Compare commits

..

8 Commits

Author SHA1 Message Date
Liam DeBeasi
926b119231 remove old lines 2019-11-18 15:03:42 -05:00
Liam DeBeasi
256c7de469 only fire pressUp if press was fired; allow overriding of other gesture params 2019-11-18 15:02:38 -05:00
Liam DeBeasi
b7b5b94cce add angular integration 2019-11-12 11:39:21 -05:00
Liam DeBeasi
5e1e883585 sync with master 2019-11-12 11:33:42 -05:00
Liam DeBeasi
ad747b05f1 add press up handler 2019-11-07 15:20:49 -05:00
Liam DeBeasi
3b52074a10 fix typo 2019-11-07 15:17:26 -05:00
Liam DeBeasi
9eac7266a0 Fix 2019-11-07 15:04:18 -05:00
Liam DeBeasi
12a4c974b4 add press recognizer 2019-11-07 15:03:05 -05:00
634 changed files with 16379 additions and 26350 deletions

View File

@@ -310,6 +310,9 @@ jobs:
- run:
command: npm install
working_directory: /tmp/workspace/angular/test/test-app
- run:
command: npm run sync
working_directory: /tmp/workspace/angular/test/test-app
- run:
command: npm test
working_directory: /tmp/workspace/angular/test/test-app

View File

@@ -1,443 +0,0 @@
# Ionic Component Implementation Guide
- [Button States](#button-states)
* [Component Structure](#component-structure)
* [Activated](#activated)
* [Disabled](#disabled)
* [Focused](#focused)
* [Hover](#hover)
* [Ripple Effect](#ripple-effect)
* [Example Components](#example-components)
* [References](#references)
- [Rendering Anchor or Button](#rendering-anchor-or-button)
* [Example Components](#example-components-1)
* [Component Structure](#component-structure-1)
- [Converting Scoped to Shadow](#converting-scoped-to-shadow)
## Button States
Any component that renders a button should have the following states: [`activated`](#activated), [`disabled`](#disabled), [`focused`](#focused), [`hover`](#hover). It should also have a [Ripple Effect](#ripple-effect) component added for Material Design.
### Component Structure
#### JavaScript
A component that renders a native button should use the following structure:
```jsx
<Host>
<button class="button-native">
<span class="button-inner">
<slot></slot>
</span>
</button>
</Host>
```
Any other attributes and classes that are included are irrelevant to the button states, but it's important that this structure is followed and the classes above exist. In some cases they may be named something else that makes more sense, such as in item.
#### CSS
A mixin called `button-state()` has been added to make it easier to setup the states in each component.
```scss
@mixin button-state() {
@include position(0, 0, 0, 0);
position: absolute;
content: "";
opacity: 0;
}
```
The following styles should be set for the CSS to work properly. Note that the `button-state()` mixin is included in the `::after` pseudo element of the native button.
```scss
.button-native {
/**
* All other CSS in this selector is irrelevant to button states
* but the following are required styles
*/
position: relative;
overflow: hidden;
}
.button-native::after {
@include button-state();
}
.button-inner {
/**
* All other CSS in this selector is irrelevant to button states
* but the following are required styles
*/
position: relative;
z-index: 1;
}
```
### Activated
The activated state should be enabled for elements with actions on "press". It usually changes the opacity or background of an element.
> Make sure the component has the correct [component structure](#component-structure) before continuing.
#### JavaScript
The `ion-activatable` class needs to be set on an element that can be activated:
```jsx
render() {
return (
<Host class='ion-activatable'>
<slot></slot>
</Host>
);
}
```
Once that is done, the element will get the `ion-activated` class added on press.
In addition to setting that class, `ion-activatable-instant` can be set in order to have an instant press with no delay:
```jsx
<Host class='ion-activatable ion-activatable-instant'>
```
#### CSS
```css
/**
* @prop --color-activated: Color of the button when pressed
* @prop --background-activated: Background of the button when pressed
* @prop --background-activated-opacity: Opacity of the background when pressed
*/
```
Style the `ion-activated` class based on the spec for that element:
```scss
:host(.ion-activated) .button-native {
color: var(--color-activated);
&::after {
background: var(--background-activated);
opacity: var(--background-activated-opacity);
}
}
```
> Order is important! Activated should be before the focused & hover states.
#### User Customization
Setting the activated state on the `::after` pseudo-element allows the user to customize the activated state without knowing what the default opacity is set at. A user can customize in the following ways to have a solid red background on press, or they can leave out `--background-activated-opacity` and the button will use the default activated opacity to match the spec.
```css
ion-button {
--background-activated: red;
--background-activated-opacity: 1;
}
```
### Disabled
The disabled state should be set via prop on all components that render a native button. Setting a disabled state will change the opacity or color of the button and remove click events from firing.
#### JavaScript
The `disabled` property should be set on the component:
```jsx
/**
* If `true`, the user cannot interact with the button.
*/
@Prop({ reflectToAttr: true }) disabled = false;
```
Then, the render function should add the [`aria-disabled`](https://www.w3.org/WAI/PF/aria/states_and_properties#aria-disabled) role to the host, a class that is the element tag name followed by `disabled`, and pass the `disabled` attribute to the native button:
```jsx
render() {
const { disabled } = this;
return (
<Host
aria-disabled={disabled ? 'true' : null}
class={{
'button-disabled': disabled
}}
>
<button disabled={disabled}>
<slot></slot>
</button>
</Host>
);
}
```
> Note: if the class being added was for `ion-back-button` it would be `back-button-disabled`.
#### CSS
The following CSS _at the bare minimum_ should be added for the disabled class, but it should be styled to match the spec:
```css
:host(.button-disabled) {
cursor: default;
opacity: .5;
pointer-events: none;
}
```
#### User Customization
TODO
### Focused
The focused state should be enabled for elements with actions when tabbed to via the keyboard. This will only work inside of an `ion-app`. It usually changes the opacity or background of an element.
> Make sure the component has the correct [component structure](#component-structure) before continuing.
#### JavaScript
The `ion-focusable` class needs to be set on an element that can be focused:
```jsx
render() {
return (
<Host class='ion-focusable'>
<slot></slot>
</Host>
);
}
```
Once that is done, the element will get the `ion-focused` class added when the element is tabbed to.
#### CSS
Components should be written to include the following focused variables for styling:
```css
/**
* @prop --color-focused: Color of the button when tabbed to with the keyboard
* @prop --background-focused: Background of the button when tabbed to with the keyboard
* @prop --background-focused-opacity: Opacity of the background when tabbed to with the keyboard
*/
```
Style the `ion-focused` class based on the spec for that element:
```scss
:host(.ion-focused) .button-native {
color: var(--color-focused);
&::after {
background: var(--background-focused);
opacity: var(--background-focused-opacity);
}
}
```
> Order is important! Focused should be after the activated and before the hover state.
#### User Customization
Setting the focused state on the `::after` pseudo-element allows the user to customize the focused state without knowing what the default opacity is set at. A user can customize in the following ways to have a solid red background on focus, or they can leave out `--background-focused-opacity` and the button will use the default focus opacity to match the spec.
```css
ion-button {
--background-focused: red;
--background-focused-opacity: 1;
}
```
### Hover
The [hover state](https://developer.mozilla.org/en-US/docs/Web/CSS/:hover) happens when a user moves their cursor on top of an element without pressing on it. It should not happen on mobile, only on desktop devices that support hover.
> Make sure the component has the correct [component structure](#component-structure) before continuing.
#### CSS
Components should be written to include the following hover variables for styling:
```css
/**
* @prop --color-hover: Color of the button on hover
* @prop --background-hover: Background of the button on hover
* @prop --background-hover-opacity: Opacity of the background on hover
*/
```
Style the `:hover` based on the spec for that element:
```scss
@media (any-hover: hover) {
:host(:hover) .button-native {
color: var(--color-hover);
&::after {
background: var(--background-hover);
opacity: var(--background-hover-opacity);
}
}
}
```
> Order is important! Hover should be after the activated and focused states.
#### User Customization
Setting the hover state on the `::after` pseudo-element allows the user to customize the hover state without knowing what the default opacity is set at. A user can customize in the following ways to have a solid red background on hover, or they can leave out `--background-hover-opacity` and the button will use the default hover opacity to match the spec.
```css
ion-button {
--background-hover: red;
--background-hover-opacity: 1;
}
```
### Ripple Effect
The ripple effect should be added to elements for Material Design. It *requires* the `ion-activatable` class to be set on the parent element to work, and relative positioning on the parent.
```jsx
render() {
const mode = getIonMode(this);
return (
<Host
class={{
'ion-activatable': true,
}}
>
<button>
<slot></slot>
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
</button>
</Host>
);
```
The ripple effect can also accept a different `type`. By default it is `"bounded"` which will expand the ripple effect from the click position outwards. To add a ripple effect that always starts in the center of the element and expands in a circle, set the type to `"unbounded"`. An unbounded ripple will exceed the container, so add `overflow: hidden` to the parent to prevent this.
Make sure to style the ripple effect for that component to accept a color:
```css
ion-ripple-effect {
color: var(--ripple-color);
}
```
### Example Components
- [ion-button](https://github.com/ionic-team/ionic/tree/master/core/src/components/button)
- [ion-back-button](https://github.com/ionic-team/ionic/tree/master/core/src/components/back-button)
- [ion-menu-button](https://github.com/ionic-team/ionic/tree/master/core/src/components/menu-button)
### References
- [Material Design States](https://material.io/design/interaction/states.html)
- [iOS Buttons](https://developer.apple.com/design/human-interface-guidelines/ios/controls/buttons/)
## Rendering Anchor or Button
Certain components can render an `<a>` or a `<button>` depending on the presence of an `href` attribute.
### Example Components
- [ion-button](https://github.com/ionic-team/ionic/tree/master/core/src/components/button)
- [ion-card](https://github.com/ionic-team/ionic/tree/master/core/src/components/card)
- [ion-fab-button](https://github.com/ionic-team/ionic/tree/master/core/src/components/fab-button)
- [ion-item-option](https://github.com/ionic-team/ionic/tree/master/core/src/components/item-option)
- [ion-item](https://github.com/ionic-team/ionic/tree/master/core/src/components/item)
### Component Structure
#### JavaScript
In order to implement a component with a dynamic tag type, set the property that it uses to switch between them, we use `href`:
```jsx
/**
* Contains a URL or a URL fragment that the hyperlink points to.
* If this property is set, an anchor tag will be rendered.
*/
@Prop() href: string | undefined;
```
Then use that in order to render the tag:
```jsx
render() {
const TagType = href === undefined ? 'button' : 'a' as any;
return (
<Host>
<TagType>
<slot></slot>
</TagType>
</Host>
);
}
```
If the component can render an `<a>`, `<button>` or a `<div>` add in more properties such as a `button` attribute in order to check if it should render a button.
## Converting Scoped to Shadow
### CSS
There will be some CSS issues when converting to shadow. Below are some of the differences.
**Targeting host + slotted child**
```css
/* IN SCOPED */
:host(.ion-color)::slotted(ion-segment-button)
/* IN SHADOW*/
:host(.ion-color) ::slotted(ion-segment-button)
```
**Targeting host-context + host (with a :not)**
```css
/* IN SCOPED */
:host-context(ion-toolbar.ion-color):not(.ion-color) {
/* IN SHADOW */
:host-context(ion-toolbar.ion-color):host(:not(.ion-color)) {
```
**Targeting host-context + host (with a :not) > slotted child**
```css
/* IN SCOPED */
:host-context(ion-toolbar:not(.ion-color)):not(.ion-color)::slotted(ion-segment-button) {
/* IN SHADOW*/
:host-context(ion-toolbar:not(.ion-color)):host(:not(.ion-color)) ::slotted(ion-segment-button) {
```

View File

@@ -10,7 +10,6 @@
<!-- (For Ionic 1.x issues, please use https://github.com/ionic-team/ionic-v1) -->
<!-- (For Ionic 2.x & 3.x issues, please use https://github.com/ionic-team/ionic-v3) -->
[x] **4.x**
[ ] **5.x**
**I'm submitting a ...**
<!-- (check one with "x") -->

View File

@@ -13,8 +13,7 @@ const packages = [
'docs',
'angular',
'packages/react',
'packages/react-router',
'packages/angular-server'
'packages/react-router'
];
function readPkg(project) {
@@ -36,13 +35,13 @@ function projectPath(project) {
return path.join(rootDir, project);
}
async function askNpmTag(version) {
async function askTag() {
const prompts = [
{
type: 'list',
name: 'npmTag',
name: 'tag',
message: 'Select npm tag or specify a new tag',
choices: ['latest', 'next', 'v4-lts']
choices: ['latest', 'next']
.concat([
new inquirer.Separator(),
{
@@ -55,13 +54,13 @@ async function askNpmTag(version) {
type: 'confirm',
name: 'confirm',
message: answers => {
return `Will publish ${tc.cyan(version)} to ${tc.cyan(answers.npmTag)}. Continue?`;
return `Will publish to ${tc.cyan(answers.tag)}. Continue?`;
}
}
];
const { npmTag, confirm } = await inquirer.prompt(prompts);
return { npmTag, confirm };
const { tag, confirm } = await inquirer.prompt(prompts);
return { tag, confirm };
}
function checkGit(tasks) {
@@ -152,26 +151,21 @@ function preparePackage(tasks, package, version, install) {
}
}
// Lint, Test, Bump Core dependency
if (version) {
projectTasks.push({
title: `${pkg.name}: lint`,
task: () => execa('npm', ['run', 'lint'], { cwd: projectRoot })
});
// TODO will not work due to https://github.com/ionic-team/ionic/issues/20136
// projectTasks.push({
// title: `${pkg.name}: test`,
// task: async () => await execa('npm', ['test'], { cwd: projectRoot })
// });
projectTasks.push({
title: `${pkg.name}: test`,
task: async () => await execa('npm', ['test'], { cwd: projectRoot })
});
}
// Build
projectTasks.push({
title: `${pkg.name}: build`,
task: () => execa('npm', ['run', 'build'], { cwd: projectRoot })
});
// Link core or react for sub projects
if (package === 'core' || package === 'packages/react') {
projectTasks.push({
title: `${pkg.name}: npm link`,
@@ -253,23 +247,6 @@ function updatePackageVersions(tasks, packages, version) {
}
}
});
// angular & angular-server need to update their dist versions
if (package === 'angular' || package === 'packages/angular-server') {
const distPackage = path.join(package, 'dist');
updatePackageVersion(tasks, distPackage, version);
tasks.push({
title: `${package} update @ionic/core dependency, if present ${tc.dim(`(${version})`)}`,
task: async () => {
const pkg = readPkg(distPackage);
updateDependency(pkg, '@ionic/core', version);
writePkg(distPackage, pkg);
}
});
}
if (package === 'packages/react-router') {
tasks.push({
title: `${package} update @ionic/react dependency, if present ${tc.dim(`(${version})`)}`,
@@ -294,23 +271,7 @@ function updatePackageVersion(tasks, package, version) {
});
}
function copyPackageToDist(tasks, packages) {
packages.forEach(package => {
const projectRoot = projectPath(package);
// angular and angular-server are the only packages that publish dist
if (package !== 'angular' && package !== 'packages/angular-server') {
return;
}
tasks.push({
title: `${package}: Copy package.json to dist`,
task: () => execa('node', ['copy-package.js', package], { cwd: path.join(rootDir, '.scripts') })
});
});
}
function publishPackages(tasks, packages, version, npmTag = 'latest') {
function publishPackages(tasks, packages, version, tag = 'latest') {
// first verify version
packages.forEach(package => {
if (package === 'core') {
@@ -329,18 +290,14 @@ function publishPackages(tasks, packages, version, npmTag = 'latest') {
});
});
// Publish
// next publish
packages.forEach(package => {
let projectRoot = projectPath(package);
if (package === 'packages/angular-server' || package === 'angular') {
projectRoot = path.join(projectRoot, 'dist')
}
const projectRoot = projectPath(package);
tasks.push({
title: `${package}: publish to ${npmTag} tag`,
title: `${package}: publish to ${tag} tag`,
task: async () => {
await execa('npm', ['publish', '--tag', npmTag], { cwd: projectRoot });
await execa('npm', ['publish', '--tag', tag], { cwd: projectRoot });
}
});
});
@@ -375,11 +332,10 @@ function copyCDNLoader(tasks, version) {
module.exports = {
checkTestDist,
checkGit,
askNpmTag,
askTag,
isValidVersion,
isVersionGreater,
copyCDNLoader,
copyPackageToDist,
packages,
packagePath,
prepareDevPackage,

View File

@@ -6,7 +6,7 @@ const tc = require('turbocolor');
const execa = require('execa');
const Listr = require('listr');
const path = require('path');
const { Octokit } = require('@octokit/rest');
const octokit = require('@octokit/rest')()
const common = require('./common');
const fs = require('fs-extra');
@@ -28,7 +28,7 @@ async function main() {
// repo must be clean
common.checkGit(tasks);
const { npmTag, confirm } = await common.askNpmTag(version);
const { tag, confirm } = await common.askTag();
if (!confirm) {
return;
@@ -36,10 +36,10 @@ async function main() {
if(!dryRun) {
// publish each package in NPM
common.publishPackages(tasks, common.packages, version, npmTag);
common.publishPackages(tasks, common.packages, version, tag);
// push tag to git remote
publishGit(tasks, version, changelog, npmTag);
publishGit(tasks, version, changelog);
}
const listr = new Listr(tasks);
@@ -48,10 +48,10 @@ async function main() {
// Dry run doesn't publish to npm or git
if (dryRun) {
console.log(`
\n${tc.yellow('Did not publish. Remove the "--dry-run" flag to publish:')}\n${tc.green(version)} to ${tc.cyan(npmTag)}\n
\n${tc.yellow('Did not publish. Remove the "--dry-run" flag to publish:')}\n${tc.green(version)} to ${tc.cyan(tag)}\n
`);
} else {
console.log(`\nionic ${version} published to ${npmTag}!! 🎉\n`);
console.log(`\nionic ${version} published to ${tag}!! 🎉\n`);
}
} catch (err) {
@@ -70,13 +70,13 @@ function checkProductionRelease() {
}
}
function publishGit(tasks, version, changelog, npmTag) {
const gitTag = `v${version}`;
function publishGit(tasks, version, changelog) {
const tag = `v${version}`;
tasks.push(
{
title: `Tag latest commit ${tc.dim(`(${gitTag})`)}`,
task: () => execa('git', ['tag', `${gitTag}`], { cwd: common.rootDir })
title: `Tag latest commit ${tc.dim(`(${tag})`)}`,
task: () => execa('git', ['tag', `${tag}`], { cwd: common.rootDir })
},
{
title: 'Push branches to remote',
@@ -88,7 +88,7 @@ function publishGit(tasks, version, changelog, npmTag) {
},
{
title: 'Publish Github release',
task: () => publishGithub(version, gitTag, changelog, npmTag)
task: () => publishGithub(version, tag, changelog)
}
);
}
@@ -116,12 +116,10 @@ function findChangelog() {
return lines.slice(start, end).join('\n').trim();
}
async function publishGithub(version, gitTag, changelog, npmTag) {
// If the npm tag is next then publish as a prerelease
const prerelease = npmTag === 'next' ? true : false;
const octokit = new Octokit({
auth: process.env.GH_TOKEN
async function publishGithub(version, tag, changelog) {
octokit.authenticate({
type: 'oauth',
token: process.env.GH_TOKEN
});
let branch = await execa.stdout('git', ['symbolic-ref', '--short', 'HEAD']);
@@ -134,10 +132,9 @@ async function publishGithub(version, gitTag, changelog, npmTag) {
owner: 'ionic-team',
repo: 'ionic',
target_commitish: branch,
tag_name: gitTag,
tag_name: tag,
name: version,
body: changelog,
prerelease: prerelease
});
}

View File

@@ -11,22 +11,7 @@ const fs = require('fs');
},
// angular
{
files: [
'../angular/dist/schematics/collection.json',
'../angular/dist/fesm5/ionic-angular.js',
'../angular/dist/fesm2015/ionic-angular.js',
'../angular/dist/ionic-angular.d.ts',
'../angular/dist/ionic-angular.metadata.json'
]
},
// angular-server
{
files: [
'../packages/angular-server/dist/fesm5/ionic-angular-server.js',
'../packages/angular-server/dist/fesm2015/ionic-angular-server.js',
'../packages/angular-server/dist/ionic-angular-server.d.ts',
'../packages/angular-server/dist/ionic-angular-server.metadata.json'
]
files: ['../angular/dist/fesm5.cjs.js']
},
// react
{

View File

@@ -1,671 +1,3 @@
# Breaking Changes
This is a comprehensive list of the breaking changes introduced in the major version releases of Ionic Framework.
## Versions
- [Version 5.x](#version-5x)
- [Version 4.x](#version-4x)
- [Legacy](#legacy)
## Version 5.x
- [CSS](#css)
* [CSS Utilities](#css-utilities)
* [Display Classes](#display-classes)
* [Activated, Focused, Hover States](#activated-focused-hover-states)
* [Distributed Sass](#distributed-sass)
- [Components](#components)
* [Action Sheet](#action-sheet)
* [Anchor](#anchor)
* [Back Button](#back-button)
* [Button](#button)
* [Card](#card)
* [Controllers](#controllers)
* [FAB Button](#fab-button)
* [Item](#item)
* [Header / Footer](#header---footer)
* [List Header](#list-header)
* [Menu](#menu)
* [Menu Button](#menu-button)
* [Nav Link](#nav-link)
* [Radio](#radio)
* [Searchbar](#searchbar)
* [Segment](#segment)
* [Segment Button](#segment-button)
* [Select Option](#select-option)
* [Skeleton Text](#skeleton-text)
* [Split Pane](#split-pane)
* [Toast](#toast)
* [Tabs](#tabs)
- [Colors](#colors)
- [Events](#events)
- [Mode](#mode)
- [Ionicons](#ionicons)
### CSS
#### CSS Utilities
We originally added CSS utility attributes for styling components because it was a quick and easy way to wrap text or add padding to an element. Once we added support for multiple frameworks as part of our "Ionic for everyone" approach, we quickly determined there were problems with using CSS attributes with frameworks that use JSX and Typescript. In order to solve this we added CSS classes. Rather than support CSS attributes in certain frameworks and classes in others, we decided to remove the CSS attributes and support what works in all of them, classes, for consistency. In addition to this, changing to classes prefixed with `ion` avoids conflict with native attributes and user's CSS. In the latest version of Ionic 4, there are deprecation warnings printed in the console to show what the new classes are, and the documentation has been updated since support for classes was added to remove all references to attributes: https://ionicframework.com/docs/layout/css-utilities.
Some examples of what's changed are below. *This is not all-inclusive, see the documentation linked above for all of the available CSS utility classes.*
**Before**
```html
<ion-header text-center></ion-header>
<ion-content padding></ion-content>
<ion-label text-wrap></ion-label>
<ion-item wrap></ion-item>
```
**After**
```html
<ion-header class="ion-text-center"></ion-header>
<ion-content class="ion-padding"></ion-content>
<ion-label class="ion-text-wrap"></ion-label>
<ion-item class="ion-wrap"></ion-item>
```
#### Display Classes
The responsive display classes found in the `display.css` file have had their media queries updated to better reflect how they should work. Instead of using the maximum value of the breakpoint for `.ion-hide-{breakpoint}-down` classes it will use the minimum of that breakpoint.
The [Ionic breakpoints](https://ionicframework.com/docs/layout/css-utilities#ionic-breakpoints) are the following:
| Breakpoint Name | Width |
| ----------------| --------|
| xs | 0 |
| sm | 576px |
| md | 768px |
| lg | 992px |
| xl | 1200px |
Previously, if you added the class `ion-hide-md-down` to an element, it would hide the element when the screen size was `991px` (the maximum of the `md` breakpoint) or smaller. Now, using this same class will hide the element when the maximum screen size is `768px`.
Below is a table of how the media queries have changed for each class:
| Class Name | Ionic 4 | Ionic 5 |
| --------------------| -----------------------------| -----------------------------|
| `.ion-hide-down` | `@media (max-width: 575px)` | all screen sizes |
| `.ion-hide-sm-down` | `@media (max-width: 767px)` | `@media (max-width: 576px)` |
| `.ion-hide-md-down` | `@media (max-width: 991px)` | `@media (max-width: 768px)` |
| `.ion-hide-lg-down` | `@media (max-width: 1199px)` | `@media (max-width: 992px)` |
| `.ion-hide-xl-down` | all screen sizes | `@media (max-width: 1200px)` |
_Note that no changes were made to the `.ion-hide-{breakpoint}-up` classes._
See the [CSS Utilities responsive display documentation](https://ionicframework.com/docs/layout/css-utilities#responsive-display-attributes) for more information.
#### Activated, Focused, Hover States
The `.activated` class that is automatically added to clickable components has been renamed to `.ion-activated`.
The way the CSS variables are used for targeting the activated, focused and hover backgrounds have been updated on the following components:
- Action Sheet
- Back Button
- Button
- FAB Button
- Item
- Menu Button
- Segment Button
- Tab Button
Previously, in order to update any of the background colors for the states you would have to know what the opacity was set to. Using the Material Design spec as an example, it would require you to know that the hover state uses a white overlay with an opacity of `.08`. This means that if we had the following set by default:
```css
--background-hover: rgba(255, 255, 255, 0.08);
```
If you wanted to change the hover overlay to use black but still match the spec, you'd have to set it to:
```css
--background-hover: rgba(0, 0, 0, 0.08);
```
The new way adds the following variables:
```css
--background-activated-opacity
--background-focused-opacity
--background-hover-opacity
```
It also updates the Action Sheet component so that the variables will be prefixed with `button`. See the [Action Sheet](#action-sheet) section in this document for all of the new variable names.
This allows you to still have control over the opacity if desired, but when updating the state, you only have to set the main variables: `--background-activated`, `--background-focused`, `--background-hover` and the button will still match the spec. This is most important when changing the global theme, as updating the toolbar color will automatically update the hover states for all of the buttons in a toolbar, regardless of their fill and without having to know what each opacity is.
##### Examples
```css
/* Setting the button background on hover to solid red */
ion-button {
--background-hover: red;
--background-hover-opacity: 1;
}
/* Setting the action sheet button background on focus to an opaque green */
ion-action-sheet {
--button-background-focus: green;
--button-background-focus-opacity: 0.5;
}
/*
* Setting the fab button background on hover to match the text color with
* the default --background-hover-opacity on md
*/
.md ion-fab-button {
--color: #222;
--background-hover: #222;
}
```
##### Global CSS Properties
Some variables were renamed, removed or added. See the chart below for the changes.
| Old variable | Status | New variable |
| ----------------------------------------| --------|-------------------------------------------|
| `--ion-toolbar-color-unchecked` | renamed | `--ion-toolbar-segment-color` |
| `--ion-toolbar-color-checked` | renamed | `--ion-toolbar-segment-color-checked` |
| `--ion-toolbar-background-unchecked` | renamed | `--ion-toolbar-segment-background` |
| `--ion-toolbar-background-checked` | renamed | `--ion-toolbar-segment-background-checked`|
| `--ion-tab-bar-color-activated` | renamed | `--ion-tab-bar-color-selected` |
| | added | `--ion-toolbar-segment-indicator-color` |
| `--ion-toolbar-color-activated` | removed | |
| `--ion-item-background-activated` | removed | |
| `--ion-item-background-focused` | removed | |
| `--ion-item-background-hover` | removed | |
#### Distributed Sass
The `scss` files have been removed from `dist/`. CSS variables should be used to theme instead.
### Components
#### Action Sheet
The following CSS variables have been renamed or added:
| Old | New |
|--------------------------| -------------------------------------------|
| | `--button-background` |
| `--background-activated` | `--button-background-activated` |
| | `--button-background-activated-opacity` |
| `--background-selected` | `--button-background-selected` |
| | `--button-background-focused` |
| | `--button-background-focused-opacity` |
| | `--button-background-hover` |
| | `--button-background-hover-opacity` |
| | `--button-background-selected` |
| | `--button-background-selected-opacity` |
| | `--button-color` |
| | `--button-color-activated` |
| | `--button-color-focused` |
| | `--button-color-hover` |
| | `--button-color-selected` |
See the [Action Sheet CSS Custom Properties](https://ionicframework.com/docs/api/action-sheet#css-custom-properties) documentation for descriptions.
#### Anchor
The `ion-anchor` component has been renamed to `ion-router-link` as this is a better description of which component it should be used with. This component should still only be used in vanilla and Stencil JavaScript projects. Angular projects should use an `<a>` and `routerLink` with the Angular router. See the [documentation for router-link](https://ionicframework.com/docs/api/router-link) for more information.
#### Back Button
- Converted `ion-back-button` to use [shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM).
- [Focused, Hover States](#activated-focused-hover-states) have been updated.
#### Button
- [Activated, Focused, Hover States](#activated-focused-hover-states) have been updated.
#### Card
Converted `ion-card` to use [shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM).
#### Controllers
The controller components (`ion-action-sheet-controller`, `ion-alert-controller`, `ion-loading-controller`, `ion-menu-controller`, `ion-modal-controller`, `ion-picker-controller`, `ion-popover-controller`, `ion-toast-controller`) have been removed from Ionic core as elements. They should be imported from `@ionic/core` instead. This will not affect projects that use Angular or React. Below is an example of the loading controller change in a JavaScript project, but this change applies to all controller elements.
**Before**
```html
<ion-loading-controller></ion-loading-controller>
<script>
async function presentLoading() {
const loadingController = document.querySelector('ion-loading-controller');
const loading = await loadingController.create({
message: 'Hello',
duration: 2000
});
await loading.present();
}
</script>
```
**After**
```html
<script type="module">
import { loadingController } from '@ionic/core';
window.loadingController = loadingController;
</script>
<script>
async function presentLoading() {
const loading = await loadingController.create({
message: 'Hello',
duration: 2000
});
await loading.present();
}
</script>
```
#### FAB Button
- [Activated, Focused, Hover States](#activated-focused-hover-states) have been updated.
#### Item
- [Activated, Focused, Hover States](#activated-focused-hover-states) have been updated.
#### Header / Footer
The `no-border` attribute has been removed, use `ion-no-border` class instead. See [CSS Utilities](#css-utilities) above for more information on why this change was made.
#### List Header
The list header has been redesigned to match the latest iOS spec. This may break the design of your application as the previous design had a small font size with uppercase text. The latest design includes a larger, bolder text.
In addition, any text content inside of an `<ion-list-header>` should be wrapped in an `<ion-label>` in order to get the proper styling of the new design. If the label is missing, the button alignment in the list header may look off.
**Before**
```html
<ion-list-header>
New This Week
<ion-button>See All</ion-button>
</ion-list-header>
```
**After**
```html
<ion-list-header>
<ion-label>New This Week</ion-label>
<ion-button>See All</ion-button>
</ion-list-header>
```
The button has also been updated to default to `fill="clear"` and `size="small"` when inside of a list header. If the old look of the list header or buttons is desired, use custom CSS or button properties to achieve it.
For more information see the [List Header usage](https://ionicframework.com/docs/api/list-header#usage).
#### Menu
- The `swipeEnable()` function has been removed in Angular, use `swipeGesture()` instead.
- The `side` values `left` and `right` have been removed, use `start` and `end` instead.
- Removed the `main` attribute, use `content-id` (for vanilla JS / Vue) and `contentId` (for Angular / React) instead.
**Before**
```html
<ion-menu>...</ion-menu>
<ion-content main>...</ion-content>
```
**After**
```html
<ion-menu content-id="main"></ion-menu>
<ion-content id="main">...</ion-content>
```
- The presentation type in `ios` now defaults to `"overlay"`.
#### Menu Button
- [Focused, Hover States](#activated-focused-hover-states) have been updated.
#### Nav Link
The `ion-nav-push`, `ion-nav-back`, and `ion-nav-set-root` components have been removed in favor of using `ion-nav-link` with a `router-direction` property which accepts `”root”`, `“forward”`, and `“back”`. This reduces the need for maintaining multiple components when they all do the same thing with different transition directions. See the [documentation for nav-link](https://ionicframework.com/docs/api/nav-link) for more information.
#### Radio
The `ion-radio` must be used inside of an `ion-radio-group` even if there is only one `ion-radio`. Additionally, the `checked` property has been removed. Developers should set the `value` property on the parent `ion-radio-group` to match the value of the desired checked radio button.
`ion-radio` no longer emits an `ionSelect` event. Developers should listen for an `ionChange` event to be emitted on `ion-radio-group` instead.
**Before**
```html
<ion-radio checked>One</ion-radio>
<ion-radio-group>
<ion-radio>One</ion-radio>
<ion-radio checked>Two</ion-radio>
</ion-radio-group>
```
**After**
```html
<ion-radio-group value="one">
<ion-radio value="one">One</ion-radio>
</ion-radio-group>
<ion-radio-group value="two">
<ion-radio value="one">One</ion-radio>
<ion-radio value="two">Two</ion-radio>
</ion-radio-group>
```
#### Searchbar
##### Show Cancel Button
The `show-cancel-button` property of the searchbar no longer accepts boolean values. Accepted values are strings: `"focus"`, `"always"`, `"never"`.
**Before**
```html
<ion-searchbar show-cancel-button>
<ion-searchbar show-cancel-button="true">
<ion-searchbar show-cancel-button="false">
```
**After**
```html
<ion-searchbar show-cancel-button="focus">
<ion-searchbar show-cancel-button="focus">
<ion-searchbar show-cancel-button="never">
```
See the [Searchbar documentation](https://ionicframework.com/docs/api/searchbar#properties) for more information.
##### Inputmode
The `inputmode` property for `ion-searchbar` now defaults to `undefined`. To get the old behavior, set the inputmode property to `"search"`.
#### Segment
Segment was completely revamped to use the new iOS design including an all new gesture that applies for both Material Design and iOS. Due to these changes, some breaking changes were inevitably introduced in order to support the new design.
##### Renamed Events
`ion-segment` no longer emits an `ionSelect` event. Developers should listen for an `ionChange` event to be emitted on `ion-segment` instead.
##### Button States
- The activated styles and custom CSS properties have been removed. These are no longer being used in the latest spec as the indicator and ripple are used to show activation. Properties removed:
```
--color-activated
--background-activated
```
- The [Focused & Hover States](#activated-focused-hover-states) have been updated.
##### Indicator Color
- `--indicator-color` now applies to the checked segment button (for both `ios` and `md`)
- `--indicator-color-checked` has been removed
- The Material Design spec does not include an indicator color on non-checked buttons: https://material.io/components/tabs/
- In order to style the Segment to match the old spec, please use custom CSS. For example, to update Material Design to include a bottom line all of the time:
```css
.md ion-segment::after {
position: absolute;
bottom: 0;
height: 2px;
width: 100%;
content: '';
background: rgba(0,0,0,0.5);
z-index: -1;
}
```
##### Background & Color
A `--background` variable has been added to style the `ion-segment` component. As a result of this, the following background variables for a child segment button must now be set on the `ion-segment-button`:
```
--background: Background of the segment button
--background-checked: Background of the checked segment button
--background-disabled: Background of the disabled segment button
--background-hover: Background of the segment button on hover
```
> Note: iOS no longer checks the button background, so setting the `--background-checked` variable may have an undesired outcome. Instead, Segment uses an indicator to slide between the buttons, showing which one is checked. See the previous section on the indicator color variables.
The above variables *will not* be inherited in the button if set on the `ion-segment`. In addition to this, all color variables should also be set on the button for consistency:
```
--color: Color of the segment button
--color-checked: Color of the checked segment button
--color-disabled: Color of the disabled segment button
--color-hover: Color of the segment button on hover
```
###### Removed variables
The following variables were removed due to the current spec no longer using them.
- `--color-checked-disabled`
- `--background-disabled`
- `--color-disabled`
- `--background-activated`
- `--color-activated`
##### Global CSS Properties
Some variables were renamed or added. See the chart below for the new names.
| Old variable | Status | New variable |
| ----------------------------------------| --------|-------------------------------------------|
| `--ion-toolbar-color-unchecked` | renamed | `--ion-toolbar-segment-color` |
| `--ion-toolbar-color-checked` | renamed | `--ion-toolbar-segment-color-checked` |
| `--ion-toolbar-background-unchecked` | renamed | `--ion-toolbar-segment-background` |
| `--ion-toolbar-background-checked` | renamed | `--ion-toolbar-segment-background-checked`|
| | added | `--ion-toolbar-segment-indicator-color` |
#### Segment Button
The `checked` property has been removed. Developers should set the `value` property on the parent `ion-segment` to match the value of the desired checked segment button.
**Before**
```html
<ion-segment>
<ion-segment-button>One</ion-segment-button>
<ion-segment-button checked>Two</ion-segment-button>
<ion-segment-button>Three</ion-segment-button>
</ion-segment>
```
**After**
```html
<ion-segment value="two">
<ion-segment-button value="one">One</ion-segment-button>
<ion-segment-button value="two">Two</ion-segment-button>
<ion-segment-button value="three">Three</ion-segment-button>
</ion-segment>
```
#### Select Option
The `selected` property has been removed. Developers should set the `value` property on the parent `ion-select` to match the desired selected option.
**Before**
```html
<ion-select>
<ion-select-option>One</ion-select-option>
<ion-select-option selected>Two</ion-select-option>
</ion-select>
```
**After**
```html
<ion-select value="two">
<ion-select-option value="one">One</ion-select-option>
<ion-select-option value="two">Two</ion-select-option>
</ion-select>
```
#### Skeleton Text
The `width` property has been removed in favor of using CSS styling.
#### Split Pane
- Converted to use [shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM).
- Removed the `main` attribute, use `content-id` (for vanilla JS / Vue) and `contentId` (for Angular / React) instead.
**Before**
```html
<ion-split-pane>
...
<div main>...</div>
</ion-split-pane>
```
**After**
```html
<ion-split-pane content-id="main">
...
<div id="main">...</div>
</ion-split-pane>
```
#### Tabs
- [Focused State](#activated-focused-hover-states) have been updated.
#### Toast
The close button properties (`showCloseButton` and `closeButtonText`) have been removed. Use the `buttons` array instead with `role: 'cancel'`. See the [usage documentation](https://ionicframework.com/docs/api/toast#usage) for more information.
**Before**
```javascript
async presentToast() {
const toast = await this.toastController.create({
message: 'Your settings have been saved.',
showCloseButton: true,
closeButtonText: 'Close'
});
toast.present();
}
```
**After**
```javascript
async presentToast() {
const toast = await this.toastController.create({
message: 'Your settings have been saved.',
buttons: [
{
text: 'Close',
role: 'cancel',
handler: () => {
console.log('Close clicked');
}
}
]
});
toast.present();
}
```
### Colors
The default Ionic colors have been updated to the following:
```scss
primary: #3880ff
secondary: #3dc2ff
tertiary: #5260ff
success: #2dd36f
warning: #ffc409
danger: #eb445a
light: #f4f5f8
medium: #92949c
dark: #222428
```
`primary`, `light` and `dark` have not changed. The contrast color for `warning` has been updated to `#000`.
This will only be a breaking change in your app if you are not using one of our starters and not overriding the defaults. If you are overriding the defaults already these will need to be manually updated if desired.
### Events
The `@ionic/angular` Events service has been removed.
- Use "Observables" for a similar pub/sub architecture: https://angular.io/guide/observables
- Use "Redux" for advanced state management: https://ngrx.io
### Mode
Mode is now cascaded from the parent to the child component. Previously, if you wanted to update a component and its children to use the same mode, you'd have to set it on all components. For example, if you wanted to use a `md` segment no matter the mode, you'd have to write the following:
```html
<ion-segment mode="md">
<ion-segment-button mode="md">Button</ion-segment-button>
<ion-segment-button mode="md">Button</ion-segment-button>
</ion-segment>
```
Now, the `mode` only needs to be set on the `ion-segment` and it will be inherited. If this behavior is not desired set a different mode on the child component.
### Ionicons
Ionicons 5 has been released! :tada: This brings many changes including a top to bottom re-draw of every icon, variants for each icon (filled, outline, and sharp), and the removal of auto-switching icons based on the platform.
For more information, check out the [Ionicons Changelog](https://github.com/ionic-team/ionicons/blob/master/CHANGELOG.md)!
--------------------------------------------------------------------------------------------------
## Version 4.x
The list of the breaking changes introduced in Ionic Angular v4 can be found in [angular/BREAKING.md](https://github.com/ionic-team/ionic/blob/master/angular/BREAKING.md).
## Legacy
For the breaking changes of the older legacy versions (versions 2.x & 3.x) of Ionic Framework, see the [v3 changelog](https://github.com/ionic-team/ionic-v3/blob/master/CHANGELOG.md).
The list of the breaking changes introduced in Ionic Angular v4 has been moved to [angular/BREAKING.md](https://github.com/ionic-team/ionic/blob/master/angular/BREAKING.md).

View File

@@ -1,476 +1,3 @@
## [5.0.6](https://github.com/ionic-team/ionic/compare/v5.0.5...v5.0.6) (2020-03-25)
### Bug Fixes
* **all** only warn invalid mode if used on an ionic component ([#20828](https://github.com/ionic-team/ionic/issues/20828)) ([6ed1c51](https://github.com/ionic-team/ionic/commit/6ed1c51321d781ff92efbf623790af91cb16a5af)), closes [#20055](https://github.com/ionic-team/ionic/issues/20055)
* **all** properly scroll to input with scroll assist ([#20742](https://github.com/ionic-team/ionic/issues/20742)) ([e24060e](https://github.com/ionic-team/ionic/commit/e24060ecd9d803ece4bbb9c6beae23e761d7fb5e)), closes [#19589](https://github.com/ionic-team/ionic/issues/19589)
* **angular:** export Animation and Gesture related types ([#20766](https://github.com/ionic-team/ionic/issues/20766)) ([2ece194](https://github.com/ionic-team/ionic/commit/2ece194a085742b919cc68f643b1b365f7d85594))
* **angular:** respect animation property for ion-router-outlet ([#20767](https://github.com/ionic-team/ionic/issues/20767)) ([f2dbe1f](https://github.com/ionic-team/ionic/commit/f2dbe1ff3be44e6697b791de392a9ef46dbf27e8)), closes [#20764](https://github.com/ionic-team/ionic/issues/20764)
* **content:** apply --offset-top and --offset-bottom values correctly ([#20790](https://github.com/ionic-team/ionic/issues/20790)) ([2707289](https://github.com/ionic-team/ionic/commit/2707289b36883ae495f86cfb2f2b6c84e090551b)), closes [#20735](https://github.com/ionic-team/ionic/issues/20735)
* **content:** set overscroll-behavior based on the scroll direction ([#20011](https://github.com/ionic-team/ionic/issues/20011)) ([a3fc77b](https://github.com/ionic-team/ionic/commit/a3fc77be91ead6edc3f07c6127879753a063bd18)), closes [#20010](https://github.com/ionic-team/ionic/issues/20010)
* **item-divider:** update design to match native iOS ([#20854](https://github.com/ionic-team/ionic/issues/20854)) ([d91e22d](https://github.com/ionic-team/ionic/commit/d91e22d820f170ecfdfad835ca56701ad70e6f3d))
* **item-sliding:** account for swipe to go back gesture when opening item-options ([#20777](https://github.com/ionic-team/ionic/issues/20777)) ([f23ac44](https://github.com/ionic-team/ionic/commit/f23ac44c9a6646129762bb861cae6145690ca5a1)), closes [#20773](https://github.com/ionic-team/ionic/issues/20773)
* **list:** show bottom border on last item in a list followed by a list ([#20798](https://github.com/ionic-team/ionic/issues/20798)) ([7bc5191](https://github.com/ionic-team/ionic/commit/7bc51911f6c538be8b91d1e569675b19832cb000))
* **modal:** backdrop and box shadows no longer stack when opening multiple modals ([#20801](https://github.com/ionic-team/ionic/issues/20801)) ([253cd96](https://github.com/ionic-team/ionic/commit/253cd96164914a803f6bb42ff95ca74880c940d0)), closes [#20800](https://github.com/ionic-team/ionic/issues/20800)
* **modal:** backdrop is no longer tappable on card-style modal on smaller screens ([#20802](https://github.com/ionic-team/ionic/issues/20802)) ([12932dd](https://github.com/ionic-team/ionic/commit/12932dd20212bec7d780650166c70819d125f75a)), closes [#20783](https://github.com/ionic-team/ionic/issues/20783)
* **modal:** properly apply border radius on card-style modal ([#20852](https://github.com/ionic-team/ionic/issues/20852)) ([dff3816](https://github.com/ionic-team/ionic/commit/dff3816c049a1c051f94d3176c8b903a69603912)), closes [#20851](https://github.com/ionic-team/ionic/issues/20851)
* **modal:** properly remove safe area padding on card-modal ([#20853](https://github.com/ionic-team/ionic/issues/20853)) ([71f1182](https://github.com/ionic-team/ionic/commit/71f118201b0918f60c1a078d55afd10b39f17e86)), closes [#20799](https://github.com/ionic-team/ionic/issues/20799)
* **modal:** respect card-style modal spec for iPadOS ([#20750](https://github.com/ionic-team/ionic/issues/20750)) ([75bae40](https://github.com/ionic-team/ionic/commit/75bae403e917b20645675343734440ee95d31634)), closes [#20700](https://github.com/ionic-team/ionic/issues/20700)
* **react:** expose correct type for CreateAnimation ([#20775](https://github.com/ionic-team/ionic/issues/20775)) ([0897c3f](https://github.com/ionic-team/ionic/commit/0897c3f9c2591442b3f80d28a25ec4471da3c9d7)), closes [#20771](https://github.com/ionic-team/ionic/issues/20771)
* **refresher:** properly dismiss refresher when completed synchronously ([#20815](https://github.com/ionic-team/ionic/issues/20815)) ([b1a87c8](https://github.com/ionic-team/ionic/commit/b1a87c88923201fd0b31bf55d81b97acc09ddf1c)), closes [#20803](https://github.com/ionic-team/ionic/issues/20803)
* **segment:** automatically expand width for scrollable segment buttons ([#20763](https://github.com/ionic-team/ionic/issues/20763)) ([cdfd50b](https://github.com/ionic-team/ionic/commit/cdfd50b554d1d8f89c3d9948c7613ce75ede1e52)), closes [#20566](https://github.com/ionic-team/ionic/issues/20566)
* **segment:** scrollable segments only show scrollbar if they overflow ([#20760](https://github.com/ionic-team/ionic/issues/20760)) ([ab146c9](https://github.com/ionic-team/ionic/commit/ab146c96ec5cbc962eed629c30b2c5c446f3098d)), closes [#20758](https://github.com/ionic-team/ionic/issues/20758)
* **slides:** check that mutation observer is defined for ssr ([#20791](https://github.com/ionic-team/ionic/issues/20791)) ([2d5d251](https://github.com/ionic-team/ionic/commit/2d5d2515be86496a280d93847185ab332e5d47a2))
* **textarea:** properly adjust auto-grow textarea in scrolled content ([#19776](https://github.com/ionic-team/ionic/issues/19776)) ([8bd5bac](https://github.com/ionic-team/ionic/commit/8bd5bace73670dfe351b3734b51cbf3aa87517dc)), closes [#19193](https://github.com/ionic-team/ionic/issues/19193)
* **title:** improve reliability of large title ios nav transition ([#20861](https://github.com/ionic-team/ionic/issues/20861)) ([3bd6b5d](https://github.com/ionic-team/ionic/commit/3bd6b5def2877f6a918c587de25a10ccc82f88f1))
* **title:** large title now inherits global color styling during nav transition ([#20862](https://github.com/ionic-team/ionic/issues/20862)) ([321140f](https://github.com/ionic-team/ionic/commit/321140ff736b46d2631a9e87a7b070009c5e1b2c))
## [5.0.5](https://github.com/ionic-team/ionic/compare/v5.0.4...v5.0.5) (2020-03-11)
### Bug Fixes
* **button:** allow overflow to be overridden by the CSS variable ([#20738](https://github.com/ionic-team/ionic/issues/20738)) ([7ecde36](https://github.com/ionic-team/ionic/commit/7ecde36f9d31327a45f7b5023ed533edbb9cc709)), closes [#20726](https://github.com/ionic-team/ionic/issues/20726)
* **datetime:** account for max property when hour, minute, or second is set to 0 ([#20665](https://github.com/ionic-team/ionic/issues/20665)) ([2177461](https://github.com/ionic-team/ionic/commit/21774612d8d70ab7eda3eab0e6e9ac039b5c87d8)), closes [#20652](https://github.com/ionic-team/ionic/issues/20652)
* **header:** collapsable header should default to using content background ([#20736](https://github.com/ionic-team/ionic/issues/20736)) ([f6c3ba7](https://github.com/ionic-team/ionic/commit/f6c3ba7e5af2af9e32f75306cde7704509e82263)), closes [#20691](https://github.com/ionic-team/ionic/issues/20691)
* **header:** resolve undefined error on collapsible header when navigating quickly ([#20728](https://github.com/ionic-team/ionic/issues/20728)) ([87a2721](https://github.com/ionic-team/ionic/commit/87a27216d011f1d02ac0fc0aeb3ae0400ecfbd8c)), closes [#20725](https://github.com/ionic-team/ionic/issues/20725)
* **ios:** large title animation now works properly in a modal ([#20703](https://github.com/ionic-team/ionic/issues/20703)) ([ec4878a](https://github.com/ionic-team/ionic/commit/ec4878ac085d8ff92cb8b2ea0852523f174ab01b)), closes [#20696](https://github.com/ionic-team/ionic/issues/20696)
* **item:** apply proper margin left for slotted icon in RTL ([#20684](https://github.com/ionic-team/ionic/issues/20684)) ([d53595e](https://github.com/ionic-team/ionic/commit/d53595eb1629e0d60f7e832414e84c544e184346)), closes [#20653](https://github.com/ionic-team/ionic/issues/20653)
* **label:** text overflow for slotted headings ([#20690](https://github.com/ionic-team/ionic/issues/20690)) ([4d34ce6](https://github.com/ionic-team/ionic/commit/4d34ce6a31eaa19859699646cc614f5be6239e10)), closes [#17087](https://github.com/ionic-team/ionic/issues/17087)
* **modal:** leave animation transitions modal completely out of viewport on ipad ([#20702](https://github.com/ionic-team/ionic/issues/20702)) ([22d5256](https://github.com/ionic-team/ionic/commit/22d52568100d8096ee36e3a61a19614f0d63d45f)), closes [#20697](https://github.com/ionic-team/ionic/issues/20697)
* **angular** exclude components from ssr ([#20674](https://github.com/ionic-team/ionic/issues/20674)) ([f64b142](https://github.com/ionic-team/ionic/commit/f64b1420aead39b9056dc25cfdbcf95bc4f6f621))
* **modal:** swipeable modal now works in firefox ([#20714](https://github.com/ionic-team/ionic/issues/20714)) ([7d260b9](https://github.com/ionic-team/ionic/commit/7d260b96a73958709fa93a4fe58f816a445471ee)), closes [#20706](https://github.com/ionic-team/ionic/issues/20706)
* **overlays:** prevent accidental dismiss of overlays when tapping screen twice ([#20683](https://github.com/ionic-team/ionic/issues/20683)) ([b6c2a77](https://github.com/ionic-team/ionic/commit/b6c2a77deb1c09eb1fd414f7737794e208ab5081)), closes [#20608](https://github.com/ionic-team/ionic/issues/20608)
* **segment:** allow routerLink to work on segment buttons ([#20682](https://github.com/ionic-team/ionic/issues/20682)) ([314dbb1](https://github.com/ionic-team/ionic/commit/314dbb1a4d970327fcbb2f3fbdec0627c626fe4d)), closes [#20678](https://github.com/ionic-team/ionic/issues/20678)
* **segment:** iOS mode segment now works on older Android devices ([#20673](https://github.com/ionic-team/ionic/issues/20673)) ([44993b7](https://github.com/ionic-team/ionic/commit/44993b7987031b6618409675fdbb1f15ec4ea343)), closes [#20648](https://github.com/ionic-team/ionic/issues/20648)
## [5.0.4](https://github.com/ionic-team/ionic/compare/v5.0.3...v5.0.4) (2020-02-27)
### Bug Fixes
* **animation:** reset all temporary flags when interrupting an animation ([#20627](https://github.com/ionic-team/ionic/issues/20627)) ([0e0e401](https://github.com/ionic-team/ionic/commit/0e0e401d86dabaa1dc804656e4d384154d6fdd05)), closes [#20602](https://github.com/ionic-team/ionic/issues/20602)
* **buttons:** use proper button colors based on CSS variables when inside of a toolbar ([#20633](https://github.com/ionic-team/ionic/issues/20633)) ([c1d7bf2](https://github.com/ionic-team/ionic/commit/c1d7bf229d10d0a12f90b6d2730d6d8ac78b48cd))
## [5.0.3](https://github.com/ionic-team/ionic/compare/v5.0.2...v5.0.3) (2020-02-26)
### Bug Fixes
* **menu:** allow ssr to work properly with hardware back button updates ([#20629](https://github.com/ionic-team/ionic/issues/20629)) ([fe8d74d](https://github.com/ionic-team/ionic/commit/fe8d74d08cb919ed1c685262f0aed4a544c3a7e1))
## [5.0.2](https://github.com/ionic-team/ionic/compare/v5.0.1...v5.0.2) (2020-02-26)
### Bug Fixes
* **ios:** large title transition works properly in tabbed applications ([#20555](https://github.com/ionic-team/ionic/issues/20555)) ([7187541](https://github.com/ionic-team/ionic/commit/71875417f207d26bd7115655f239251460a1e3d8)), closes [#20482](https://github.com/ionic-team/ionic/issues/20482)
* **menu:** hardware back button now dismisses side menu if open in Cordova/Capacitor app ([#20558](https://github.com/ionic-team/ionic/issues/20558)) ([6b2a929](https://github.com/ionic-team/ionic/commit/6b2a929cd7e70b16383cb3336b399a1aee2d6101)), closes [#20559](https://github.com/ionic-team/ionic/issues/20559)
* **modal:** allow swipe to close animation to be overridden ([#20585](https://github.com/ionic-team/ionic/issues/20585)) ([8d3ce8d](https://github.com/ionic-team/ionic/commit/8d3ce8d29c9abd89ce47c882e0d7b2ac0f861966)), closes [#20577](https://github.com/ionic-team/ionic/issues/20577)
* **modal:** card style modal now adds appropriate contrast ([#20604](https://github.com/ionic-team/ionic/issues/20604)) ([b5310ef](https://github.com/ionic-team/ionic/commit/b5310effe3f9b47459f22221da1853a55dbb0279))
* **modal:** allow swipeable modal background to be overridden ([#20584](https://github.com/ionic-team/ionic/issues/20584)) ([ad6fac8](https://github.com/ionic-team/ionic/commit/ad6fac83cb7c4acb377b4b1620ab1a3f852bc6d3)), closes [#20572](https://github.com/ionic-team/ionic/issues/20572)
* **modal:** swipeable modal styles only apply to ios ([#20571](https://github.com/ionic-team/ionic/issues/20571)) ([3a2d828](https://github.com/ionic-team/ionic/commit/3a2d82814b22a3987a5abfe4412d83a93a97b6b7)), closes [#20569](https://github.com/ionic-team/ionic/issues/20569)
* **refresher:** ensure that translate is cleaned up to avoid stacking context ([#20621](https://github.com/ionic-team/ionic/issues/20621)) ([e3e5c69](https://github.com/ionic-team/ionic/commit/e3e5c69681f376cbc4b1305f719fc6895b21a9b7)), closes [#17949](https://github.com/ionic-team/ionic/issues/17949)
* **segment:** segment functions properly on older versions of Android ([#20554](https://github.com/ionic-team/ionic/issues/20554)) ([0224bed](https://github.com/ionic-team/ionic/commit/0224bed0c9f91bcb54bb4b3064df56928cf5ed8a)), closes [#20466](https://github.com/ionic-team/ionic/issues/20466)
* **select:** properly align text, add icon-inner and placeholder part ([#20605](https://github.com/ionic-team/ionic/issues/20605)) ([926ac3f](https://github.com/ionic-team/ionic/commit/926ac3fb47228be19146ccdfab92a05cf6677ff4))
* **slides:** set height to 100% for vertical slides ([#20603](https://github.com/ionic-team/ionic/issues/20603)) ([20af652](https://github.com/ionic-team/ionic/commit/20af652a1be5e1aff2836422489642c8baed6939)), closes [#17341](https://github.com/ionic-team/ionic/issues/17341)
## [5.0.1](https://github.com/ionic-team/ionic/compare/v5.0.0...v5.0.1) (2020-02-19)
### Bug Fixes
* **button:** reduce font size of icon only button in toolbar on iOS ([#20547](https://github.com/ionic-team/ionic/issues/20547)) ([59fa340](https://github.com/ionic-team/ionic/commit/59fa340650840b2abf86bd643350da7064ee9ead))
* **card:** inherit background in inner button ([#20461](https://github.com/ionic-team/ionic/issues/20461)) ([c16de96](https://github.com/ionic-team/ionic/commit/c16de9663329993698c10e4251dbb0b75167701f)), closes [#20458](https://github.com/ionic-team/ionic/issues/20458)
* **fab:** add close icon to internal icons for react ([#20490](https://github.com/ionic-team/ionic/issues/20490)) ([c4fb314](https://github.com/ionic-team/ionic/commit/c4fb31403eb4704bcf04e6c32bfa46422f08bf4f)), closes [#20489](https://github.com/ionic-team/ionic/issues/20489)
* **fab:** show close icon on hover, focused, activated ([#20497](https://github.com/ionic-team/ionic/issues/20497)) ([e42c85d](https://github.com/ionic-team/ionic/commit/e42c85d64161b7fac7147325cb6c2ceff990042b))
* **input:** do not clear input if "Enter" key pressed ([#20462](https://github.com/ionic-team/ionic/issues/20462)) ([89bf08b](https://github.com/ionic-team/ionic/commit/89bf08b6276f2a25d66fc0e74ba3303f923af652)), closes [#20442](https://github.com/ionic-team/ionic/issues/20442)
* **ios:** clamp out of bounds values for swipe to go back ([#20540](https://github.com/ionic-team/ionic/issues/20540)) ([dd32a5e](https://github.com/ionic-team/ionic/commit/dd32a5e2788a11a5c2be0d1840f5775c7307c57f)), closes [#20505](https://github.com/ionic-team/ionic/issues/20505)
* **menu:** swipe gesture should not open menu when a modal is displayed ([#20546](https://github.com/ionic-team/ionic/issues/20546)) ([3252c2f](https://github.com/ionic-team/ionic/commit/3252c2f8dc46e0853a7f626baa6023a01ac21a25)), closes [#20467](https://github.com/ionic-team/ionic/issues/20467)
* **modal:** presenting multiple card-style modals now adds border radius properly ([#20476](https://github.com/ionic-team/ionic/issues/20476)) ([abf594a](https://github.com/ionic-team/ionic/commit/abf594aa611562a76e3baecfa38456d41a1410f3)), closes [#20475](https://github.com/ionic-team/ionic/issues/20475)
* **modal:** prevent card style modal styles from being overridden ([#20470](https://github.com/ionic-team/ionic/issues/20470)) ([86ab77a](https://github.com/ionic-team/ionic/commit/86ab77a6e2cb124510c244110fc78a4bc0654cd1)), closes [#20469](https://github.com/ionic-team/ionic/issues/20469)
* **react:** do a better job matching up route to sync ([#20446](https://github.com/ionic-team/ionic/issues/20446)) ([c0aadd6](https://github.com/ionic-team/ionic/commit/c0aadd60077e5ba379959d93006e3a9c1418263c)), closes [#20363](https://github.com/ionic-team/ionic/issues/20363)
* **react:** do not remove pages when navigating between tabs ([#20431](https://github.com/ionic-team/ionic/issues/20431)) ([b6fbe98](https://github.com/ionic-team/ionic/commit/b6fbe98812fbab5ef9e0723802605c0711581dd2)), closes [#20398](https://github.com/ionic-team/ionic/issues/20398)
* **react:** icons with MD set should work in browser ([#20463](https://github.com/ionic-team/ionic/issues/20463)) ([82670fe](https://github.com/ionic-team/ionic/commit/82670fe4d0592451cbc243b3008beb3f8f483c30))
* **react:** update paths of tab buttons when href changes in ion buttons ([#20480](https://github.com/ionic-team/ionic/issues/20480)) ([45d03ba](https://github.com/ionic-team/ionic/commit/45d03baf981d0e10eb1fe689908532adef2ba31d)), closes [#20321](https://github.com/ionic-team/ionic/issues/20321)
* **searchbar:** properly align placeholder ([#20460](https://github.com/ionic-team/ionic/issues/20460)) ([4d6e15a](https://github.com/ionic-team/ionic/commit/4d6e15ab18fc894c3826b89362163256adc227f4)), closes [#20456](https://github.com/ionic-team/ionic/issues/20456)
* **segment:** border radius applies to indicator on ios ([#20541](https://github.com/ionic-team/ionic/issues/20541)) ([9b5854d](https://github.com/ionic-team/ionic/commit/9b5854d79712356f8a3772442c0cc412db09d5e0)), closes [#20539](https://github.com/ionic-team/ionic/issues/20539)
* **segment:** do not show ripple effect if disabled via config ([#20542](https://github.com/ionic-team/ionic/issues/20542)) ([7a461c5](https://github.com/ionic-team/ionic/commit/7a461c59c5d9a23de0bcdd53397f452d17251fd6)), closes [#20533](https://github.com/ionic-team/ionic/issues/20533)
* **segment:** inner div no longer interferes with click events ([#20522](https://github.com/ionic-team/ionic/issues/20522)) ([06b828b](https://github.com/ionic-team/ionic/commit/06b828b4ffb12b076b0805274f53fa158ee65c5a)), closes [#20381](https://github.com/ionic-team/ionic/issues/20381)
* **segment:** only emit ionChange when user releases pointer from screen ([#20495](https://github.com/ionic-team/ionic/issues/20495)) ([4d50064](https://github.com/ionic-team/ionic/commit/4d5006476479bc376d3bb4edad6db0b3ce806ef7)), closes [#20500](https://github.com/ionic-team/ionic/issues/20500) [#20257](https://github.com/ionic-team/ionic/issues/20257)
* **tab-bar:** update ios icon and label design to match native ([#20548](https://github.com/ionic-team/ionic/issues/20548)) ([34f8576](https://github.com/ionic-team/ionic/commit/34f8576b959d41896502e4f7b0c4240156e001eb))
# [5.0.0 Magnesium](https://github.com/ionic-team/ionic/compare/v4.11.10...v5.0.0) (2020-02-11)
Enjoy! :fire:
> We recommend updating to version `4.11.10` before updating to this version in order to see deprecation warnings related to your app [in the developer console](https://javascript.info/devtools).
Run the following commands based on your project type:
```
# for an angular app
npm i @ionic/angular@latest --save
# for a react app
npm i @ionic/react@latest --save
npm i @ionic/react-router@latest --save
npm i ionicons@latest --save
# for a stencil / vanilla JS app
npm i @ionic/core@latest --save
```
Then take a look at the [Breaking Changes](./BREAKING.md) file for API changes.
# [5.0.0-rc.5](https://github.com/ionic-team/ionic/compare/v5.0.0-rc.4...v5.0.0-rc.5) (2020-02-11)
### Bug Fixes
* **angular:** correct path for angular projects ([#20436](https://github.com/ionic-team/ionic/issues/20436)) ([fd9c7a9](https://github.com/ionic-team/ionic/commit/fd9c7a9601e7f21b74c76be1f8bb305bf008915c)), closes [#20435](https://github.com/ionic-team/ionic/issues/20435)
# [5.0.0-rc.4](https://github.com/ionic-team/ionic/compare/v5.0.0-rc.3...v5.0.0-rc.4) (2020-02-10)
### Bug Fixes
* **content:** only emit scroll events if enabled ([#20401](https://github.com/ionic-team/ionic/issues/20401)) ([fd1b44a](https://github.com/ionic-team/ionic/commit/fd1b44a40b741088e099f6538dd14caa0dc5540c))
* **header:** backdrop filter no longer distorts content with collapsible header ([#20388](https://github.com/ionic-team/ionic/issues/20388)) ([11d3945](https://github.com/ionic-team/ionic/commit/11d39457d56c091e9c41c180391d27464ae748b5)), closes [#20385](https://github.com/ionic-team/ionic/issues/20385)
* **item:** remove unneeded box-shadow CSS variable ([#20412](https://github.com/ionic-team/ionic/issues/20412)) ([a6764c4](https://github.com/ionic-team/ionic/commit/a6764c4724e1e7eed19a1902b563aeb61bfde38e)), closes [#20392](https://github.com/ionic-team/ionic/issues/20392)
* **label:** remove subpixel font-size to prevent visual glitches ([#20415](https://github.com/ionic-team/ionic/issues/20415)) ([3d6f287](https://github.com/ionic-team/ionic/commit/3d6f287d87bfaa0d81a34182baf38192e08fb3c1)), closes [#20407](https://github.com/ionic-team/ionic/issues/20407)
* **segment:** add activated class directly to segment button ([#20400](https://github.com/ionic-team/ionic/issues/20400)) ([e8886e9](https://github.com/ionic-team/ionic/commit/e8886e98f188044227bf5757892341cb598fdd27))
# [5.0.0-rc.3](https://github.com/ionic-team/ionic/compare/v5.0.0-rc.2...v5.0.0-rc.3) (2020-02-05)
### Bug Fixes
* **refresher:** ensure gesture does not interfere with item-sliding ([#20380](https://github.com/ionic-team/ionic/issues/20380)) ([8983c70](https://github.com/ionic-team/ionic/commit/8983c7006e54743873cd45ae1acdfa974d74547a)), closes [#20379](https://github.com/ionic-team/ionic/issues/20379)
* **refresher:** translate background content when refreshing ([#20378](https://github.com/ionic-team/ionic/issues/20378)) ([cf70916](https://github.com/ionic-team/ionic/commit/cf7091625ecb46c3f9882ae9eff5c946523fab75)), closes [#20377](https://github.com/ionic-team/ionic/issues/20377)
* **segment:** allow background to be set on iOS segment in a toolbar ([#20350](https://github.com/ionic-team/ionic/issues/20350)) ([0f31624](https://github.com/ionic-team/ionic/commit/0f31624104d195367df197eda9b8d6c5bda4cf75))
* **toolbar:** properly apply safe area and border ([#20375](https://github.com/ionic-team/ionic/issues/20375)) ([4971499](https://github.com/ionic-team/ionic/commit/4971499026fcee70a32cc9480302bb14a1bebcb7)), closes [#20354](https://github.com/ionic-team/ionic/issues/20354)
# [5.0.0-rc.2](https://github.com/ionic-team/ionic/compare/v5.0.0-rc.1...v5.0.0-rc.2) (2020-01-30)
### Bug Fixes
* **header:** fix race condition in collapsible header ([#20334](https://github.com/ionic-team/ionic/issues/20334)) ([215d55f](https://github.com/ionic-team/ionic/commit/215d55f1ebeb93988b513c5869faae14d1d51919))
* **ios:** translucent toolbar blur no longer obscures entering page toolbar content ([#20314](https://github.com/ionic-team/ionic/issues/20314)) ([e580b88](https://github.com/ionic-team/ionic/commit/e580b884770a086ee5d8acf61588ea50181786e6)), closes [#19158](https://github.com/ionic-team/ionic/issues/19158)
* **radio:** do not clear radio group value from radio ([#20343](https://github.com/ionic-team/ionic/issues/20343)) ([ff78e6e](https://github.com/ionic-team/ionic/commit/ff78e6e8ca8ae4dc2a6d401b377dd3977c48824a)), closes [#20323](https://github.com/ionic-team/ionic/issues/20323)
* **radio:** set default radio value if undefined ([#20329](https://github.com/ionic-team/ionic/issues/20329)) ([eb57723](https://github.com/ionic-team/ionic/commit/eb57723785ce5b05585bf48bf9c8ae1b62235ba2))
* **refresher:** add correct fallbacks for native refreshers ([#20333](https://github.com/ionic-team/ionic/issues/20333)) ([fd55427](https://github.com/ionic-team/ionic/commit/fd55427991e94488d86971aaa10acb13d7fa1c23))
* **refresher:** resolve undefined issues when updating component ([#20322](https://github.com/ionic-team/ionic/issues/20322)) ([59d8687](https://github.com/ionic-team/ionic/commit/59d86873a2ab913358b084bb05180ba176893a8f)), closes [#20320](https://github.com/ionic-team/ionic/issues/20320)
# [5.0.0-rc.1](https://github.com/ionic-team/ionic/compare/v4.11.10...v5.0.0-rc.1) (2020-01-27)
### Bug Fixes
* **components:** use proper colors for button states and add back input highlight ([#20278](https://github.com/ionic-team/ionic/issues/20278)) ([628db18](https://github.com/ionic-team/ionic/commit/628db18a97293731ecfee8e4d2f0d8c1cf672c96)), closes [#20276](https://github.com/ionic-team/ionic/issues/20276)
* **components:** inherit text indent in all components with text inherit ([#20300](https://github.com/ionic-team/ionic/issues/20300)) ([767b005](https://github.com/ionic-team/ionic/commit/767b005eacf00b640973bfb381de4dcedf083399)), closes [#17786](https://github.com/ionic-team/ionic/issues/17786)
* **content:** resolve height inheritance issues ([#20309](https://github.com/ionic-team/ionic/issues/20309)) ([09bef71](https://github.com/ionic-team/ionic/commit/09bef71ccd5a261233180bc19023bc562b905764)), closes [#20305](https://github.com/ionic-team/ionic/issues/20305)
* **picker:** include showBackdrop in interface ([#20301](https://github.com/ionic-team/ionic/issues/20301)) ([33186ba](https://github.com/ionic-team/ionic/commit/33186ba716de77edc92ae8e7d307f90fff8b8ed1)), closes [#18893](https://github.com/ionic-team/ionic/issues/18893)
* **react:** export proper types of animations and gestures ([#20311](https://github.com/ionic-team/ionic/issues/20311)) ([0034088](https://github.com/ionic-team/ionic/commit/00340885fb031d3dbc7c458fddeed9d28a2deda4))
* **refresher:** update animation for dashed property values ([#20310](https://github.com/ionic-team/ionic/issues/20310)) ([44211c1](https://github.com/ionic-team/ionic/commit/44211c11ee929b9966d5e67e99fb6a495380432c))
* **toast:** inherit color in cancel button for a toast with color ([#20299](https://github.com/ionic-team/ionic/issues/20299)) ([7b44ae2](https://github.com/ionic-team/ionic/commit/7b44ae2a400bb0c0616012e9c42bfc67edbfc793)), closes [#20139](https://github.com/ionic-team/ionic/issues/20139)
## [4.11.10](https://github.com/ionic-team/ionic/compare/v4.11.9...v4.11.10) (2020-01-24)
### Bug Fixes
* **input:** revert previous type change ([db1fd1d](https://github.com/ionic-team/ionic/commit/db1fd1d72a8a0ade824ad2309d1adb2953731f37))
# [5.0.0-rc.0](https://github.com/ionic-team/ionic/compare/v5.0.0-beta.6...v5.0.0-rc.0) (2020-01-23)
Release Candidate is here! :tada:
# [5.0.0-beta.6](https://github.com/ionic-team/ionic/compare/v4.11.9...v5.0.0-beta.6) (2020-01-23)
### Bug Fixes
* **animation:** add property conversions for CSS Animations ([#20252](https://github.com/ionic-team/ionic/issues/20252)), fixes [#20251](https://github.com/ionic-team/ionic/issues/20251) ([32a7401](https://github.com/ionic-team/ionic/commit/32a7401576a9c91fdee66d2cede06b6a16884d35))
* **content:** set min-height to allow for sticky headers ([#20265](https://github.com/ionic-team/ionic/issues/20252)), fixes [#20258](https://github.com/ionic-team/ionic/issues/20258) ([e613f63](https://github.com/ionic-team/ionic/commit/e613f63590f3d6a4fa4f3a361811224394ba0be2))
* **modal:** card-style modal now opens at full width on larger devices ([#20256](https://github.com/ionic-team/ionic/issues/20256)), fixes [#20255](https://github.com/ionic-team/ionic/issues/20255) ([443cbd9](https://github.com/ionic-team/ionic/commit/443cbd9eb273767d8405b6a05ffabee037e9f3b7))
* **segment:** clicking disabled button no longer adds ripple to active button ([#20254](https://github.com/ionic-team/ionic/issues/20254)), fixes [#20253](https://github.com/ionic-team/ionic/issues/20253) ([f896821](https://github.com/ionic-team/ionic/commit/f8968217533ff60948047510064d2f15d01c249c))
### Features
* **components:** improve button states and add new css properties ([#19440](https://github.com/ionic-team/ionic/issues/19440)) ([9415929](https://github.com/ionic-team/ionic/commit/94159291b27ddf1a859c8f3f87a0d6e54a8b5f13)), closes [#20213](https://github.com/ionic-team/ionic/issues/20213) [#19965](https://github.com/ionic-team/ionic/issues/19965)
* **react:** add Ionic Animations wrapper (experimental) ([#20273](https://github.com/ionic-team/ionic/issues/20273)) ([b59d764](https://github.com/ionic-team/ionic/commit/b59d7647fd6f9a645a4ec0fe9aca526ea5eda4e0))
* **segment-button:** add --indicator-height property to segment button ([#19653](https://github.com/ionic-team/ionic/issues/19653)) ([d76a503](https://github.com/ionic-team/ionic/commit/d76a5031c4c96b5fdf691a56ed61d3dcc4e4dafb))
### BREAKING CHANGES
> We recommend updating to the latest version of 4.x before trying out version 5 in order to see deprecation warnings related to your app [in the developer console](https://javascript.info/devtools).
*Activated Class*
The `activated` class that is automatically added to buttons on press has been renamed to `ion-activated`. This will be more consistent with our `ion-focused` class we add and also will reduce conflicts with users' CSS.
*CSS Variables*
The `--background-hover`, `--background-focused` and `--background-activated` CSS variables on components that render native buttons will now have an opacity automatically set. If you are setting any of these like the following:
```
--background-hover: rgba(44, 44, 44, 0.08);
```
You will likely not see a hover state anymore. It should be updated to only set the desired color:
```
--background-hover: rgba(44, 44, 44);
```
If the opacity desired is something other than what the spec asks for, use:
```
--background-hover: rgba(44, 44, 44);
--background-hover-opacity: 1;
```
## [4.11.9](https://github.com/ionic-team/ionic/compare/v4.11.8...v4.11.9) (2020-01-23)
### Bug Fixes
* **core:** updating type of input value to accept numbers, fixes [#20173](https://github.com/ionic-team/ionic/issues/20173) ([#20267](https://github.com/ionic-team/ionic/issues/20267)) ([7080205](https://github.com/ionic-team/ionic/commit/708020551f9c51ca3b32d7b49bf4572db3dda12e))
* **react:** adding missing overlay component events, fixes [#19923](https://github.com/ionic-team/ionic/issues/19923) ([#20266](https://github.com/ionic-team/ionic/issues/20266)) ([ec6a8dd](https://github.com/ionic-team/ionic/commit/ec6a8dd86f3854edba367f79a6ebac7d60eed839))
* **react:** Don't render overlay children if isOpen is false, fixes [#20225](https://github.com/ionic-team/ionic/issues/20225) ([#20226](https://github.com/ionic-team/ionic/issues/20226)) ([aff9612](https://github.com/ionic-team/ionic/commit/aff9612d1197dca48eab6eff9d749032c380cf82))
* **react:** re attach props on update, fixes 20192 ([#20228](https://github.com/ionic-team/ionic/issues/20228)) ([9e35ebe](https://github.com/ionic-team/ionic/commit/9e35ebed4a1590ef2521f5f8c393bdd9dea32a04))
* **react:** remove leaving view when routerdirection is back, fixes [#20124](https://github.com/ionic-team/ionic/issues/20124) ([#20268](https://github.com/ionic-team/ionic/issues/20268)) ([63d4e87](https://github.com/ionic-team/ionic/commit/63d4e877fb18c90d70c4cbd5f66ffccb8ee6489c))
* **react:** support routes without a path for notfound routes, fixes [#20259](https://github.com/ionic-team/ionic/issues/20259) ([#20261](https://github.com/ionic-team/ionic/issues/20261)) ([2f8c13b](https://github.com/ionic-team/ionic/commit/2f8c13b6960f9bcfb941c36fa6e1742b96f80ba9))
* **react:** update icon types to be a string as well, fixes [#20229](https://github.com/ionic-team/ionic/issues/20229) ([#20230](https://github.com/ionic-team/ionic/issues/20230)) ([1411d8a](https://github.com/ionic-team/ionic/commit/1411d8a173bfefd7db5241218fd5641b7e9da823))
# [5.0.0-beta.5](https://github.com/ionic-team/ionic/compare/v4.11.8...v5.0.0-beta.5) (2020-01-17)
### Bug Fixes
* **action-sheet:** allow scrollable action sheet with many options ([#20145](https://github.com/ionic-team/ionic/issues/20145)) ([53fad97](https://github.com/ionic-team/ionic/commit/53fad978c5a57efe34671db6cbede49c4a5af866)), closes [#17311](https://github.com/ionic-team/ionic/issues/17311)
* **card:** remove top padding of content in iOS if under header ([#20223](https://github.com/ionic-team/ionic/issues/20223)) ([9232f16](https://github.com/ionic-team/ionic/commit/9232f16eea8163c1ac0797abd9b6e92da44bacb1))
* **content:** scroll-content div now takes up full height of container ([#20194](https://github.com/ionic-team/ionic/issues/20194)) ([9d63b41](https://github.com/ionic-team/ionic/commit/9d63b41a5296688524c64f828f92090d73d6b556)), closes [#20185](https://github.com/ionic-team/ionic/issues/20185)
* **header:** header opacity properly resets on collapsible titles ([#20202](https://github.com/ionic-team/ionic/issues/20202)) ([8e11f79](https://github.com/ionic-team/ionic/commit/8e11f79fcca94a9c50ccc7e18e0fe44ef9764b1d))
* **modal:** prevent double dismiss via gesture and backdrop tap on card-style modal ([#20203](https://github.com/ionic-team/ionic/issues/20203)) ([5b0400d](https://github.com/ionic-team/ionic/commit/5b0400d5afec308861408967a5f61c9b93af0004))
* **picker:** pick correct option at low velocities ([#19660](https://github.com/ionic-team/ionic/issues/19660)) ([39d1262](https://github.com/ionic-team/ionic/commit/39d12629dbc12e4a86037b09350ec1c49ed6e2e4)), closes [#19659](https://github.com/ionic-team/ionic/issues/19659)
* **react:** updating icon type and add caret to internal icons ([#20216](https://github.com/ionic-team/ionic/issues/20216)) ([dc78f98](https://github.com/ionic-team/ionic/commit/dc78f981531960791a425b3b1b81d45d5065a263))
* **ssr:** add reflect content-id attribute to applicable properties ([#20169](https://github.com/ionic-team/ionic/issues/20169)) ([3aa47e6](https://github.com/ionic-team/ionic/commit/3aa47e6e2f18c3a07f2c0560a0946571e8e6815d))
### Code Refactoring
* removed checked/selected properties in favor of setting value on parent ([#19449](https://github.com/ionic-team/ionic/issues/19449)) ([a5229d9](https://github.com/ionic-team/ionic/commit/a5229d90ca2a608e8bf4db0c8f71c86d481dd649))
### Features
* **datetime:** add custom timezone display property ([#19519](https://github.com/ionic-team/ionic/issues/19519)) ([7b032c5](https://github.com/ionic-team/ionic/commit/7b032c5e9b396fcfb0b0e313aff1bebcbc43305e)), closes [#19401](https://github.com/ionic-team/ionic/issues/19401)
* **segment:** update design for iOS and MD spec ([#19036](https://github.com/ionic-team/ionic/issues/19036)) ([dc66ce4](https://github.com/ionic-team/ionic/commit/dc66ce48e1f210ca57cecae5c89e5dc3b7e95de5)), closes [#18663](https://github.com/ionic-team/ionic/issues/18663)
* **toast:** expose shadow parts ([#20146](https://github.com/ionic-team/ionic/issues/20146)) ([3b4988a](https://github.com/ionic-team/ionic/commit/3b4988aa60dc6d31e1bc3367cb8f5e8d85710ac6))
### BREAKING CHANGES
> We recommend updating to the latest version of 4.x before trying out version 5 in order to see deprecation warnings related to your app [in the developer console](https://javascript.info/devtools).
* The following components have been updated to remove the checked or selected properties:
- Radio
- Segment Button
- Select
Developers should set the value property on the respective parent components in order to managed checked/selected status. See the [Breaking Changes](./BREAKING.md) document for updated usage examples.
* Controller components have been removed. Developers should user their respective imports instead. This only affects vanilla JS applications.
Before:
```html
<ion-modal-controller></ion-modal-controller>
```
After:
```javascript
import { modalController } from '@ionic/core';
```
## [4.11.8](https://github.com/ionic-team/ionic/compare/v4.11.7...v4.11.8) (2020-01-13)
* **react:** add missing react memory router ([8a5aba2](https://github.com/ionic-team/ionic/commit/8a5aba206865ce2af7f8bb85f4e7cd8dec37831d))
* **react:** fixing type of icon in ToastOptions, ActionSheetOptions, fixes [#20100](https://github.com/ionic-team/ionic/issues/20100) ([857bab6](https://github.com/ionic-team/ionic/commit/857bab66419a851c6d189cd1456cd67c1c2d934c))
* **react:** supporting ios and md props on icons ([#20170](https://github.com/ionic-team/ionic/issues/20170)) ([676cc19](https://github.com/ionic-team/ionic/commit/676cc19b89cd6374346aaac9cc3292872c7148fa))
# [5.0.0-beta.4](https://github.com/ionic-team/ionic/compare/v5.0.0-beta.3...v5.0.0-beta.4) (2020-01-06)
### Features
* **refresher:** add MD native refresher ([#20096](https://github.com/ionic-team/ionic/issues/20096)) ([5b81bdf](https://github.com/ionic-team/ionic/commit/5b81bdfcf18ed182bde14bbea4957b49ea886322)), closes [#17316](https://github.com/ionic-team/ionic/issues/17316)
# [5.0.0-beta.3](https://github.com/ionic-team/ionic/compare/v4.11.7...v5.0.0-beta.3) (2020-01-03)
### Bug Fixes
* **animation:** support css animation on older devices ([#20020](https://github.com/ionic-team/ionic/issues/20020)) ([49c394c](https://github.com/ionic-team/ionic/commit/49c394c3d335795fd100f54a5b29db009d413dff)), closes [#20017](https://github.com/ionic-team/ionic/issues/20017)
* **icons:** fix the ellipsis fill in ionicons ([#20137](https://github.com/ionic-team/ionic/issues/20137)) ([9318d24](https://github.com/ionic-team/ionic/commit/9318d2418ec144bbce4a3b7ead33cf099d6ec25b))
* **modal:** account for safe area on devices with a notch ([#20072](https://github.com/ionic-team/ionic/issues/20072)) ([1cabb53](https://github.com/ionic-team/ionic/commit/1cabb5365097d0675447a36223583824a58a140c))
* **react:** fire lifecycle events on initial render, fixes [#20071](https://github.com/ionic-team/ionic/issues/20071) ([2dcf3ee](https://github.com/ionic-team/ionic/commit/2dcf3ee7b570be73be35c52f03ccfa09baf5d830))
### Code Refactoring
* **searchbar:** set inputmode default to undefined ([#20080](https://github.com/ionic-team/ionic/issues/20080)) ([6612604](https://github.com/ionic-team/ionic/commit/6612604733ac1b3e46546625f24ef6efa5be1538)), closes [#20074](https://github.com/ionic-team/ionic/issues/20074)
### Features
* **angular:** angular 9 support ([#19515](https://github.com/ionic-team/ionic/issues/19515)) ([2344d0b](https://github.com/ionic-team/ionic/commit/2344d0b272105e368c00ef611f28909215162f7c))
* **checkbox:** add --checkmark-width variable ([#19933](https://github.com/ionic-team/ionic/issues/19933)) ([c32a7bc](https://github.com/ionic-team/ionic/commit/c32a7bcd202993056923857a5d9eed14f5be8580)), closes [#16803](https://github.com/ionic-team/ionic/issues/16803)
* **radio:** add --border-radius and --inner-border-radius variables ([#20140](https://github.com/ionic-team/ionic/issues/20140)) ([a01c102](https://github.com/ionic-team/ionic/commit/a01c10267e18a48f30af2f552c556d31dad582e9))
* **refresher:** add iOS native refresher ([#20037](https://github.com/ionic-team/ionic/issues/20037)) ([04e7c03](https://github.com/ionic-team/ionic/commit/04e7c031326ec551531af291ef1a03878d168378)), closes [#18664](https://github.com/ionic-team/ionic/issues/18664)
* **toggle:** add --border-radius and --handle-border-radius variables ([#20141](https://github.com/ionic-team/ionic/issues/20141)) ([02a46a1](https://github.com/ionic-team/ionic/commit/02a46a1007dde820cb158d34d4e3f243c07251dc))
### BREAKING CHANGES
> We recommend updating to the latest version of 4.x before trying out version 5 in order to see deprecation warnings related to your app [in the developer console](https://javascript.info/devtools).
* **searchbar:** The `inputmode` property for `ion-searchbar` now defaults to `undefined`. To get the old behavior, set the `inputmode` property to `"search"`.
## [4.11.7](https://github.com/ionic-team/ionic/compare/v4.11.6...v4.11.7) (2019-12-12)
### Bug Fixes
* **react:** fire lifecycle events on initial render, fixes [#20071](https://github.com/ionic-team/ionic/issues/20071) ([9ea75eb](https://github.com/ionic-team/ionic/commit/9ea75ebec7b1367fc0e319fe61c1f42516357e10))
# [5.0.0-beta.2](https://github.com/ionic-team/ionic/compare/v5.0.0-beta.1...v5.0.0-beta.2) (2019-12-11)
### Bug Fixes
* **animation:** convert hyphenated properties to camel case when using Web Animations ([#20059](https://github.com/ionic-team/ionic/issues/20059)) ([56f67bd](https://github.com/ionic-team/ionic/commit/56f67bd9a5c8c81768e310560b2605e44bf7a9f0)), closes [#20058](https://github.com/ionic-team/ionic/issues/20058)
* **animation:** properly update Web Animation object ([#19964](https://github.com/ionic-team/ionic/issues/19964)) ([e766194](https://github.com/ionic-team/ionic/commit/e76619478c3c49469fcc22e264cc831d498abf8d))
* **picker:** pass selected value to handler on dismiss ([#20042](https://github.com/ionic-team/ionic/issues/20042)) ([6e0b9c4](https://github.com/ionic-team/ionic/commit/6e0b9c45489889266620ee2ca38c33fdf8ce3f3b)), closes [#20036](https://github.com/ionic-team/ionic/issues/20036)
* **tabs:** preserve route navigation extras when changing tabs ([#18493](https://github.com/ionic-team/ionic/issues/18493)) ([4c8f32f](https://github.com/ionic-team/ionic/commit/4c8f32fae99db4022aa9dc75187e2f161e8e678e)), closes [#18717](https://github.com/ionic-team/ionic/issues/18717)
* **title:** add correct safe area to large title nav transition ([#20029](https://github.com/ionic-team/ionic/issues/20029)) ([300d543](https://github.com/ionic-team/ionic/commit/300d54356df925bb94f22b6805e48c88d1e56a26)), closes [#20028](https://github.com/ionic-team/ionic/issues/20028)
### Features
* **modal:** add card-style presentation with swipe to close gesture ([#19428](https://github.com/ionic-team/ionic/issues/19428)) ([b3b3312](https://github.com/ionic-team/ionic/commit/b3b33127115bb966980a1288a0005dfb09306881)), closes [#18660](https://github.com/ionic-team/ionic/issues/18660)
## [4.11.6](https://github.com/ionic-team/ionic/compare/v4.11.5...v4.11.6) (2019-12-11)
### Bug Fixes
* **react:** don't show back button when not appropriate ([684293d](https://github.com/ionic-team/ionic/commit/684293ddbf1ad4edce590d56f7ff66fcd6c817a5))
* **react:** first render performance improvements ([1c7d1e5](https://github.com/ionic-team/ionic/commit/1c7d1e5cf1ad7e53ebbee2566e8fa89f567f7fb5))
* **react:** fix refs for controllers, overlays, ionpage, and ionrouteroutlet, fixes [#19924](https://github.com/ionic-team/ionic/issues/19924) ([#20012](https://github.com/ionic-team/ionic/issues/20012)) ([eef55bb](https://github.com/ionic-team/ionic/commit/eef55bb0072a9e54b1fd7d1c8c69e7fd43b2a5c5))
* **react:** support for 'root' router direction, fixes [#19982](https://github.com/ionic-team/ionic/issues/19982) ([#20052](https://github.com/ionic-team/ionic/issues/20052)) ([e116712](https://github.com/ionic-team/ionic/commit/e1167122758b23221935e897bcd65839b75c59aa))
* **react:** support navigating to same page and route updates in IonRouterOutlet, fixes [#19891](https://github.com/ionic-team/ionic/issues/19891), [#19892](https://github.com/ionic-team/ionic/issues/19892), [#19986](https://github.com/ionic-team/ionic/issues/19986) ([f9bf8db](https://github.com/ionic-team/ionic/commit/f9bf8dbe6f952ee53b6b213a4c0d043d25f49b93))
### Upgrade Note
If you run into a "Property 'translate' is missing in type" error building after updating to 4.11.6, update your React Typings library to the latest:
npm i @types/react@latest @types/react-dom@latest
# [5.0.0-beta.1](https://github.com/ionic-team/ionic/compare/v5.0.0-beta.0...v5.0.0-beta.1) (2019-11-20)
### Bug Fixes
* **animation:** track correctly when updating CSS Animation ([#19813](https://github.com/ionic-team/ionic/issues/19813)) ([7bd4412](https://github.com/ionic-team/ionic/commit/7bd44128895b9fa4992142c0cc30cf75092cb794))
* **card:** update background to use the same as item ([#19602](https://github.com/ionic-team/ionic/issues/19602)) ([1a8b7a4](https://github.com/ionic-team/ionic/commit/1a8b7a4559860b3efa4778a78c905e30f18587bf))
* **content:** set fixed content to position absolute ([#19867](https://github.com/ionic-team/ionic/issues/19867)) ([fce3e24](https://github.com/ionic-team/ionic/commit/fce3e24600be6f04b285cda62fe2f21c49d809e2)), closes [#17754](https://github.com/ionic-team/ionic/issues/17754)
* **gesture:** release gesture when disabling ([#19855](https://github.com/ionic-team/ionic/issues/19855)) ([21484f1](https://github.com/ionic-team/ionic/commit/21484f1f3a9ebe46096c979fe3f2035892a53a62)), closes [#19848](https://github.com/ionic-team/ionic/issues/19848)
* **header:** avoid flicker on collapsible header load ([#19682](https://github.com/ionic-team/ionic/issues/19682)) ([0a7aae2](https://github.com/ionic-team/ionic/commit/0a7aae28a7eb0270cdcd100933c01850403b66db))
* **header:** avoid flicker when collapsing ([#19850](https://github.com/ionic-team/ionic/issues/19850)) ([a3666dd](https://github.com/ionic-team/ionic/commit/a3666ddf0ccc44c696121a8d6107015dbe7aeabb)), closes [#19839](https://github.com/ionic-team/ionic/issues/19839)
* **header:** support collapsible header with multiple toolbars ([#19909](https://github.com/ionic-team/ionic/issues/19909)) ([fc4bb2d](https://github.com/ionic-team/ionic/commit/fc4bb2db5c5715841347135bdfa1bf66718d647d))
* **header:** translucent toolbars now work with collapsible header ([#19774](https://github.com/ionic-team/ionic/issues/19774)) ([b642b53](https://github.com/ionic-team/ionic/commit/b642b532e8846042f1317dc936191d0934b23945)), closes [#19773](https://github.com/ionic-team/ionic/issues/19773)
* **title:** only animate large title if back button is in start slot ([#19846](https://github.com/ionic-team/ionic/issues/19846)) ([cace1b3](https://github.com/ionic-team/ionic/commit/cace1b357e5acd54d49f2b662ecee5de90add708)), closes [#19840](https://github.com/ionic-team/ionic/issues/19840)
* **nav-params:** set generic type on navigation parameters get() ([#19195](https://github.com/ionic-team/ionic/issues/19195)) ([504051d](https://github.com/ionic-team/ionic/commit/504051d709c8afe08d588747866d2ee924baf804))
* **picker:** pass data and role to dismiss ([#19787](https://github.com/ionic-team/ionic/issues/19787)) ([7988720](https://github.com/ionic-team/ionic/commit/7988720b1cf46a651d9c140f0fe95726d3feb48c)), closes [#18454](https://github.com/ionic-team/ionic/issues/18454)
* **searchbar:** use back button config value for cancel icon ([#19353](https://github.com/ionic-team/ionic/issues/19353)) ([3d6f3b9](https://github.com/ionic-team/ionic/commit/ed6f3b9f3f42ef85f3f2d083fa7fe37a69b491c8))
* **textarea:** remove padding from textarea placeholder ([#19694](https://github.com/ionic-team/ionic/issues/19694)) ([f63d37a](https://github.com/ionic-team/ionic/commit/f63d37a4c506801a19b9bf6e5ef05d415d680b0c)), closes [#19616](https://github.com/ionic-team/ionic/issues/19616)
* **toast:** call button handler on cancel ([#19793](https://github.com/ionic-team/ionic/issues/19793)) ([420aa66](https://github.com/ionic-team/ionic/commit/420aa6639214e7d2e7b7413e699ace3d7fd35e40)), closes [#19791](https://github.com/ionic-team/ionic/issues/19791)
### Features
* **animation:** animation identifiers ([#19771](https://github.com/ionic-team/ionic/issues/19771)) ([7d41715](https://github.com/ionic-team/ionic/commit/7d417154c5f1ba89e0a30084807ff7e164dd6eba)), closes [#19550](https://github.com/ionic-team/ionic/issues/19550)
* **animation:** cubic-bezier easing conversion utility (experimental) ([#19788](https://github.com/ionic-team/ionic/issues/19788)) ([96a5e60](https://github.com/ionic-team/ionic/commit/96a5e600e563489d93a26d5956d210f246f6fea5)), closes [#19789](https://github.com/ionic-team/ionic/issues/19789)
* **alert:** add support for textarea inputs ([#16851](https://github.com/ionic-team/ionic/issues/16851)) ([b28cf02](https://github.com/ionic-team/ionic/commit/b28cf02ef3979c844c498a8e30ee977937984828)), closes [#14153](https://github.com/ionic-team/ionic/issues/14153)
* **angular:** expose Ionic Animations via AnimationController ([#19745](https://github.com/ionic-team/ionic/issues/19745)) ([67a7e23](https://github.com/ionic-team/ionic/commit/67a7e232b9058620653feec5ed99e0ebf22b6620))
* **angular:** expose Ionic Gestures via GestureController ([#19864](https://github.com/ionic-team/ionic/issues/19864)) ([48a7662](https://github.com/ionic-team/ionic/commit/48a766246d08170c709345bba235275eef0bd020))
* **searchbar:** add --box-shadow variable to style searchbar input ([#19838](https://github.com/ionic-team/ionic/issues/19838)) ([1ab7066](https://github.com/ionic-team/ionic/commit/1ab7066aa085bc0185a6dd3d162439f7f82415fa))
* **select:** add --placeholder-opacity and --placeholder-color, expose shadow parts ([#19893](https://github.com/ionic-team/ionic/issues/19893)) ([bef0f53](https://github.com/ionic-team/ionic/commit/bef0f53d0dcb15c58221c2dec8c4c274d3b5c77e)), closes [#17446](https://github.com/ionic-team/ionic/issues/17446)
* **split-pane:** convert to shadow component, add width, max-width, and min-width vars ([#19754](https://github.com/ionic-team/ionic/issues/19754)) ([d80f455](https://github.com/ionic-team/ionic/commit/d80f45516d5dca62b77db1773206ef274d42f3ef)), closes [#17088](https://github.com/ionic-team/ionic/issues/17088)
### Breaking Changes
> We recommend updating to the latest version of 4.x before trying out version 5 in order to see deprecation warnings related to your app [in the developer console](https://javascript.info/devtools).
* **back-button:** convert back button to shadow ([#19411](https://github.com/ionic-team/ionic/pull/19411)) ([0d40d3f](https://github.com/ionic-team/ionic/commit/0d40d3f3b72aac7932ac71e6573d8bbb65a01515))
* **ionicons:** update to Ionicons v5. See https://ionicons.com for more information. ([#19670](https://github.com/ionic-team/ionic/pull/19670)) ([69e10de](https://github.com/ionic-team/ionic/commit/69e10de718dcba4d43e82bd37aeacd2585dd9a79))
* **list-header:** redesign list header to match latest iOS spec ([#19915](https://github.com/ionic-team/ionic/issues/19915)) ([5bbb95f](https://github.com/ionic-team/ionic/commit/5bbb95fae1e371021d6a0edc17fbb021a598b285))
* **split-pane:** convert split-pane to shadow ([#19754](https://github.com/ionic-team/ionic/issues/19754)) ([d80f455](https://github.com/ionic-team/ionic/commit/d80f45516d5dca62b77db1773206ef274d42f3ef))
## [4.11.5](https://github.com/ionic-team/ionic/compare/v4.11.0...v4.11.5) (2019-11-14)
### Bug Fixes
* **react:** improved lifecycle hooks to deal with stale closures, fixes [#19873](https://github.com/ionic-team/ionic/issues/19873) ([#19874](https://github.com/ionic-team/ionic/issues/19874)) ([5ff786a](https://github.com/ionic-team/ionic/commit/5ff786a23d5aa32281bbf5daaa7f8156de39caca))
## [4.11.4](https://github.com/ionic-team/ionic/compare/v4.11.1...v4.11.4) (2019-11-07)
@@ -545,7 +72,7 @@ npm i @types/react@latest @types/react-dom@latest
### Breaking Changes
> We recommend updating to the latest version of 4.x before trying out version 5 in order to see deprecation warnings related to your app [in the developer console](https://javascript.info/devtools).
> We recommend updating to the latest version of 4.x before trying out version 5 in order to see deprecation warnings related to your app in the console.
* **all:** mode is now cascaded from parent to child component. If this is not desired set a different mode on the child component. ([#19369](https://github.com/ionic-team/ionic/issues/19369)) ([55462d7](https://github.com/ionic-team/ionic/commit/55462d7a0935f57b6855f9bd1bf788bfcf532bc3))
* **anchor:** remove `ion-anchor`, use `ion-router-link` instead. ([#18935](https://github.com/ionic-team/ionic/issues/18935)) ([e7cd197](https://github.com/ionic-team/ionic/commit/e7cd197af79cdf87f04bc769e0367c7e93c0aa0b))

View File

@@ -507,7 +507,7 @@ _In the following examples, `{breakpoint}` refers to the optional screen breakpo
- `push-{breakpoint}-{value}` attributes have been renamed to `push-{breakpoint}=“{value}”`
- `pull-{breakpoint}-{value}` attributes have been renamed to `pull-{breakpoint}=“{value}”`
Customizing the padding and width of a grid should now be done with CSS variables. For more information, see [Grid Layout](https://github.com/ionic-team/ionic-docs/blob/master/src/pages/layout/grid.md).
Customizing the padding and width of a grid should now be done with CSS variables. For more information, see [Grid Layout](https://github.com/ionic-team/ionic-docs/blob/master/src/content/layout/grid.md).
## Icon

View File

@@ -23,7 +23,7 @@ Ionic Angular specific building blocks on top of [@ionic/core](https://www.npmjs
1. Pull the latest from master
2. Build ionic/angular: `npm run build`
3. Run `npm link` from `ionic/angular/dist` directory
3. Run `npm link` from ionic/angular directory
4. Create a blank angular project
```

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/angular",
"version": "5.0.6",
"version": "5.0.0-beta.0",
"description": "Angular specific wrappers for @ionic/core",
"keywords": [
"ionic",
@@ -24,11 +24,11 @@
},
"homepage": "https://ionicframework.com/",
"scripts": {
"build": "npm run clean && npm run build.ng && npm run build.core && npm run clean-generated",
"build": "npm run clean && npm run build.core && npm run build.ng && npm run clean-generated",
"build.core": "node scripts/build-core.js",
"build.fesm": "rollup --config ./scripts/rollup.config.js",
"build.link": "npm run build && node scripts/link-copy.js",
"build.ng": "ng-packagr -p package.json",
"build.ng": "npm run build.es2015 && npm run build.es5",
"build.es2015": "ngc -p tsconfig.json && rollup --config ./scripts/rollup.config.js",
"build.es5": "ngc -p tsconfig.legacy.json && rollup --config ./scripts/rollup.config.legacy.js",
"clean": "node scripts/clean.js",
@@ -41,46 +41,53 @@
"tsc": "tsc -p .",
"validate": "npm i && npm run lint && npm run test && npm run build"
},
"module": "dist/fesm5.js",
"main": "dist/fesm5.cjs.js",
"types": "dist/core.d.ts",
"files": [
"dist/",
"css/"
],
"dependencies": {
"@ionic/core": "5.0.6",
"@ionic/core": "5.0.0-beta.0",
"tslib": "^1.9.3"
},
"peerDependencies": {
"@angular/core": ">=8.2.7",
"@angular/forms": ">=8.2.7",
"@angular/router": ">=8.2.7",
"@angular-devkit/core": "7.2.1 - 8",
"@angular-devkit/schematics": "7.2.1 - 8",
"@angular/core": "7.2.1 - 8",
"@angular/common": "7.2.1 - 8",
"@angular/forms": "7.2.1 - 8",
"@angular/router": "7.2.1 - 8",
"@angular/compiler": "7.2.1 - 8",
"@angular/compiler-cli": "7.2.1 - 8",
"@angular/platform-browser": "7.2.1 - 8",
"@angular/platform-browser-dynamic": "7.2.1 - 8",
"rxjs": ">=6.2.0",
"zone.js": ">=0.8.26"
},
"devDependencies": {
"@angular-devkit/core": "8.3.17",
"@angular-devkit/schematics": "8.3.17",
"@angular/common": "8.2.13",
"@angular/compiler": "8.2.13",
"@angular/compiler-cli": "8.2.13",
"@angular/core": "8.2.13",
"@angular/forms": "8.2.13",
"@angular/router": "8.2.13",
"@types/node": "12.12.5",
"@angular-devkit/core": "^7.2.1",
"@angular-devkit/schematics": "^7.2.1",
"@angular/common": "^7.2.1",
"@angular/compiler": "^7.2.1",
"@angular/compiler-cli": "^7.2.1",
"@angular/core": "^7.2.1",
"@angular/forms": "^7.2.1",
"@angular/platform-browser": "^7.2.1",
"@angular/platform-browser-dynamic": "^7.2.1",
"@angular/router": "^7.2.1",
"@types/node": "~12.0.12",
"fs-extra": "^7.0.0",
"glob": "^7.1.4",
"ng-packagr": "5.7.1",
"rollup": "~1.17.0",
"rollup-plugin-node-resolve": "~5.2.0",
"rxjs": "^6.5.2",
"tsickle": "^0.34.0",
"tslint": "^5.12.1",
"tslint-ionic-rules": "0.0.21",
"typescript": "3.4.5",
"zone.js": "^0.8.28"
"typescript": "~3.2.2",
"zone.js": "~0.8.26"
},
"schematics": "./schematics/collection.json",
"ngPackage": {
"lib": {
"entryFile": "src/index.ts"
},
"whitelistedNonPeerDependencies": [
"@ionic/core"
]
}
"schematics": "./dist/schematics/collection.json"
}

View File

@@ -15,7 +15,7 @@ function copyIonicons() {
function copyCSS() {
const src = path.join(__dirname, '..', '..', 'core', 'css');
const dst = path.join(__dirname, '..','dist', 'css');
const dst = path.join(__dirname, '..', 'css');
fs.removeSync(dst);
fs.copySync(src, dst);

View File

@@ -16,7 +16,7 @@ export default {
},
plugins: [
resolve({
mainFields: ['module']
module: true,
})
]
};
};

View File

@@ -10,7 +10,7 @@ let didInitialize = false;
export const appInitialize = (config: Config, doc: Document, zone: NgZone) => {
return (): any => {
const win: IonicWindow | undefined = doc.defaultView as any;
if (win && typeof (window as any) !== 'undefined') {
if (win) {
if (didInitialize) {
console.warn('Ionic Angular was already initialized. Make sure IonicModule.forRoot() is just called once.');
}

View File

@@ -12,13 +12,6 @@ export class ValueAccessor implements ControlValueAccessor {
constructor(protected el: ElementRef) {}
writeValue(value: any) {
/**
* TODO for Ionic 6:
* Change `value == null ? '' : value;`
* to `value`. This was a fix for IE9, but IE9
* is no longer supported; however, this change
* is potentially a breaking change
*/
this.el.nativeElement.value = this.lastValue = value == null ? '' : value;
setIonicClasses(this.el);
}

View File

@@ -6,7 +6,7 @@ import { IonRouterOutlet } from './ion-router-outlet';
@Directive({
selector: 'ion-back-button',
inputs: ['defaultHref'],
inputs: ['defaultHref']
})
export class IonBackButtonDelegate {

View File

@@ -4,7 +4,6 @@ import { ActivatedRoute, ChildrenOutletContexts, OutletContext, PRIMARY_OUTLET,
import { BehaviorSubject, Observable } from 'rxjs';
import { distinctUntilChanged, filter, switchMap } from 'rxjs/operators';
import { AnimationBuilder } from '../../';
import { Config } from '../../providers/config';
import { NavController } from '../../providers/nav-controller';
@@ -14,11 +13,9 @@ import { RouteView, getUrl } from './stack-utils';
@Directive({
selector: 'ion-router-outlet',
exportAs: 'outlet',
inputs: ['animated', 'animation', 'swipeGesture']
inputs: ['animated', 'swipeGesture']
})
export class IonRouterOutlet implements OnDestroy, OnInit {
nativeEl: HTMLIonRouterOutletElement;
private activated: ComponentRef<any> | null = null;
private activatedView: RouteView | null = null;
@@ -26,6 +23,7 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
private _swipeGesture?: boolean;
private name: string;
private stackCtrl: StackController;
private nativeEl: HTMLIonRouterOutletElement;
// Maintain map of activated route proxies for each component instance
private proxyMap = new WeakMap<any, ActivatedRoute>();
@@ -39,10 +37,6 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
@Output('activate') activateEvents = new EventEmitter<any>();
@Output('deactivate') deactivateEvents = new EventEmitter<any>();
set animation(animation: AnimationBuilder) {
this.nativeEl.animation = animation;
}
set animated(animated: boolean) {
this.nativeEl.animated = animated;
}
@@ -247,22 +241,6 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
return active ? active.url : undefined;
}
/**
* Returns the RouteView of the active page of each stack.
* @internal
*/
getLastRouteView(stackId?: string): RouteView | undefined {
return this.stackCtrl.getLastUrl(stackId);
}
/**
* Returns the root view in the tab stack.
* @internal
*/
getRootView(stackId?: string): RouteView | undefined {
return this.stackCtrl.getRootUrl(stackId);
}
/**
* Returns the active stack ID. In the context of ion-tabs, it means the active tab.
*/
@@ -336,7 +314,7 @@ class OutletInjector implements Injector {
private route: ActivatedRoute,
private childContexts: ChildrenOutletContexts,
private parent: Injector
) { }
) {}
get(token: any, notFoundValue?: any): any {
if (token === ActivatedRoute) {

View File

@@ -42,15 +42,15 @@ import { StackEvent } from './stack-utils';
})
export class IonTabs {
@ViewChild('outlet', { read: IonRouterOutlet, static: false }) outlet: IonRouterOutlet;
@ContentChild(IonTabBar, { static: false }) tabBar: IonTabBar | undefined;
@ViewChild('outlet', { read: IonRouterOutlet }) outlet: IonRouterOutlet;
@ContentChild(IonTabBar) tabBar: IonTabBar | undefined;
@Output() ionTabsWillChange = new EventEmitter<{ tab: string }>();
@Output() ionTabsDidChange = new EventEmitter<{ tab: string }>();
@Output() ionTabsWillChange = new EventEmitter<{tab: string}>();
@Output() ionTabsDidChange = new EventEmitter<{tab: string}>();
constructor(
private navCtrl: NavController,
) { }
) {}
/**
* @internal
@@ -66,53 +66,18 @@ export class IonTabs {
}
}
/**
* When a tab button is clicked, there are several scenarios:
* 1. If the selected tab is currently active (the tab button has been clicked
* again), then it should go to the root view for that tab.
*
* a. Get the saved root view from the router outlet. If the saved root view
* matches the tabRootUrl, set the route view to this view including the
* navigation extras.
* b. If the saved root view from the router outlet does
* not match, navigate to the tabRootUrl. No navigation extras are
* included.
*
* 2. If the current tab tab is not currently selected, get the last route
* view from the router outlet.
*
* a. If the last route view exists, navigate to that view including any
* navigation extras
* b. If the last route view doesn't exist, then navigate
* to the default tabRootUrl
*/
@HostListener('ionTabButtonClick', ['$event.detail.tab'])
select(tab: string) {
const alreadySelected = this.outlet.getActiveStackId() === tab;
const tabRootUrl = `${this.outlet.tabsPrefix}/${tab}`;
if (alreadySelected) {
const rootView = this.outlet.getRootView(tab);
const navigationExtras = rootView && tabRootUrl === rootView.url && rootView.savedExtras;
return this.navCtrl.navigateRoot(tabRootUrl, {
...(navigationExtras),
animated: true,
animationDirection: 'back',
});
} else {
const lastRoute = this.outlet.getLastRouteView(tab);
/**
* If there is a lastRoute, goto that, otherwise goto the fallback url of the
* selected tab
*/
const url = lastRoute && lastRoute.url || tabRootUrl;
const navigationExtras = lastRoute && lastRoute.savedExtras;
const href = `${this.outlet.tabsPrefix}/${tab}`;
const url = alreadySelected
? href
: this.outlet.getLastUrl(tab) || href;
return this.navCtrl.navigateRoot(url, {
...(navigationExtras),
animated: true,
animationDirection: 'back',
});
}
return this.navCtrl.navigateRoot(url, {
animated: true,
animationDirection: 'back'
});
}
getSelected(): string | undefined {

View File

@@ -1,17 +1,11 @@
import { ComponentFactoryResolver, Directive, ElementRef, Injector, ViewContainerRef } from '@angular/core';
import { AngularDelegate } from '../../providers/angular-delegate';
import { ProxyCmp, proxyOutputs } from '../proxies-utils';
@ProxyCmp({
inputs: ['animated', 'animation', 'root', 'rootParams', 'swipeGesture'],
methods: ['push', 'insert', 'insertPages', 'pop', 'popTo', 'popToRoot', 'removeIndex', 'setRoot', 'setPages', 'getActive', 'getByIndex', 'canGoBack', 'getPrevious']
})
@Directive({
selector: 'ion-nav'
selector: 'ion-nav',
})
export class NavDelegate {
protected el: HTMLElement;
constructor(
ref: ElementRef,
resolver: ComponentFactoryResolver,
@@ -19,8 +13,6 @@ export class NavDelegate {
angularDelegate: AngularDelegate,
location: ViewContainerRef
) {
this.el = ref.nativeElement;
ref.nativeElement.delegate = angularDelegate.create(resolver, injector, location);
proxyOutputs(this, this.el, ['ionNavDidChange' , 'ionNavWillChange' ]);
}
}

View File

@@ -70,7 +70,7 @@ export class StackController {
if (router.getCurrentNavigation) {
currentNavigation = router.getCurrentNavigation();
// Angular < 7.2.0
// Angular < 7.2.0
} else if (
router.navigations &&
router.navigations.value
@@ -191,14 +191,6 @@ export class StackController {
return views.length > 0 ? views[views.length - 1] : undefined;
}
/**
* @internal
*/
getRootUrl(stackId?: string) {
const views = this.getStack(stackId);
return views.length > 0 ? views[0] : undefined;
}
getActiveStackId(): string | undefined {
return this.activeView ? this.activeView.stackId : undefined;
}

View File

@@ -2,7 +2,7 @@
import * as d from './proxies';
export const DIRECTIVES = [
d.IonApp,
d.IonApp,
d.IonAvatar,
d.IonBackButton,
d.IonBackdrop,

View File

@@ -1,46 +1,28 @@
/* eslint-disable */
/* tslint:disable */
import { fromEvent } from 'rxjs';
export const proxyInputs = (Cmp: any, inputs: string[]) => {
const Prototype = Cmp.prototype;
inputs.forEach(item => {
Object.defineProperty(Prototype, item, {
get() {
return this.el[item];
},
set(val: any) {
this.z.runOutsideAngular(() => (this.el[item] = val));
}
});
Object.defineProperty(Prototype, item, {
get() { return this.el[item]; },
set(val: any) {
this.z.runOutsideAngular(() => this.el[item] = val);
},
});
});
};
export const proxyMethods = (Cmp: any, methods: string[]) => {
const Prototype = Cmp.prototype;
methods.forEach(methodName => {
Prototype[methodName] = function () {
const args = arguments;
return this.z.runOutsideAngular(() =>
this.el[methodName].apply(this.el, args)
);
};
Prototype[methodName] = function() {
const args = arguments;
return this.z.runOutsideAngular(() => this.el[methodName].apply(this.el, args));
};
});
};
export const proxyOutputs = (instance: any, el: any, events: string[]) => {
events.forEach(eventName => instance[eventName] = fromEvent(el, eventName));
}
export function ProxyCmp(opts: { inputs?: any; methods?: any }) {
const decorator = function(cls: any){
if (opts.inputs) {
proxyInputs(cls, opts.inputs);
}
if (opts.methods) {
proxyMethods(cls, opts.methods);
}
return cls;
};
return decorator;
}
};

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, Component, ContentChild, ElementRef, EmbeddedViewRef, IterableDiffer, IterableDiffers, NgZone, SimpleChanges, TrackByFunction } from '@angular/core';
import { Cell, CellType, FooterHeightFn, HeaderFn, HeaderHeightFn, ItemHeightFn } from '@ionic/core';
import { ProxyCmp } from '../proxies-utils';
import { proxyInputs, proxyMethods } from '../proxies-utils';
import { VirtualFooter } from './virtual-footer';
import { VirtualHeader } from './virtual-header';
@@ -112,10 +112,6 @@ export declare interface IonVirtualScroll {
'positionForItem': (index: number) => Promise<number>;
}
@ProxyCmp({
inputs: ['approxItemHeight', 'approxHeaderHeight', 'approxFooterHeight', 'headerFn', 'footerFn', 'items', 'itemHeight', 'headerHeight', 'footerHeight'],
methods: ['checkEnd', 'checkRange', 'positionForItem']
})
@Component({
selector: 'ion-virtual-scroll',
template: '<ng-content></ng-content>',
@@ -137,11 +133,11 @@ export class IonVirtualScroll {
private differ?: IterableDiffer<any>;
private el: HTMLIonVirtualScrollElement;
private refMap = new WeakMap<HTMLElement, EmbeddedViewRef<VirtualContext>>();
private refMap = new WeakMap<HTMLElement, EmbeddedViewRef<VirtualContext>> ();
@ContentChild(VirtualItem, { static: false }) itmTmp!: VirtualItem;
@ContentChild(VirtualHeader, { static: false }) hdrTmp!: VirtualHeader;
@ContentChild(VirtualFooter, { static: false }) ftrTmp!: VirtualFooter;
@ContentChild(VirtualItem) itmTmp!: VirtualItem;
@ContentChild(VirtualHeader) hdrTmp!: VirtualHeader;
@ContentChild(VirtualFooter) ftrTmp!: VirtualFooter;
constructor(
private z: NgZone,
@@ -219,3 +215,21 @@ const getElement = (view: EmbeddedViewRef<VirtualContext>): HTMLElement => {
}
throw new Error('virtual element was not created');
};
proxyInputs(IonVirtualScroll, [
'approxItemHeight',
'approxHeaderHeight',
'approxFooterHeight',
'headerFn',
'footerFn',
'items',
'itemHeight',
'headerHeight',
'footerHeight'
]);
proxyMethods(IonVirtualScroll, [
'checkEnd',
'checkRange',
'positionForItem'
]);

View File

@@ -38,6 +38,3 @@ export { IonicRouteStrategy } from './util/ionic-router-reuse-strategy';
// PACKAGE MODULE
export { IonicModule } from './ionic-module';
// CORE TYPES
export { Animation, AnimationBuilder, AnimationCallbackOptions, AnimationDirection, AnimationFill, AnimationKeyFrames, AnimationLifecycle, Gesture, GestureConfig, GestureDetail, mdTransitionAnimation, iosTransitionAnimation } from '@ionic/core';

View File

@@ -126,7 +126,7 @@ const DECLARATIONS = [
imports: [CommonModule]
})
export class IonicModule {
static forRoot(config?: IonicConfig): ModuleWithProviders<IonicModule> {
static forRoot(config?: IonicConfig): ModuleWithProviders {
return {
ngModule: IonicModule,
providers: [

View File

@@ -33,7 +33,7 @@ export class Config {
}
set(key: keyof IonicConfig, value?: any) {
console.warn(`[DEPRECATION][Config]: The Config.set() method is deprecated and will be removed in Ionic Framework 6.0. Please see https://ionicframework.com/docs/angular/config for alternatives.`);
console.warn(`[DEPRECATION][Config]: The Config.set() method is deprecated and will be removed in the next major release.`);
const c = getConfig();
if (c) {
c.set(key, value);

View File

@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { Gesture, GestureConfig, createGesture } from '@ionic/core';
import { Gesture, GestureConfig, PressRecognizerOptions, createGesture, createPressRecognizer } from '@ionic/core';
@Injectable({
providedIn: 'root',
@@ -11,4 +11,11 @@ export class GestureController {
create(opts: GestureConfig): Gesture {
return createGesture(opts);
}
/**
* Create a new Press recognizer gesture
*/
pressRecognizer(opts: PressRecognizerOptions): Gesture {
return createPressRecognizer(opts);
}
}

View File

@@ -2,7 +2,7 @@ import { join, Path } from '@angular-devkit/core';
import { apply, chain, mergeWith, move, Rule, SchematicContext, SchematicsException, template, Tree, url } from '@angular-devkit/schematics';
import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
import { addModuleImportToRootModule } from './../utils/ast';
import { addArchitectBuilder, addStyle, getWorkspace, addAsset, WorkspaceProject, WorkspaceSchema } from './../utils/config';
import { addArchitectBuilder, addStyle, getWorkspace, addAsset } from './../utils/config';
import { addPackageToPackageJson } from './../utils/package';
import { Schema as IonAddOptions } from './schema';
@@ -25,7 +25,7 @@ function addIonicAngularToolkitToPackageJson(): Rule {
};
}
function addIonicAngularModuleToAppModule(projectSourceRoot: Path): Rule {
function addIonicAngularModuleToAppModule(projectSourceRoot): Rule {
return (host: Tree) => {
addModuleImportToRootModule(
host,
@@ -37,7 +37,7 @@ function addIonicAngularModuleToAppModule(projectSourceRoot: Path): Rule {
};
}
function addIonicStyles(projectSourceRoot: Path): Rule {
function addIonicStyles(): Rule {
return (host: Tree) => {
const ionicStyles = [
'node_modules/@ionic/angular/css/normalize.css',
@@ -49,7 +49,7 @@ function addIonicStyles(projectSourceRoot: Path): Rule {
'node_modules/@ionic/angular/css/text-alignment.css',
'node_modules/@ionic/angular/css/text-transformation.css',
'node_modules/@ionic/angular/css/flex-utils.css',
`${projectSourceRoot}/theme/variables.css`
'src/theme/variables.css'
].forEach(entry => {
addStyle(host, entry);
});
@@ -69,29 +69,29 @@ function addIonicons(): Rule {
};
}
function addIonicBuilder(projectName: string): Rule {
function addIonicBuilder(): Rule {
return (host: Tree) => {
addArchitectBuilder(host, 'ionic-cordova-serve', {
builder: '@ionic/angular-toolkit:cordova-serve',
options: {
cordovaBuildTarget: `${projectName}:ionic-cordova-build`,
devServerTarget: `${projectName}:serve`
cordovaBuildTarget: 'app:ionic-cordova-build',
devServerTarget: 'app:serve'
},
configurations: {
production: {
cordovaBuildTarget: `${projectName}:ionic-cordova-build:production`,
devServerTarget: `${projectName}:serve:production`
cordovaBuildTarget: 'app:ionic-cordova-build:production',
devServerTarget: 'app:serve:production'
}
}
});
addArchitectBuilder(host, 'ionic-cordova-build', {
builder: '@ionic/angular-toolkit:cordova-build',
options: {
browserTarget: `${projectName}:build`
browserTarget: 'app:build'
},
configurations: {
production: {
browserTarget: `${projectName}:build:production`
browserTarget: 'app:build:production'
}
}
});
@@ -100,24 +100,25 @@ function addIonicBuilder(projectName: string): Rule {
}
function installNodeDeps() {
return (_host: Tree, context: SchematicContext) => {
return (host: Tree, context: SchematicContext) => {
context.addTask(new NodePackageInstallTask());
};
}
export default function ngAdd(options: IonAddOptions): Rule {
return (host: Tree) => {
const workspace: WorkspaceSchema = getWorkspace(host);
const workspace = getWorkspace(host);
if (!options.project) {
options.project = Object.keys(workspace.projects)[0];
}
const project: WorkspaceProject = workspace.projects[options.project];
const project = workspace.projects[options.project];
if (project.projectType !== 'application') {
throw new SchematicsException(
`Ionic Add requires a project type of "application".`
);
}
const sourcePath: Path = join(project.sourceRoot as Path);
const sourcePath = join(project.root as Path, 'src');
const rootTemplateSource = apply(url('./files/root'), [
template({ ...options }),
move(sourcePath)
@@ -127,8 +128,8 @@ export default function ngAdd(options: IonAddOptions): Rule {
addIonicAngularToPackageJson(),
addIonicAngularToolkitToPackageJson(),
addIonicAngularModuleToAppModule(sourcePath),
addIonicBuilder(options.project),
addIonicStyles(sourcePath),
addIonicBuilder(),
addIonicStyles(),
addIonicons(),
mergeWith(rootTemplateSource),
// install freshly added dependencies

View File

@@ -89,7 +89,6 @@ export function addArchitectBuilder(host: Tree, builderName: string, builderOpts
}
export type WorkspaceSchema = experimental.workspace.WorkspaceSchema;
export type WorkspaceProject = experimental.workspace.WorkspaceProject;
export function getWorkspacePath(host: Tree): string {
const possibleFiles = ['/angular.json', '/.angular.json'];

View File

@@ -13,13 +13,11 @@
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"aot": true,
"outputPath": "dist/test-app/browser",
"outputPath": "dist/browser",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"buildOptimizer": true,
"assets": [
"src/favicon.ico",
{
@@ -59,10 +57,6 @@
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb"
}
]
}
@@ -122,44 +116,20 @@
"server": {
"builder": "@angular-devkit/build-angular:server",
"options": {
"outputPath": "dist/test-app/server",
"main": "server.ts",
"outputPath": "dist/server",
"main": "src/main.server.ts",
"tsConfig": "tsconfig.server.json"
},
"configurations": {
"production": {
"outputHashing": "media",
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
"src": "src/environments/environment.ts",
"replaceWith": "src/environments/environment.prod.ts"
}
],
"sourceMap": false,
"optimization": true
]
}
}
},
"serve-ssr": {
"builder": "@nguniversal/builders:ssr-dev-server",
"options": {
"browserTarget": "test-app:build",
"serverTarget": "test-app:server"
},
"configurations": {
"production": {
"browserTarget": "test-app:build:production",
"serverTarget": "test-app:server:production"
}
}
},
"prerender": {
"builder": "@nguniversal/builders:prerender",
"options": {
"browserTarget": "test-app:build:production",
"serverTarget": "test-app:server:production",
"routes": []
}
}
}
}

View File

@@ -23,7 +23,7 @@ exports.config = {
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 100000,
defaultTimeoutInterval: 70000,
print: function() {}
},
onPrepare() {

View File

@@ -1,5 +1,5 @@
import { browser, by, element, ElementFinder, ExpectedConditions } from 'protractor';
import { handleErrorMessages, testStack, waitTime } from './utils';
import { browser, element, by, ElementFinder } from 'protractor';
import { waitTime, testStack, handleErrorMessages } from './utils';
describe('tabs', () => {
afterEach(() => {
@@ -131,94 +131,6 @@ describe('tabs', () => {
await testTabTitle('Tab 3 - Page 1');
await testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1', 'app-tabs-tab3']);
});
it('should preserve navigation extras when switching tabs', async () => {
const expectUrlToContain = 'search=hello#fragment';
let tab = await getSelectedTab() as ElementFinder;
await tab.$('#goto-nested-page1-with-query-params').click();
await testTabTitle('Tab 1 - Page 2 (1)');
await testUrlContains(expectUrlToContain);
await element(by.css('#tab-button-contact')).click();
await testTabTitle('Tab 2 - Page 1');
await element(by.css('#tab-button-account')).click();
tab = await testTabTitle('Tab 1 - Page 2 (1)');
await testUrlContains(expectUrlToContain);
});
it('should set root when clicking on an active tab to navigate to the root', async () => {
const expectNestedTabUrlToContain = 'search=hello#fragment';
let tab = await getSelectedTab() as ElementFinder;
const initialUrl = await browser.getCurrentUrl();
await tab.$('#goto-nested-page1-with-query-params').click();
await testTabTitle('Tab 1 - Page 2 (1)');
await testUrlContains(expectNestedTabUrlToContain);
await element(by.css('#tab-button-account')).click();
await testTabTitle('Tab 1 - Page 1');
await testUrlEquals(initialUrl);
});
});
describe('entry tab contains navigation extras', () => {
const expectNestedTabUrlToContain = 'search=hello#fragment';
const rootUrlParams = 'test=123#rootFragment';
const rootUrl = `/tabs/account?${rootUrlParams}`;
beforeEach(async () => {
await browser.get(rootUrl);
await waitTime(30);
});
it('should preserve root url navigation extras when clicking on an active tab to navigate to the root', async () => {
await browser.get(rootUrl);
let tab = await getSelectedTab() as ElementFinder;
await tab.$('#goto-nested-page1-with-query-params').click();
await testTabTitle('Tab 1 - Page 2 (1)');
await testUrlContains(expectNestedTabUrlToContain);
await element(by.css('#tab-button-account')).click();
await testTabTitle('Tab 1 - Page 1');
await testUrlContains(rootUrl);
});
it('should preserve root url navigation extras when changing tabs', async () => {
await browser.get(rootUrl);
let tab = await getSelectedTab() as ElementFinder;
await element(by.css('#tab-button-contact')).click();
tab = await testTabTitle('Tab 2 - Page 1');
await element(by.css('#tab-button-account')).click();
await testTabTitle('Tab 1 - Page 1');
await testUrlContains(rootUrl);
});
it('should navigate deep then go home and preserve navigation extras', async () => {
let tab = await getSelectedTab();
await tab.$('#goto-tab1-page2').click();
tab = await testTabTitle('Tab 1 - Page 2 (1)');
await tab.$('#goto-next').click();
tab = await testTabTitle('Tab 1 - Page 2 (2)');
await element(by.css('#tab-button-contact')).click();
tab = await testTabTitle('Tab 2 - Page 1');
await element(by.css('#tab-button-account')).click();
await testTabTitle('Tab 1 - Page 2 (2)');
await element(by.css('#tab-button-account')).click();
await testTabTitle('Tab 1 - Page 1');
await testUrlContains(rootUrl);
});
});
describe('entry url - /tabs/account/nested/1', () => {
@@ -247,7 +159,7 @@ describe('tabs', () => {
await tab.$('#goto-next').click();
tab = await testTabTitle('Tab 1 - Page 2 (3)');
await testStack('ion-tabs ion-router-outlet', [
await testStack('ion-tabs ion-router-outlet',[
'app-tabs-tab1-nested',
'app-tabs-tab1-nested',
'app-tabs-tab1-nested'
@@ -314,18 +226,6 @@ async function testTabTitle(title: string) {
return tab;
}
async function testUrlContains(urlFragment: string) {
await browser.wait(ExpectedConditions.urlContains(urlFragment),
5000,
`expected ${browser.getCurrentUrl()} to contain ${urlFragment}`);
}
async function testUrlEquals(url: string) {
await browser.wait(ExpectedConditions.urlIs(url),
5000,
`expected ${browser.getCurrentUrl()} to equal ${url}`);
}
async function getSelectedTab(): Promise<ElementFinder> {
const tabs = element.all(by.css('ion-tabs ion-router-outlet > *:not(.ion-page-hidden)'));
expect(await tabs.count()).toEqual(1);

View File

@@ -8,8 +8,6 @@ module.exports = function (config) {
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
@@ -26,7 +24,6 @@ module.exports = function (config) {
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
singleRun: false
});
};
};

View File

@@ -11,53 +11,50 @@
"test": "ng e2e --prod",
"test.dev": "npm run sync && ng e2e",
"lint": "ng lint",
"postinstall": "npm run sync && ngcc",
"serve:ssr": "node dist/test-app/server/main.js",
"build:ssr": "ng build --prod && ng run test-app:server:production",
"dev:ssr": "ng run test-app:serve-ssr",
"prerender": "ng run test-app:prerender"
"postinstall": "npm run sync",
"compile:server": "webpack --config webpack.server.config.js --progress --colors",
"serve:ssr": "node dist/server",
"build:ssr": "npm run build:client-and-server-bundles && npm run compile:server",
"build:client-and-server-bundles": "npm run build && ng run test-app:server:production --bundleDependencies all"
},
"dependencies": {
"@angular/animations": "^9.0.0-rc.2",
"@angular/common": "^9.0.0-rc.2",
"@angular/compiler": "^9.0.0-rc.2",
"@angular/core": "^9.0.0-rc.2",
"@angular/forms": "^9.0.0-rc.2",
"@angular/platform-browser": "^9.0.0-rc.2",
"@angular/platform-browser-dynamic": "^9.0.0-rc.2",
"@angular/platform-server": "^9.0.0-rc.2",
"@angular/router": "^9.0.0-rc.2",
"@angular/animations": "^8.2.8",
"@angular/common": "^8.2.8",
"@angular/compiler": "^8.2.8",
"@angular/core": "^8.2.8",
"@angular/forms": "^8.2.8",
"@angular/platform-browser": "^8.2.8",
"@angular/platform-browser-dynamic": "^8.2.8",
"@angular/platform-server": "^8.2.8",
"@angular/router": "^8.2.8",
"@ionic/angular": "^4.7.0",
"@ionic/angular-server": "^0.0.2",
"@nguniversal/express-engine": "9.0.0-next.9",
"@nguniversal/express-engine": "~8.1.1",
"@nguniversal/module-map-ngfactory-loader": "~8.1.1",
"core-js": "^2.6.2",
"express": "^4.15.2",
"rxjs": "^6.5.3",
"tslib": "^1.10.0",
"zone.js": "~0.10.2"
"tslib": "^1.9.0",
"zone.js": "~0.9.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.900.0-rc.2",
"@angular/cli": "^9.0.0-rc.2",
"@angular/compiler-cli": "^9.0.0-rc.2",
"@angular/language-service": "^9.0.0-rc.2",
"@nguniversal/builders": "9.0.0-next.9",
"@types/express": "^4.17.0",
"@angular-devkit/build-angular": "^0.803.6",
"@angular/cli": "^8.3.6",
"@angular/compiler-cli": "^8.2.8",
"@angular/language-service": "^8.2.8",
"@types/jasmine": "3.4.1",
"@types/node": "^12.11.1",
"@types/node": "12.7.8",
"codelyzer": "^5.1.2",
"jasmine-core": "~3.5.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~4.3.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~2.1.0",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.2",
"protractor": "~5.4.2",
"jasmine-core": "3.5.0",
"jasmine-spec-reporter": "4.2.1",
"karma": "4.3.0",
"karma-chrome-launcher": "3.1.0",
"karma-jasmine": "2.0.1",
"protractor": "5.4.2",
"ts-loader": "^6.1.2",
"ts-node": "8.4.1",
"tslint": "~5.18.0",
"typescript": "~3.6.4",
"typescript": "~3.5.3",
"webpack-cli": "^3.3.9"
}
}

View File

@@ -1,10 +1,15 @@
# Copy angular dist
rm -rf node_modules/@ionic/angular
cp -a ../../dist node_modules/@ionic/angular
mkdir node_modules/@ionic/angular
cp -a ../../dist node_modules/@ionic/angular/dist
cp -a ../../css node_modules/@ionic/angular/css
cp -a ../../package.json node_modules/@ionic/angular/package.json
# Copy angular server
rm -rf node_modules/@ionic/angular-server
cp -a ../../../packages/angular-server/dist node_modules/@ionic/angular-server
mkdir node_modules/@ionic/angular-server
cp -a ../../../packages/angular-server/dist node_modules/@ionic/angular-server/dist
cp -a ../../../packages/angular-server/package.json node_modules/@ionic/angular-server/package.json
# # Copy core dist
rm -rf node_modules/@ionic/core

View File

@@ -1,57 +1,58 @@
/**
* *** NOTE ON IMPORTING FROM ANGULAR AND NGUNIVERSAL IN THIS FILE ***
*
* If your application uses third-party dependencies, you'll need to
* either use Webpack or the Angular CLI's `bundleDependencies` feature
* in order to adequately package them for use on the server without a
* node_modules directory.
*
* However, due to the nature of the CLI's `bundleDependencies`, importing
* Angular in this file will create a different instance of Angular than
* the version in the compiled application code. This leads to unavoidable
* conflicts. Therefore, please do not explicitly import from @angular or
* @nguniversal in this file. You can export any needed resources
* from your application's main.server.ts file, as seen below with the
* import for `ngExpressEngine`.
*/
import 'zone.js/dist/zone-node';
import { ngExpressEngine } from '@nguniversal/express-engine';
import * as express from 'express';
import { join } from 'path';
import {join} from 'path';
import { AppServerModule } from './src/main.server';
import { APP_BASE_HREF } from '@angular/common';
// Express server
const app = express();
// The Express app is exported so that it can be used by serverless Functions.
export function app() {
const server = express();
const distFolder = join(process.cwd(), 'dist/test-app/browser');
const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist/browser');
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
server.engine('html', ngExpressEngine({
bootstrap: AppServerModule,
}));
// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const {AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModuleMap} = require('./dist/server/main');
server.set('view engine', 'html');
server.set('views', distFolder);
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine('html', ngExpressEngine({
bootstrap: AppServerModuleNgFactory,
providers: [
provideModuleMap(LAZY_MODULE_MAP)
]
}));
// Example Express Rest API endpoints
// app.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.get('*.*', express.static(distFolder, {
maxAge: '1y'
}));
app.set('view engine', 'html');
app.set('views', DIST_FOLDER);
// All regular routes use the Universal engine
server.get('*', (req, res) => {
res.render('index', { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
});
// Example Express Rest API endpoints
// app.get('/api/**', (req, res) => { });
// Serve static files from /browser
app.get('*.*', express.static(DIST_FOLDER, {
maxAge: '1y'
}));
return server;
}
// All regular routes use the Universal engine
app.get('*', (req, res) => {
res.render('index', { req });
});
function run() {
const port = process.env.PORT || 4000;
// Start up the Node server
const server = app();
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
if (mainModule && mainModule.filename === __filename) {
run();
}
export * from './src/main.server';
// Start up the Node server
app.listen(PORT, () => {
console.log(`Node Express server listening on http://localhost:${PORT}`);
});

View File

@@ -1,13 +1,17 @@
import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { IonicServerModule } from '@ionic/angular-server';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';
@NgModule({
imports: [
AppModule,
ServerModule,
ModuleMapLoaderModule,
IonicServerModule
],
bootstrap: [AppComponent],

View File

@@ -15,8 +15,6 @@
</p>
<p>
<ion-button routerLink="/tabs/account/nested/1" id="goto-tab1-page2">Go to Page 2</ion-button>
<ion-button routerLink="/tabs/account/nested/1" [queryParams]="{search:'hello'}" fragment="fragment"
id="goto-nested-page1-with-query-params">Go to Page 2 with Query Params</ion-button>
<ion-button routerLink="/tabs/lazy/nested" id="goto-tab3-page2">Go to Tab 3 - Page 2</ion-button>
<ion-button routerLink="/nested-outlet/page" id="goto-nested-page1">Go to nested</ion-button>
</p>

View File

@@ -7,4 +7,5 @@ if (environment.production) {
}
export { AppServerModule } from './app/app.server.module';
export { renderModule, renderModuleFactory } from '@angular/platform-server';
export { ngExpressEngine } from '@nguniversal/express-engine';
export { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';

View File

@@ -10,6 +10,6 @@ if (environment.production) {
document.addEventListener('DOMContentLoaded', () => {
platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch(err => console.error(err));
.bootstrapModule(AppModule)
.catch(err => console.error(err));
});

View File

@@ -43,7 +43,7 @@
*
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
* (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
*
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch for IE/Edge
@@ -52,12 +52,9 @@
*
*/
import './zone-flags.ts';
/***************************************************************************************************
* Zone JS is required by default for Angular itself.
*/
import 'zone.js/dist/zone'; // Included with Angular CLI.

View File

@@ -1,5 +0,0 @@
/**
* Prevents Angular change detection from
* running with certain Web Component callbacks
*/
(window as any).__Zone_disable_customElements = true;

View File

@@ -3,10 +3,6 @@
"compilerOptions": {
"outDir": "./out-tsc/app"
},
"files": [
"src/main.ts",
"src/polyfills.ts",
"src/zone-flags.ts"
],
"include": ["src/**/*.d.ts"]
"include": ["src/**/*.ts"],
"exclude": ["src/test.ts", "src/**/*.spec.ts"]
}

View File

@@ -1,16 +1,8 @@
{
"extends": "./tsconfig.app.json",
"compilerOptions": {
"outDir": "./out-tsc/app-server",
"module": "commonjs",
"types": [
"node"
]
"outDir": "../out-tsc/app-server"
},
"files": [
"src/main.server.ts",
"server.ts"
],
"angularCompilerOptions": {
"entryModule": "./src/app/app.server.module#AppServerModule"
}

View File

@@ -0,0 +1,53 @@
// Work around for https://github.com/angular/angular-cli/issues/7200
const path = require('path');
const webpack = require('webpack');
module.exports = {
mode: 'none',
entry: {
// This is our Express server for Dynamic universal
server: './server.ts'
},
externals: {
'./dist/server/main': 'require("./server/main")'
},
target: 'node',
resolve: {
mainFields: ['module', 'main'],
extensions: ['.ts', '.js']
},
optimization: {
minimize: false
},
output: {
// Puts the output at the root of the dist folder
path: path.join(__dirname, 'dist'),
filename: '[name].js'
},
module: {
rules: [
{ test: /\.ts$/, loader: 'ts-loader' },
{
// Mark files inside `@angular/core` as using SystemJS style dynamic imports.
// Removing this will cause deprecation warnings to appear.
test: /(\\|\/)@angular(\\|\/)core(\\|\/).+\.js$/,
parser: { system: true },
},
]
},
plugins: [
new webpack.ContextReplacementPlugin(
// fixes WARNING Critical dependency: the request of a dependency is an expression
/(.+)?angular(\\|\/)core(.+)?/,
path.join(__dirname, 'src'), // location of your src
{} // a map of your routes
),
new webpack.ContextReplacementPlugin(
// fixes WARNING Critical dependency: the request of a dependency is an expression
/(.+)?express(\\|\/)(.+)?/,
path.join(__dirname, 'src'),
{}
)
]
};

View File

@@ -1,13 +1,11 @@
{
"angularCompilerOptions": {
"annotateForClosureCompiler": true,
"strictMetadataEmit": true,
"strictMetadataEmit" : true,
"flatModuleOutFile": "core.js",
"flatModuleId": "@ionic/angular",
"skipTemplateCodegen": true,
"fullTemplateTypeCheck": false,
"enableResourceInlining": true,
"enableIvy": false
"fullTemplateTypeCheck": false
},
"compilerOptions": {
"alwaysStrict": true,
@@ -34,8 +32,12 @@
"target": "es2015",
"baseUrl": ".",
"paths": {
"@ionic/core/hydrate": ["../core/hydrate"],
"@ionic/core": ["../core"]
"@ionic/core/hydrate": [
"../core/hydrate"
],
"@ionic/core": [
"../core"
]
}
},
"exclude": ["node_modules", "src/schematics"],

View File

@@ -51,7 +51,7 @@ npm start
You should be able to navigate to `http://localhost:3333` which will look like a file browser.
E2E tests are located inside the `src/components` folder, in the following way: `http://localhost:3333/src/components/{COMPONENT}/test/`
E2E tests are located inside the `src/component` folder, in the following way: `http://localhost:3333/src/components/{COMPONENT}/test/`
**Path examples:**

View File

@@ -23,9 +23,9 @@ The Ionic Core package contains the Web Components that make up the reusable UI
Easiest way to start using Ionic Core is by adding a script tag to the CDN:
```html
<script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.esm.js"></script>
<script nomodule src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.js"></script>
<link href="https://cdn.jsdelivr.net/npm/@ionic/core/css/ionic.bundle.css" rel="stylesheet">
<script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core@4.6.2/dist/ionic/ionic.esm.js"></script>
<script nomodule src="https://cdn.jsdelivr.net/npm/@ionic/core@4.6.2/dist/ionic/ionic.js"></script>
<link href="https://cdn.jsdelivr.net/npm/@ionic/core@4.6.2/css/ionic.bundle.css" rel="stylesheet">
```
Any Ionic component added to the webpage will automatically load. This includes writing the component tag directly in HTML, or using JavaScript such as `document.createElement('ion-toggle')`.

View File

@@ -21,20 +21,8 @@ ion-action-sheet,event,ionActionSheetWillDismiss,OverlayEventDetail<any>,true
ion-action-sheet,event,ionActionSheetWillPresent,void,true
ion-action-sheet,css-prop,--backdrop-opacity
ion-action-sheet,css-prop,--background
ion-action-sheet,css-prop,--button-background
ion-action-sheet,css-prop,--button-background-activated
ion-action-sheet,css-prop,--button-background-activated-opacity
ion-action-sheet,css-prop,--button-background-focused
ion-action-sheet,css-prop,--button-background-focused-opacity
ion-action-sheet,css-prop,--button-background-hover
ion-action-sheet,css-prop,--button-background-hover-opacity
ion-action-sheet,css-prop,--button-background-selected
ion-action-sheet,css-prop,--button-background-selected-opacity
ion-action-sheet,css-prop,--button-color
ion-action-sheet,css-prop,--button-color-activated
ion-action-sheet,css-prop,--button-color-focused
ion-action-sheet,css-prop,--button-color-hover
ion-action-sheet,css-prop,--button-color-selected
ion-action-sheet,css-prop,--background-activated
ion-action-sheet,css-prop,--background-selected
ion-action-sheet,css-prop,--color
ion-action-sheet,css-prop,--height
ion-action-sheet,css-prop,--max-height
@@ -43,6 +31,11 @@ ion-action-sheet,css-prop,--min-height
ion-action-sheet,css-prop,--min-width
ion-action-sheet,css-prop,--width
ion-action-sheet-controller,none
ion-action-sheet-controller,method,create,create(options: ActionSheetOptions) => Promise<HTMLIonActionSheetElement>
ion-action-sheet-controller,method,dismiss,dismiss(data?: any, role?: string | undefined, id?: string | undefined) => Promise<boolean>
ion-action-sheet-controller,method,getTop,getTop() => Promise<HTMLIonActionSheetElement | undefined>
ion-alert,scoped
ion-alert,prop,animated,boolean,true,false,false
ion-alert,prop,backdropDismiss,boolean,true,false,false
@@ -74,12 +67,17 @@ ion-alert,css-prop,--min-height
ion-alert,css-prop,--min-width
ion-alert,css-prop,--width
ion-alert-controller,none
ion-alert-controller,method,create,create(options: AlertOptions) => Promise<HTMLIonAlertElement>
ion-alert-controller,method,dismiss,dismiss(data?: any, role?: string | undefined, id?: string | undefined) => Promise<boolean>
ion-alert-controller,method,getTop,getTop() => Promise<HTMLIonAlertElement | undefined>
ion-app,none
ion-avatar,shadow
ion-avatar,css-prop,--border-radius
ion-back-button,shadow
ion-back-button,scoped
ion-back-button,prop,color,string | undefined,undefined,false,false
ion-back-button,prop,defaultHref,string | undefined,undefined,false,false
ion-back-button,prop,disabled,boolean,false,false,true
@@ -89,9 +87,7 @@ ion-back-button,prop,text,null | string | undefined,undefined,false,false
ion-back-button,prop,type,"button" | "reset" | "submit",'button',false,false
ion-back-button,css-prop,--background
ion-back-button,css-prop,--background-focused
ion-back-button,css-prop,--background-focused-opacity
ion-back-button,css-prop,--background-hover
ion-back-button,css-prop,--background-hover-opacity
ion-back-button,css-prop,--border-radius
ion-back-button,css-prop,--color
ion-back-button,css-prop,--color-focused
@@ -156,11 +152,8 @@ ion-button,event,ionBlur,void,true
ion-button,event,ionFocus,void,true
ion-button,css-prop,--background
ion-button,css-prop,--background-activated
ion-button,css-prop,--background-activated-opacity
ion-button,css-prop,--background-focused
ion-button,css-prop,--background-focused-opacity
ion-button,css-prop,--background-hover
ion-button,css-prop,--background-hover-opacity
ion-button,css-prop,--border-color
ion-button,css-prop,--border-radius
ion-button,css-prop,--border-style
@@ -232,7 +225,6 @@ ion-checkbox,css-prop,--border-radius
ion-checkbox,css-prop,--border-style
ion-checkbox,css-prop,--border-width
ion-checkbox,css-prop,--checkmark-color
ion-checkbox,css-prop,--checkmark-width
ion-checkbox,css-prop,--size
ion-checkbox,css-prop,--transition
@@ -308,7 +300,6 @@ ion-datetime,prop,dayShortNames,string | string[] | undefined,undefined,false,fa
ion-datetime,prop,dayValues,number | number[] | string | undefined,undefined,false,false
ion-datetime,prop,disabled,boolean,false,false,false
ion-datetime,prop,displayFormat,string,'MMM D, YYYY',false,false
ion-datetime,prop,displayTimezone,string | undefined,undefined,false,false
ion-datetime,prop,doneText,string,'Done',false,false
ion-datetime,prop,hourValues,number | number[] | string | undefined,undefined,false,false
ion-datetime,prop,max,string | undefined,undefined,false,false
@@ -320,7 +311,7 @@ ion-datetime,prop,monthShortNames,string | string[] | undefined,undefined,false,
ion-datetime,prop,monthValues,number | number[] | string | undefined,undefined,false,false
ion-datetime,prop,name,string,this.inputId,false,false
ion-datetime,prop,pickerFormat,string | undefined,undefined,false,false
ion-datetime,prop,pickerOptions,undefined | { columns?: PickerColumn[] | undefined; buttons?: PickerButton[] | undefined; cssClass?: string | string[] | undefined; showBackdrop?: boolean | undefined; backdropDismiss?: boolean | undefined; animated?: boolean | undefined; mode?: "ios" | "md" | undefined; keyboardClose?: boolean | undefined; id?: string | undefined; enterAnimation?: AnimationBuilder | undefined; leaveAnimation?: AnimationBuilder | undefined; },undefined,false,false
ion-datetime,prop,pickerOptions,undefined | { columns?: PickerColumn[] | undefined; buttons?: PickerButton[] | undefined; cssClass?: string | string[] | undefined; backdropDismiss?: boolean | undefined; animated?: boolean | undefined; mode?: "ios" | "md" | undefined; keyboardClose?: boolean | undefined; id?: string | undefined; enterAnimation?: AnimationBuilder | undefined; leaveAnimation?: AnimationBuilder | undefined; },undefined,false,false
ion-datetime,prop,placeholder,null | string | undefined,undefined,false,false
ion-datetime,prop,readonly,boolean,false,false,false
ion-datetime,prop,value,null | string | undefined,undefined,false,false
@@ -361,11 +352,8 @@ ion-fab-button,event,ionBlur,void,true
ion-fab-button,event,ionFocus,void,true
ion-fab-button,css-prop,--background
ion-fab-button,css-prop,--background-activated
ion-fab-button,css-prop,--background-activated-opacity
ion-fab-button,css-prop,--background-focused
ion-fab-button,css-prop,--background-focused-opacity
ion-fab-button,css-prop,--background-hover
ion-fab-button,css-prop,--background-hover-opacity
ion-fab-button,css-prop,--border-color
ion-fab-button,css-prop,--border-radius
ion-fab-button,css-prop,--border-style
@@ -455,7 +443,7 @@ ion-input,prop,size,number | undefined,undefined,false,false
ion-input,prop,spellcheck,boolean,false,false,false
ion-input,prop,step,string | undefined,undefined,false,false
ion-input,prop,type,"date" | "email" | "number" | "password" | "search" | "tel" | "text" | "time" | "url",'text',false,false
ion-input,prop,value,null | number | string | undefined,'',false,false
ion-input,prop,value,null | string | undefined,'',false,false
ion-input,method,getInputElement,getInputElement() => Promise<HTMLInputElement>
ion-input,method,setFocus,setFocus() => Promise<void>
ion-input,event,ionBlur,void,true
@@ -477,7 +465,7 @@ ion-item,shadow
ion-item,prop,button,boolean,false,false,false
ion-item,prop,color,string | undefined,undefined,false,false
ion-item,prop,detail,boolean | undefined,undefined,false,false
ion-item,prop,detailIcon,string,'chevron-forward',false,false
ion-item,prop,detailIcon,string,'ios-arrow-forward',false,false
ion-item,prop,disabled,boolean,false,false,false
ion-item,prop,download,string | undefined,undefined,false,false
ion-item,prop,href,string | undefined,undefined,false,false
@@ -489,15 +477,13 @@ ion-item,prop,target,string | undefined,undefined,false,false
ion-item,prop,type,"button" | "reset" | "submit",'button',false,false
ion-item,css-prop,--background
ion-item,css-prop,--background-activated
ion-item,css-prop,--background-activated-opacity
ion-item,css-prop,--background-focused
ion-item,css-prop,--background-focused-opacity
ion-item,css-prop,--background-hover
ion-item,css-prop,--background-hover-opacity
ion-item,css-prop,--border-color
ion-item,css-prop,--border-radius
ion-item,css-prop,--border-style
ion-item,css-prop,--border-width
ion-item,css-prop,--box-shadow
ion-item,css-prop,--color
ion-item,css-prop,--color-activated
ion-item,css-prop,--color-focused
@@ -580,14 +566,9 @@ ion-list,method,closeSlidingItems,closeSlidingItems() => Promise<boolean>
ion-list-header,shadow
ion-list-header,prop,color,string | undefined,undefined,false,false
ion-list-header,prop,lines,"full" | "inset" | "none" | undefined,undefined,false,false
ion-list-header,prop,mode,"ios" | "md",undefined,false,false
ion-list-header,css-prop,--background
ion-list-header,css-prop,--border-color
ion-list-header,css-prop,--border-style
ion-list-header,css-prop,--border-width
ion-list-header,css-prop,--color
ion-list-header,css-prop,--inner-border-width
ion-loading,scoped
ion-loading,prop,animated,boolean,true,false,false
@@ -620,11 +601,16 @@ ion-loading,css-prop,--min-width
ion-loading,css-prop,--spinner-color
ion-loading,css-prop,--width
ion-loading-controller,none
ion-loading-controller,method,create,create(options?: LoadingOptions | undefined) => Promise<HTMLIonLoadingElement>
ion-loading-controller,method,dismiss,dismiss(data?: any, role?: string | undefined, id?: string | undefined) => Promise<boolean>
ion-loading-controller,method,getTop,getTop() => Promise<HTMLIonLoadingElement | undefined>
ion-menu,shadow
ion-menu,prop,contentId,string | undefined,undefined,false,true
ion-menu,prop,contentId,string | undefined,undefined,false,false
ion-menu,prop,disabled,boolean,false,false,false
ion-menu,prop,maxEdgeStart,number,50,false,false
ion-menu,prop,menuId,string | undefined,undefined,false,true
ion-menu,prop,menuId,string | undefined,undefined,false,false
ion-menu,prop,side,"end" | "start",'start',false,true
ion-menu,prop,swipeGesture,boolean,true,false,false
ion-menu,prop,type,string | undefined,undefined,false,false
@@ -654,9 +640,7 @@ ion-menu-button,prop,menu,string | undefined,undefined,false,false
ion-menu-button,prop,type,"button" | "reset" | "submit",'button',false,false
ion-menu-button,css-prop,--background
ion-menu-button,css-prop,--background-focused
ion-menu-button,css-prop,--background-focused-opacity
ion-menu-button,css-prop,--background-hover
ion-menu-button,css-prop,--background-hover-opacity
ion-menu-button,css-prop,--border-radius
ion-menu-button,css-prop,--color
ion-menu-button,css-prop,--color-focused
@@ -666,6 +650,20 @@ ion-menu-button,css-prop,--padding-end
ion-menu-button,css-prop,--padding-start
ion-menu-button,css-prop,--padding-top
ion-menu-controller,none
ion-menu-controller,method,close,close(menu?: string | null | undefined) => Promise<boolean>
ion-menu-controller,method,enable,enable(enable: boolean, menu?: string | null | undefined) => Promise<HTMLIonMenuElement | undefined>
ion-menu-controller,method,get,get(menu?: string | null | undefined) => Promise<HTMLIonMenuElement | undefined>
ion-menu-controller,method,getMenus,getMenus() => Promise<HTMLIonMenuElement[]>
ion-menu-controller,method,getOpen,getOpen() => Promise<HTMLIonMenuElement | undefined>
ion-menu-controller,method,isAnimating,isAnimating() => Promise<boolean>
ion-menu-controller,method,isEnabled,isEnabled(menu?: string | null | undefined) => Promise<boolean>
ion-menu-controller,method,isOpen,isOpen(menu?: string | null | undefined) => Promise<boolean>
ion-menu-controller,method,open,open(menu?: string | null | undefined) => Promise<boolean>
ion-menu-controller,method,registerAnimation,registerAnimation(name: string, animation: AnimationBuilder) => Promise<void>
ion-menu-controller,method,swipeGesture,swipeGesture(enable: boolean, menu?: string | null | undefined) => Promise<HTMLIonMenuElement | undefined>
ion-menu-controller,method,toggle,toggle(menu?: string | null | undefined) => Promise<boolean>
ion-menu-toggle,shadow
ion-menu-toggle,prop,autoHide,boolean,true,false,false
ion-menu-toggle,prop,menu,string | undefined,undefined,false,false
@@ -680,9 +678,7 @@ ion-modal,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefin
ion-modal,prop,keyboardClose,boolean,true,false,false
ion-modal,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-modal,prop,mode,"ios" | "md",undefined,false,false
ion-modal,prop,presentingElement,HTMLElement | undefined,undefined,false,false
ion-modal,prop,showBackdrop,boolean,true,false,false
ion-modal,prop,swipeToClose,boolean,false,false,false
ion-modal,method,dismiss,dismiss(data?: any, role?: string | undefined) => Promise<boolean>
ion-modal,method,onDidDismiss,onDidDismiss() => Promise<OverlayEventDetail<any>>
ion-modal,method,onWillDismiss,onWillDismiss() => Promise<OverlayEventDetail<any>>
@@ -704,6 +700,11 @@ ion-modal,css-prop,--min-height
ion-modal,css-prop,--min-width
ion-modal,css-prop,--width
ion-modal-controller,none
ion-modal-controller,method,create,create<T extends ComponentRef>(options: ModalOptions<T>) => Promise<HTMLIonModalElement>
ion-modal-controller,method,dismiss,dismiss(data?: any, role?: string | undefined, id?: string | undefined) => Promise<boolean>
ion-modal-controller,method,getTop,getTop() => Promise<HTMLIonModalElement | undefined>
ion-nav,shadow
ion-nav,prop,animated,boolean,true,false,false
ion-nav,prop,animation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
@@ -771,6 +772,11 @@ ion-picker,css-prop,--min-height
ion-picker,css-prop,--min-width
ion-picker,css-prop,--width
ion-picker-controller,none
ion-picker-controller,method,create,create(options: PickerOptions) => Promise<HTMLIonPickerElement>
ion-picker-controller,method,dismiss,dismiss(data?: any, role?: string | undefined, id?: string | undefined) => Promise<boolean>
ion-picker-controller,method,getTop,getTop() => Promise<HTMLIonPickerElement | undefined>
ion-popover,scoped
ion-popover,prop,animated,boolean,true,false,false
ion-popover,prop,backdropDismiss,boolean,true,false,false
@@ -802,6 +808,11 @@ ion-popover,css-prop,--min-height
ion-popover,css-prop,--min-width
ion-popover,css-prop,--width
ion-popover-controller,none
ion-popover-controller,method,create,create<T extends ComponentRef>(options: PopoverOptions<T>) => Promise<HTMLIonPopoverElement>
ion-popover-controller,method,dismiss,dismiss(data?: any, role?: string | undefined, id?: string | undefined) => Promise<boolean>
ion-popover-controller,method,getTop,getTop() => Promise<HTMLIonPopoverElement | undefined>
ion-progress-bar,shadow
ion-progress-bar,prop,buffer,number,1,false,false
ion-progress-bar,prop,color,string | undefined,undefined,false,false
@@ -814,6 +825,7 @@ ion-progress-bar,css-prop,--buffer-background
ion-progress-bar,css-prop,--progress-background
ion-radio,shadow
ion-radio,prop,checked,boolean,false,false,false
ion-radio,prop,color,string | undefined,undefined,false,false
ion-radio,prop,disabled,boolean,false,false,false
ion-radio,prop,mode,"ios" | "md",undefined,false,false
@@ -821,10 +833,9 @@ ion-radio,prop,name,string,this.inputId,false,false
ion-radio,prop,value,any,undefined,false,false
ion-radio,event,ionBlur,void,true
ion-radio,event,ionFocus,void,true
ion-radio,css-prop,--border-radius
ion-radio,event,ionSelect,RadioChangeEventDetail,true
ion-radio,css-prop,--color
ion-radio,css-prop,--color-checked
ion-radio,css-prop,--inner-border-radius
ion-radio-group,none
ion-radio-group,prop,allowEmptySelection,boolean,false,false,false
@@ -931,16 +942,16 @@ ion-searchbar,scoped
ion-searchbar,prop,animated,boolean,false,false,false
ion-searchbar,prop,autocomplete,"off" | "on",'off',false,false
ion-searchbar,prop,autocorrect,"off" | "on",'off',false,false
ion-searchbar,prop,cancelButtonIcon,string,config.get('backButtonIcon', 'arrow-back-sharp') as string,false,false
ion-searchbar,prop,cancelButtonIcon,string,config.get('backButtonIcon', 'md-arrow-back') as string,false,false
ion-searchbar,prop,cancelButtonText,string,'Cancel',false,false
ion-searchbar,prop,clearIcon,string | undefined,undefined,false,false
ion-searchbar,prop,color,string | undefined,undefined,false,false
ion-searchbar,prop,debounce,number,250,false,false
ion-searchbar,prop,disabled,boolean,false,false,false
ion-searchbar,prop,inputmode,"decimal" | "email" | "none" | "numeric" | "search" | "tel" | "text" | "url" | undefined,undefined,false,false
ion-searchbar,prop,inputmode,"decimal" | "email" | "none" | "numeric" | "search" | "tel" | "text" | "url",'search',false,false
ion-searchbar,prop,mode,"ios" | "md",undefined,false,false
ion-searchbar,prop,placeholder,string,'Search',false,false
ion-searchbar,prop,searchIcon,string | undefined,undefined,false,false
ion-searchbar,prop,searchIcon,string,'search',false,false
ion-searchbar,prop,showCancelButton,"always" | "focus" | "never",'never',false,false
ion-searchbar,prop,spellcheck,boolean,false,false,false
ion-searchbar,prop,type,"email" | "number" | "password" | "search" | "tel" | "text" | "url",'search',false,false
@@ -964,40 +975,37 @@ ion-searchbar,css-prop,--placeholder-font-style
ion-searchbar,css-prop,--placeholder-font-weight
ion-searchbar,css-prop,--placeholder-opacity
ion-segment,shadow
ion-segment,scoped
ion-segment,prop,color,string | undefined,undefined,false,false
ion-segment,prop,disabled,boolean,false,false,false
ion-segment,prop,mode,"ios" | "md",undefined,false,false
ion-segment,prop,scrollable,boolean,false,false,false
ion-segment,prop,value,null | string | undefined,undefined,false,false
ion-segment,event,ionChange,SegmentChangeEventDetail,true
ion-segment,css-prop,--background
ion-segment-button,shadow
ion-segment-button,prop,checked,boolean,false,false,false
ion-segment-button,prop,disabled,boolean,false,false,false
ion-segment-button,prop,layout,"icon-bottom" | "icon-end" | "icon-hide" | "icon-start" | "icon-top" | "label-hide" | undefined,'icon-top',false,false
ion-segment-button,prop,mode,"ios" | "md",undefined,false,false
ion-segment-button,prop,type,"button" | "reset" | "submit",'button',false,false
ion-segment-button,prop,value,string,'ion-sb-' + (ids++),false,false
ion-segment-button,event,ionSelect,void,true
ion-segment-button,css-prop,--background
ion-segment-button,css-prop,--background-activated
ion-segment-button,css-prop,--background-checked
ion-segment-button,css-prop,--background-focused
ion-segment-button,css-prop,--background-focused-opacity
ion-segment-button,css-prop,--background-hover
ion-segment-button,css-prop,--background-hover-opacity
ion-segment-button,css-prop,--border-color
ion-segment-button,css-prop,--border-radius
ion-segment-button,css-prop,--border-style
ion-segment-button,css-prop,--border-width
ion-segment-button,css-prop,--color
ion-segment-button,css-prop,--color-activated
ion-segment-button,css-prop,--color-checked
ion-segment-button,css-prop,--color-focused
ion-segment-button,css-prop,--color-hover
ion-segment-button,css-prop,--indicator-box-shadow
ion-segment-button,css-prop,--color-checked-disabled
ion-segment-button,css-prop,--color-disabled
ion-segment-button,css-prop,--indicator-color
ion-segment-button,css-prop,--indicator-height
ion-segment-button,css-prop,--indicator-transform
ion-segment-button,css-prop,--indicator-transition
ion-segment-button,css-prop,--indicator-color-checked
ion-segment-button,css-prop,--margin-bottom
ion-segment-button,css-prop,--margin-end
ion-segment-button,css-prop,--margin-start
@@ -1035,6 +1043,7 @@ ion-select,css-prop,--placeholder-opacity
ion-select-option,shadow
ion-select-option,prop,disabled,boolean,false,false,false
ion-select-option,prop,selected,boolean,false,false,false
ion-select-option,prop,value,any,undefined,false,false
ion-skeleton-text,shadow
@@ -1097,7 +1106,7 @@ ion-spinner,prop,paused,boolean,false,false,false
ion-spinner,css-prop,--color
ion-split-pane,shadow
ion-split-pane,prop,contentId,string | undefined,undefined,false,true
ion-split-pane,prop,contentId,string | undefined,undefined,false,false
ion-split-pane,prop,disabled,boolean,false,false,false
ion-split-pane,prop,when,boolean | string,QUERY['lg'],false,false
ion-split-pane,event,ionSplitPaneVisible,{ visible: boolean; },true
@@ -1132,9 +1141,7 @@ ion-tab-button,prop,tab,string | undefined,undefined,false,false
ion-tab-button,prop,target,string | undefined,undefined,false,false
ion-tab-button,css-prop,--background
ion-tab-button,css-prop,--background-focused
ion-tab-button,css-prop,--background-focused-opacity
ion-tab-button,css-prop,--color
ion-tab-button,css-prop,--color-focused
ion-tab-button,css-prop,--color-selected
ion-tab-button,css-prop,--padding-bottom
ion-tab-button,css-prop,--padding-end
@@ -1239,6 +1246,11 @@ ion-toast,css-prop,--min-width
ion-toast,css-prop,--start
ion-toast,css-prop,--width
ion-toast-controller,none
ion-toast-controller,method,create,create(options?: ToastOptions | undefined) => Promise<HTMLIonToastElement>
ion-toast-controller,method,dismiss,dismiss(data?: any, role?: string | undefined, id?: string | undefined) => Promise<boolean>
ion-toast-controller,method,getTop,getTop() => Promise<HTMLIonToastElement | undefined>
ion-toggle,shadow
ion-toggle,prop,checked,boolean,false,false,false
ion-toggle,prop,color,string | undefined,undefined,false,false
@@ -1251,10 +1263,8 @@ ion-toggle,event,ionChange,ToggleChangeEventDetail,true
ion-toggle,event,ionFocus,void,true
ion-toggle,css-prop,--background
ion-toggle,css-prop,--background-checked
ion-toggle,css-prop,--border-radius
ion-toggle,css-prop,--handle-background
ion-toggle,css-prop,--handle-background-checked
ion-toggle,css-prop,--handle-border-radius
ion-toolbar,shadow
ion-toolbar,prop,color,string | undefined,undefined,false,false

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/core",
"version": "5.0.6",
"version": "5.0.0-beta.0",
"description": "Base components for Ionic",
"keywords": [
"ionic",
@@ -30,13 +30,13 @@
"loader/"
],
"dependencies": {
"ionicons": "^5.0.1",
"ionicons": "^4.6.3",
"tslib": "^1.10.0"
},
"devDependencies": {
"@stencil/core": "1.11.2",
"@stencil/sass": "1.1.1",
"@types/jest": "24.9.0",
"@stencil/core": "1.7.5",
"@stencil/sass": "1.0.1",
"@types/jest": "24.0.21",
"@types/node": "12.12.3",
"@types/puppeteer": "1.19.1",
"@types/swiper": "4.4.4",
@@ -49,7 +49,7 @@
"np": "^5.0.3",
"pixelmatch": "4.0.2",
"puppeteer": "1.20.0",
"rollup": "1.32.0",
"rollup": "1.19.4",
"rollup-plugin-node-resolve": "5.2.0",
"rollup-plugin-virtual": "^1.0.1",
"sass": "^1.22.9",

12231
core/src/components.d.ts vendored
View File

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
import { Build, Component, ComponentInterface, Method } from '@stencil/core';
import { ActionSheetOptions, OverlayController } from '../../interface';
import { createOverlay, dismissOverlay, getOverlay } from '../../utils/overlays';
/**
* @deprecated Use the `actionSheetController` exported from core.
*/
@Component({
tag: 'ion-action-sheet-controller'
})
export class ActionSheetController implements ComponentInterface, OverlayController {
constructor() {
if (Build.isDev) {
console.warn(`[DEPRECATED][ion-action-sheet-controller] Use the actionSheetController export from @ionic/core:
import { actionSheetController } from '@ionic/core';
const actionSheet = await actionSheetController.create({...});`);
}
}
/**
* Create an action sheet overlay with action sheet options.
*
* @param options The options to use to create the action sheet.
*/
@Method()
create(options: ActionSheetOptions): Promise<HTMLIonActionSheetElement> {
return createOverlay('ion-action-sheet', options);
}
/**
* Dismiss the open action sheet overlay.
*
* @param data Any data to emit in the dismiss events.
* @param role The role of the element that is dismissing the action sheet.
* This can be useful in a button handler for determining which button was
* clicked to dismiss the action sheet.
* Some examples include: ``"cancel"`, `"destructive"`, "selected"`, and `"backdrop"`.
* @param id The id of the action sheet to dismiss. If an id is not provided, it will dismiss the most recently opened action sheet.
*/
@Method()
dismiss(data?: any, role?: string, id?: string) {
return dismissOverlay(document, data, role, 'ion-action-sheet', id);
}
/**
* Get the most recently opened action sheet overlay.
*/
@Method()
async getTop(): Promise<HTMLIonActionSheetElement | undefined> {
return getOverlay(document, 'ion-action-sheet') as HTMLIonActionSheetElement;
}
}

View File

@@ -0,0 +1,45 @@
# ion-action-sheet-controller
Action Sheet controllers programmatically control the action sheet component. Action Sheets can be created and dismissed from the action sheet controller. View the [Action Sheet](../action-sheet) documentation for a full list of options to pass upon creation.
<!-- Auto Generated Below -->
> **[DEPRECATED]** Use the `actionSheetController` exported from core.
## Methods
### `create(options: ActionSheetOptions) => Promise<HTMLIonActionSheetElement>`
Create an action sheet overlay with action sheet options.
#### Returns
Type: `Promise<HTMLIonActionSheetElement>`
### `dismiss(data?: any, role?: string | undefined, id?: string | undefined) => Promise<boolean>`
Dismiss the open action sheet overlay.
#### Returns
Type: `Promise<boolean>`
### `getTop() => Promise<HTMLIonActionSheetElement | undefined>`
Get the most recently opened action sheet overlay.
#### Returns
Type: `Promise<HTMLIonActionSheetElement | undefined>`
----------------------------------------------
*Built with [StencilJS](https://stenciljs.com/)*

View File

@@ -6,18 +6,9 @@
:host {
--background: #{$action-sheet-ios-background-color};
--background-selected: #{$action-sheet-ios-button-background-selected};
--background-activated: #{$action-sheet-ios-button-background-activated};
--backdrop-opacity: var(--ion-backdrop-opacity, 0.4);
--button-background: #{$action-sheet-ios-button-background};
--button-background-activated: #{$action-sheet-ios-button-background-activated};
--button-background-activated-opacity: .08;
--button-background-hover: currentColor;
--button-background-hover-opacity: .04;
--button-background-focused: currentColor;
--button-background-focused-opacity: .12;
--button-background-selected: #{$action-sheet-ios-button-background-selected};
--button-background-selected-opacity: 1;
--button-color: #{$action-sheet-ios-button-text-color};
--color: #{$action-sheet-ios-title-color};
text-align: $action-sheet-ios-text-align;
}
@@ -41,6 +32,8 @@
.action-sheet-group {
@include border-radius($action-sheet-ios-border-radius);
@include margin(null, null, $action-sheet-ios-group-margin-bottom - 2, null);
overflow: hidden;
}
.action-sheet-group:first-child {
@@ -76,13 +69,13 @@
backdrop-filter: $action-sheet-ios-button-translucent-filter;
}
:host(.action-sheet-translucent) .action-sheet-button.ion-activated {
:host(.action-sheet-translucent) .action-sheet-button.activated {
background-color: $action-sheet-ios-translucent-background-color-activated;
background-image: none;
}
:host(.action-sheet-translucent) .action-sheet-cancel {
background: var(--button-background-selected);
background: var(--background-selected);
}
}
@@ -91,8 +84,16 @@
// Border is made with a linear gradient in order
// to get the proper color and iOS blur effect
.action-sheet-title {
background: $action-sheet-ios-button-background;
.action-sheet-title,
.action-sheet-button {
background-color: transparent;
background-image: linear-gradient(0deg, $action-sheet-ios-button-border-color, $action-sheet-ios-button-border-color 50%, transparent 50%);
background-repeat: no-repeat;
/* stylelint-disable-next-line all */
background-position: bottom;
background-size: 100% 1px;
}
@@ -125,6 +126,8 @@
height: $action-sheet-ios-button-height;
color: var(--color, $action-sheet-ios-button-text-color);
font-size: $action-sheet-ios-button-font-size;
contain: strict;
@@ -141,30 +144,17 @@
}
.action-sheet-selected {
background: var(--background-selected);
font-weight: bold;
}
.action-sheet-cancel {
font-weight: $action-sheet-ios-button-cancel-font-weight;
&::after {
background: var(--button-background-selected);
opacity: var(--button-background-selected-opacity);
}
}
// iOS Action Sheet Button: Destructive
// ---------------------------------------------------
.action-sheet-destructive,
.action-sheet-destructive.ion-activated,
.action-sheet-destructive.ion-focused {
.action-sheet-destructive {
color: $action-sheet-ios-button-destructive-text-color;
}
@media (any-hover: hover) {
.action-sheet-destructive:hover {
color: $action-sheet-ios-button-destructive-text-color;
}
.action-sheet-cancel {
background: var(--background-selected);
font-weight: $action-sheet-ios-button-cancel-font-weight;
}

View File

@@ -105,9 +105,21 @@ $action-sheet-ios-button-icon-font-size: 28px !default;
/// @prop - Padding right of the action sheet button icon
$action-sheet-ios-button-icon-padding-right: .1em !default;
/// @prop - Height of the action sheet button icon
$action-sheet-ios-button-icon-height: .7em !default;
/// @prop - Margin top of the action sheet button icon
$action-sheet-ios-button-icon-margin-top: -10px !default;
/// @prop - Font size of the action sheet button
$action-sheet-ios-button-font-size: 20px !default;
/// @prop - Border width of the action sheet button
$action-sheet-ios-button-border-width: $hairlines-width !default;
/// @prop - Border style of the action sheet button
$action-sheet-ios-button-border-style: solid !default;
/// @prop - Border color alpha of the action sheet button
$action-sheet-ios-button-border-color-alpha: .08 !default;
@@ -115,10 +127,13 @@ $action-sheet-ios-button-border-color-alpha: .08 !default;
$action-sheet-ios-button-border-color: rgba($text-color-rgb, $action-sheet-ios-button-border-color-alpha) !default;
/// @prop - Background color of the action sheet button
$action-sheet-ios-button-background: linear-gradient(0deg, $action-sheet-ios-button-border-color, $action-sheet-ios-button-border-color 50%, transparent 50%) bottom / 100% 1px no-repeat transparent !default;
$action-sheet-ios-button-background: transparent !default;
/// @prop - Background color alpha of the activated action sheet button
$action-sheet-ios-button-background-alpha-activated: .08 !default;
/// @prop - Background color of the activated action sheet button
$action-sheet-ios-button-background-activated: $text-color !default;
$action-sheet-ios-button-background-activated: rgba($text-color-rgb, $action-sheet-ios-button-background-alpha-activated) !default;
/// @prop - Background color of the selected action sheet button
$action-sheet-ios-button-background-selected: $background-color !default;

View File

@@ -6,18 +6,9 @@
:host {
--background: #{$action-sheet-md-background-color};
--background-selected: #{var(--background, $action-sheet-md-button-background-selected)};
--background-activated: var(--background);
--backdrop-opacity: var(--ion-backdrop-opacity, 0.32);
--button-background: transparent;
--button-background-selected: currentColor;
--button-background-selected-opacity: 0;
--button-background-activated: transparent;
--button-background-activated-opacity: 0;
--button-background-hover: currentColor;
--button-background-hover-opacity: .04;
--button-background-focused: currentColor;
--button-background-focused-opacity: .12;
--button-color: #{$action-sheet-md-button-text-color};
--color: #{$action-sheet-md-title-color};
}
.action-sheet-title {
@@ -61,6 +52,9 @@
height: $action-sheet-md-button-height;
background: transparent;
color: var(--color, $action-sheet-md-button-text-color);
font-size: $action-sheet-md-button-font-size;
text-align: $action-sheet-md-text-align;
@@ -73,7 +67,7 @@
@include padding(null, null, 4px, null);
@include margin($action-sheet-md-icon-margin-top, $action-sheet-md-icon-margin-end, $action-sheet-md-icon-margin-bottom, $action-sheet-md-icon-margin-start);
color: var(--color);
color: var(--color, $action-sheet-md-icon-color);
font-size: $action-sheet-md-icon-font-size;
}

View File

@@ -87,6 +87,13 @@ $action-sheet-md-button-padding-start: $action-sheet-md-button-
/// @prop - Background color of the action sheet button
$action-sheet-md-button-background: transparent !default;
/// @prop - Background color of the action sheet activated button
$action-sheet-md-button-background-activated: $background-color-step-50 !default;
/// @prop - Background color of the selected action sheet button
$action-sheet-md-button-background-selected: null !default;
// Action Sheet Icon
// --------------------------------------------------

View File

@@ -6,6 +6,9 @@
:host {
/**
* @prop --background: Background of the action sheet group
* @prop --background-activated: Background of the action sheet button when pressed
* @prop --background-selected: Background of the selected action sheet button
*
* @prop --color: Color of the action sheet text
*
* @prop --min-width: Minimum width of the action sheet
@@ -17,34 +20,14 @@
* @prop --max-height: Maximum height of the action sheet
*
* @prop --backdrop-opacity: Opacity of the backdrop
*
* @prop --button-background: Background of the action sheet button
* @prop --button-background-activated: Background of the action sheet button when pressed. Note: setting this will interfere with the Material Design ripple.
* @prop --button-background-activated-opacity: Opacity of the action sheet button background when pressed
* @prop --button-background-hover: Background of the action sheet button on hover
* @prop --button-background-hover-opacity: Opacity of the action sheet button background on hover
* @prop --button-background-focused: Background of the action sheet button when tabbed to
* @prop --button-background-focused-opacity: Opacity of the action sheet button background when tabbed to
* @prop --button-background-selected: Background of the selected action sheet button
* @prop --button-background-selected-opacity: Opacity of the selected action sheet button background
*
* @prop --button-color: Color of the action sheet button
* @prop --button-color-activated: Color of the action sheet button when pressed
* @prop --button-color-hover: Color of the action sheet button on hover
* @prop --button-color-focused: Color of the action sheet button when tabbed to
* @prop --button-color-selected: Color of the selected action sheet button
*/
--color: initial;
--button-color-activated: var(--button-color);
--button-color-focused: var(--button-color);
--button-color-hover: var(--button-color);
--button-color-selected: var(--button-color);
--min-width: auto;
--width: #{$action-sheet-width};
--max-width: #{$action-sheet-max-width};
--min-height: auto;
--height: 100%;
--max-height: calc(100% - (var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));
--max-height: 100%;
@include font-smoothing();
@include position(0, 0, 0, 0);
@@ -85,7 +68,6 @@
.action-sheet-button {
display: block;
position: relative;
width: 100%;
@@ -93,19 +75,16 @@
outline: none;
background: var(--button-background);
color: var(--button-color);
font-family: inherit;
}
overflow: hidden;
.action-sheet-button.activated {
background: var(--background-activated);
}
.action-sheet-button-inner {
display: flex;
position: relative;
flex-flow: row nowrap;
flex-shrink: 0;
align-items: center;
@@ -113,8 +92,6 @@
width: 100%;
height: 100%;
z-index: 1;
}
.action-sheet-container {
@@ -147,67 +124,6 @@
overflow: hidden;
}
// Action Sheet: States
// --------------------------------------------------
.action-sheet-button::after {
@include button-state();
}
// Action Sheet: Selected
// --------------------------------------------------
.action-sheet-selected {
color: var(--button-color-selected);
&::after {
background: var(--button-background-selected);
opacity: var(--button-background-selected-opacity);
}
}
// Action Sheet: Activated
// --------------------------------------------------
.action-sheet-button.ion-activated {
color: var(--button-color-activated);
&::after {
background: var(--button-background-activated);
opacity: var(--button-background-activated-opacity);
}
}
// Action Sheet: Focused
// --------------------------------------------------
.action-sheet-button.ion-focused {
color: var(--button-color-focused);
&::after {
background: var(--button-background-focused);
opacity: var(--button-background-focused-opacity);
}
}
// Action Sheet: Hover
// --------------------------------------------------
@media (any-hover: hover) {
.action-sheet-button:hover {
color: var(--button-color-hover);
&::after {
background: var(--button-background-hover);
opacity: var(--button-background-hover-opacity);
}
}
background: var(--background-selected);
}

View File

@@ -25,6 +25,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
presented = false;
animation?: any;
mode = getIonMode(this);
@Element() el!: HTMLIonActionSheetElement;
@@ -225,7 +226,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
</div>
}
{buttons.map(b =>
<button type="button" class={buttonClass(b)} onClick={() => this.buttonClick(b)}>
<button type="button" ion-activatable class={buttonClass(b)} onClick={() => this.buttonClick(b)}>
<span class="action-sheet-button-inner">
{b.icon && <ion-icon icon={b.icon} lazy={false} class="action-sheet-icon" />}
{b.text}
@@ -251,7 +252,6 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
/>}
{cancelButton.text}
</span>
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
</button>
</div>
}
@@ -266,7 +266,6 @@ const buttonClass = (button: ActionSheetButton): CssClassMap => {
return {
'action-sheet-button': true,
'ion-activatable': true,
'ion-focusable': true,
[`action-sheet-${button.role}`]: button.role !== undefined,
...getClassMap(button.cssClass),
};

View File

@@ -11,11 +11,7 @@ export const iosEnterAnimation = (baseEl: HTMLElement): Animation => {
backdropAnimation
.addElement(baseEl.querySelector('ion-backdrop')!)
.fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
.beforeStyles({
'pointer-events': 'none'
})
.afterClearStyles(['pointer-events']);
.fromTo('opacity', 0.01, 'var(--backdrop-opacity)');
wrapperAnimation
.addElement(baseEl.querySelector('.action-sheet-wrapper')!)

View File

@@ -11,11 +11,7 @@ export const mdEnterAnimation = (baseEl: HTMLElement): Animation => {
backdropAnimation
.addElement(baseEl.querySelector('ion-backdrop')!)
.fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
.beforeStyles({
'pointer-events': 'none'
})
.afterClearStyles(['pointer-events']);
.fromTo('opacity', 0.01, 'var(--backdrop-opacity)');
wrapperAnimation
.addElement(baseEl.querySelector('.action-sheet-wrapper')!)

View File

@@ -2,6 +2,10 @@
An Action Sheet is a dialog that displays a set of options. It appears on top of the app's content, and must be manually dismissed by the user before they can resume interaction with the app. Destructive options are made obvious in `ios` mode. There are multiple ways to dismiss the action sheet, including tapping the backdrop or hitting the escape key on desktop.
### Creating
An action sheet can be created by the [Action Sheet Controller](../action-sheet-controller) from an array of `buttons`, with each button including properties for its `text`, and optionally a `handler` and `role`. If a handler returns `false` then the action sheet will not be dismissed. An action sheet can also optionally have a `header` and a `subHeader`.
### Buttons
A button's `role` property can either be `destructive` or `cancel`. Buttons without a role property will have the default look for the platform. Buttons with the `cancel` role will always load as the bottom button, no matter where they are in the array. All other buttons will be displayed in the order they have been added to the `buttons` array. Note: We recommend that `destructive` buttons are always the first button in the array, making them the top button. Additionally, if the action sheet is dismissed by tapping the backdrop, then it will fire the handler from the button with the cancel role.
@@ -123,7 +127,6 @@ async function presentActionSheet() {
```typescript
import React, { useState } from 'react'
import { IonActionSheet, IonContent, IonButton } from '@ionic/react';
import { trash, share, playCircleOutline, heart, close } from 'ionicons/icons';
export const ActionSheetExample: React.FC = () => {
@@ -138,31 +141,31 @@ export const ActionSheetExample: React.FC = () => {
buttons={[{
text: 'Delete',
role: 'destructive',
icon: trash,
icon: 'trash',
handler: () => {
console.log('Delete clicked');
}
}, {
text: 'Share',
icon: share,
icon: 'share',
handler: () => {
console.log('Share clicked');
}
}, {
text: 'Play (open modal)',
icon: playCircleOutline,
icon: 'arrow-dropright-circle',
handler: () => {
console.log('Play clicked');
}
}, {
text: 'Favorite',
icon: heart,
icon: 'heart',
handler: () => {
console.log('Favorite clicked');
}
}, {
text: 'Cancel',
icon: close,
icon: 'close',
role: 'cancel',
handler: () => {
console.log('Cancel clicked');
@@ -316,31 +319,19 @@ Type: `Promise<void>`
## CSS Custom Properties
| Name | Description |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `--backdrop-opacity` | Opacity of the backdrop |
| `--background` | Background of the action sheet group |
| `--button-background` | Background of the action sheet button |
| `--button-background-activated` | Background of the action sheet button when pressed. Note: setting this will interfere with the Material Design ripple. |
| `--button-background-activated-opacity` | Opacity of the action sheet button background when pressed |
| `--button-background-focused` | Background of the action sheet button when tabbed to |
| `--button-background-focused-opacity` | Opacity of the action sheet button background when tabbed to |
| `--button-background-hover` | Background of the action sheet button on hover |
| `--button-background-hover-opacity` | Opacity of the action sheet button background on hover |
| `--button-background-selected` | Background of the selected action sheet button |
| `--button-background-selected-opacity` | Opacity of the selected action sheet button background |
| `--button-color` | Color of the action sheet button |
| `--button-color-activated` | Color of the action sheet button when pressed |
| `--button-color-focused` | Color of the action sheet button when tabbed to |
| `--button-color-hover` | Color of the action sheet button on hover |
| `--button-color-selected` | Color of the selected action sheet button |
| `--color` | Color of the action sheet text |
| `--height` | height of the action sheet |
| `--max-height` | Maximum height of the action sheet |
| `--max-width` | Maximum width of the action sheet |
| `--min-height` | Minimum height of the action sheet |
| `--min-width` | Minimum width of the action sheet |
| `--width` | Width of the action sheet |
| Name | Description |
| ------------------------ | -------------------------------------------------- |
| `--backdrop-opacity` | Opacity of the backdrop |
| `--background` | Background of the action sheet group |
| `--background-activated` | Background of the action sheet button when pressed |
| `--background-selected` | Background of the selected action sheet button |
| `--color` | Color of the action sheet text |
| `--height` | height of the action sheet |
| `--max-height` | Maximum height of the action sheet |
| `--max-width` | Maximum width of the action sheet |
| `--min-height` | Minimum height of the action sheet |
| `--min-width` | Minimum width of the action sheet |
| `--width` | Width of the action sheet |
## Dependencies

View File

@@ -10,10 +10,6 @@
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script></head>
<script type="module">
import { actionSheetController } from '../../../../dist/ionic/index.esm.js';
window.actionSheetController = actionSheetController;
</script>
<body>
<ion-app>
@@ -40,10 +36,10 @@
<style>
.my-color-class {
--background: #292929;
--button-background-selected: #222222;
--background-selected: #222222;
--color: #dfdfdf;
--button-color: #dfdfdf;
;
}
.my-custom-class {
@@ -61,14 +57,11 @@
</style>
<script>
window.addEventListener('ionActionSheetDidDismiss', function (e) { console.log('didDismiss', e) })
async function openActionSheet(opts) {
const actionSheet = await actionSheetController.create(opts);
await actionSheet.present();
}
async function presentBasic() {
const mode = Ionic.mode;
await openActionSheet({
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
header: "Albums",
buttons: [{
text: 'Delete',
@@ -80,13 +73,13 @@
}, {
text: 'Share',
icon: 'share',
cssClass: 'ion-activated',
cssClass: 'activated',
handler: () => {
console.log('Share clicked');
}
}, {
text: 'Play (open modal)',
icon: 'chevron-forward-circle',
icon: 'arrow-dropright-circle',
handler: () => {
console.log('Play clicked');
}
@@ -105,10 +98,12 @@
}
}]
});
document.body.append(actionSheetElement);
await actionSheetElement.present();
}
async function presentAlert() {
await openActionSheet({
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
buttons: [{
text: 'Open Alert',
handler: async () => {
@@ -119,7 +114,7 @@
buttons: [{
text: 'Okay',
handler: async () => {
await actionSheetController.dismiss();
await actionSheetElement.dismiss();
return false;
}
}]
@@ -136,10 +131,12 @@
}
}]
});
document.body.append(actionSheetElement);
await actionSheetElement.present();
}
async function presentCancelOnly() {
await openActionSheet({
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
buttons: [
{
text: 'Cancel',
@@ -150,17 +147,21 @@
}
]
});
document.body.append(actionSheetElement);
await actionSheetElement.present();
}
async function presentWithCssClass(classList) {
await openActionSheet({
const addClass = classList ? classList : "my-color-class my-custom-class";
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
header: "Custom Css Class",
cssClass: classList ? classList : "my-color-class my-custom-class",
cssClass: addClass,
buttons: [
{
text: 'Add to Favorites',
icon: 'star',
cssClass: 'my-custom-button customClass ion-activated',
cssClass: 'my-custom-button customClass activated',
handler: () => {
console.log('Add to Favorites clicked');
}
@@ -196,10 +197,14 @@
}
]
});
document.body.append(actionSheetElement);
await actionSheetElement.present();
}
async function presentIcons() {
await openActionSheet({
const mode = Ionic.mode;
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
header: "Albums",
buttons: [{
text: 'Delete',
@@ -216,7 +221,7 @@
}
}, {
text: 'Play (open modal)',
icon: 'chevron-forward-circle',
icon: 'arrow-dropright-circle',
handler: () => {
console.log('Play clicked');
}
@@ -236,10 +241,12 @@
}
}]
});
document.body.append(actionSheetElement);
await actionSheetElement.present();
}
async function presentNoBackdropDismiss() {
await openActionSheet({
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
backdropDismiss: false,
buttons: [{
text: 'Archive',
@@ -260,10 +267,12 @@
}
}]
});
document.body.append(actionSheetElement);
await actionSheetElement.present();
}
async function presentScroll() {
await openActionSheet({
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
buttons: [
{
text: 'Add Reaction',
@@ -272,7 +281,7 @@
}
}, {
text: 'Copy Text',
cssClass: 'ion-activated',
cssClass: 'activated',
handler: () => {
console.log('Copy Text clicked');
}
@@ -351,10 +360,12 @@
}
]
});
document.body.append(actionSheetElement);
await actionSheetElement.present();
}
async function presentScrollNoCancel() {
await openActionSheet({
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
buttons: [
{
text: 'Add Reaction',
@@ -420,6 +431,8 @@
}
]
});
document.body.append(actionSheetElement);
await actionSheetElement.present();
}
</script>
</body>

View File

@@ -10,10 +10,7 @@
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script></head>
<script type="module">
import { actionSheetController } from '../../../../dist/ionic/index.esm.js';
window.actionSheetController = actionSheetController;
</script>
<body>
<ion-app>
@@ -34,7 +31,8 @@
async function presentSpec() {
const mode = Ionic.mode;
const actionSheet = await actionSheetController.create({
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
header: "Open in",
buttons: [{
text: 'Item 1',
@@ -68,7 +66,8 @@
}
}]
});
await actionSheet.present();
document.body.appendChild(actionSheetElement);
await actionSheetElement.present();
}
</script>
</body>

View File

@@ -10,10 +10,7 @@
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script></head>
<script type="module">
import { actionSheetController } from '../../../../dist/ionic/index.esm.js';
window.actionSheetController = actionSheetController;
</script>
<body>
<button id="basic" onclick="presentBasic()">Basic</button>
<button id="noBackdropDismiss" onclick="presentNoBackdropDismiss()">No Backdrop Dismiss</button>
@@ -40,13 +37,8 @@
<script>
window.addEventListener('ionActionSheetDidDismiss', function(e){console.log('didDismiss', e)})
async function openActionSheet(opts) {
const actionSheet = await actionSheetController.create(opts);
await actionSheet.present();
}
function presentBasic() {
openActionSheet({
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
header: "Albums",
buttons: [{
text: 'Delete',
@@ -63,7 +55,7 @@
}
}, {
text: 'Play (open modal)',
icon: 'chevron-forward-circle',
icon: 'arrow-dropright-circle',
handler: () => {
console.log('Play clicked');
}
@@ -82,10 +74,14 @@
}
}]
});
document.body.appendChild(actionSheetElement);
return actionSheetElement.present();
}
function presentIcons() {
openActionSheet({
const mode = Ionic.mode;
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
header: "Albums",
buttons: [{
text: 'Delete',
@@ -102,7 +98,7 @@
}
}, {
text: 'Play (open modal)',
icon: 'chevron-forward-circle',
icon: 'arrow-dropright-circle',
handler: () => {
console.log('Play clicked');
}
@@ -121,10 +117,12 @@
}
}]
});
document.body.appendChild(actionSheetElement);
return actionSheetElement.present();
}
function presentNoBackdropDismiss() {
openActionSheet({
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
buttons: [{
text: 'Archive',
handler: () => {
@@ -144,10 +142,12 @@
}
}]
});
document.body.appendChild(actionSheetElement);
return actionSheetElement.present();
}
function presentAlert() {
openActionSheet({
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
buttons: [{
text: 'Open Alert',
handler: () => {
@@ -161,10 +161,12 @@
}
}]
});
document.body.appendChild(actionSheetElement);
return actionSheetElement.present();
}
function presentScroll() {
openActionSheet({
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
buttons: [
{
text: 'Add Reaction',
@@ -236,10 +238,12 @@
}
]
});
document.body.appendChild(actionSheetElement);
return actionSheetElement.present();
}
function presentScrollNoCancel() {
openActionSheet({
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
buttons: [
{
text: 'Add Reaction',
@@ -305,10 +309,12 @@
}
]
});
document.body.appendChild(actionSheetElement);
return actionSheetElement.present();
}
function presentCancelOnly() {
openActionSheet({
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
buttons: [
{
text: 'Cancel',
@@ -319,10 +325,12 @@
}
]
});
document.body.append(actionSheetElement);
return actionSheetElement.present();
}
function presentWithCssClass() {
openActionSheet({
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
header: "Custom Css Class",
cssClass: "my-class my-custom-class",
buttons: [
@@ -336,6 +344,8 @@
}
]
});
document.body.appendChild(actionSheetElement);
return actionSheetElement.present();
}
</script>

View File

@@ -10,10 +10,7 @@
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script></head>
<script type="module">
import { actionSheetController } from '../../../../dist/ionic/index.esm.js';
window.actionSheetController = actionSheetController;
</script>
<body>
<ion-app>
@@ -49,15 +46,12 @@
</ion-app>
<script>
async function openActionSheet(opts) {
const actionSheet = await actionSheetController.create(opts);
await actionSheet.present();
}
async function presentBasic() {
var mode = Ionic.mode;
await openActionSheet({
const actionSheetController = document.querySelector('ion-action-sheet-controller');
const actionSheetElement = await actionSheetController.create({
header: "Albums",
buttons: [{
text: 'Delete',
@@ -74,7 +68,7 @@
}
}, {
text: 'Play (open modal)',
icon: 'chevron-forward-circle',
icon: 'arrow-dropright-circle',
handler: () => {
console.log('Play clicked');
}
@@ -93,11 +87,13 @@
}
}],
translucent: true
});
})
await actionSheetElement.present();
}
async function presentNoBackdropDismiss() {
await openActionSheet({
const actionSheetController = document.querySelector('ion-action-sheet-controller');
const actionSheetElement = await actionSheetController.create({
backdropDismiss: false,
buttons: [{
text: 'Archive',
@@ -119,10 +115,12 @@
}],
translucent: true
});
return await actionSheetElement.present();
}
async function presentAlert() {
await openActionSheet({
const actionSheetController = document.querySelector('ion-action-sheet-controller');
const actionSheetElement = await actionSheetController.create({
buttons: [{
text: 'Open Alert',
handler: () => {
@@ -137,10 +135,12 @@
}],
translucent: true
});
return await actionSheetElement.present();
}
async function presentScroll() {
await openActionSheet({
const actionSheetController = document.querySelector('ion-action-sheet-controller');
const actionSheetElement = await actionSheetController.create({
buttons: [
{
text: 'Add Reaction',
@@ -149,7 +149,7 @@
}
}, {
text: 'Copy Text',
cssClass: 'ion-activated',
cssClass: 'activated',
handler: () => {
console.log('Copy Text clicked');
}
@@ -185,7 +185,7 @@
}
}, {
text: 'Edit Title',
cssClass: 'ion-activated',
cssClass: 'activated',
handler: () => {
console.log('Edit Title clicked');
}
@@ -215,10 +215,12 @@
],
translucent: true
});
return await actionSheetElement.present();
}
async function presentScrollNoCancel() {
await openActionSheet({
const actionSheetController = document.querySelector('ion-action-sheet-controller');
const actionSheetElement = await actionSheetController.create({
buttons: [
{
text: 'Add Reaction',
@@ -285,10 +287,12 @@
],
translucent: true
});
return await actionSheetElement.present();
}
async function presentCancelOnly() {
await openActionSheet({
const actionSheetController = document.querySelector('ion-action-sheet-controller');
const actionSheetElement = await actionSheetController.create({
buttons: [
{
text: 'Cancel',
@@ -300,6 +304,7 @@
],
translucent: true
});
return await actionSheetElement.present();
}
</script>

View File

@@ -1,7 +1,6 @@
```typescript
import React, { useState } from 'react'
import { IonActionSheet, IonContent, IonButton } from '@ionic/react';
import { trash, share, playCircleOutline, heart, close } from 'ionicons/icons';
export const ActionSheetExample: React.FC = () => {
@@ -16,31 +15,31 @@ export const ActionSheetExample: React.FC = () => {
buttons={[{
text: 'Delete',
role: 'destructive',
icon: trash,
icon: 'trash',
handler: () => {
console.log('Delete clicked');
}
}, {
text: 'Share',
icon: share,
icon: 'share',
handler: () => {
console.log('Share clicked');
}
}, {
text: 'Play (open modal)',
icon: playCircleOutline,
icon: 'arrow-dropright-circle',
handler: () => {
console.log('Play clicked');
}
}, {
text: 'Favorite',
icon: heart,
icon: 'heart',
handler: () => {
console.log('Favorite clicked');
}
}, {
text: 'Cancel',
icon: close,
icon: 'close',
role: 'cancel',
handler: () => {
console.log('Cancel clicked');

View File

@@ -0,0 +1,54 @@
import { Build, Component, ComponentInterface, Method } from '@stencil/core';
import { AlertOptions, OverlayController } from '../../interface';
import { createOverlay, dismissOverlay, getOverlay } from '../../utils/overlays';
/**
* @deprecated Use the `alertController` exported from core.
*/
@Component({
tag: 'ion-alert-controller'
})
export class AlertController implements ComponentInterface, OverlayController {
constructor() {
if (Build.isDev) {
console.warn(`[DEPRECATED][ion-alert-controller] Use the alertController export from @ionic/core:
import { alertController } from '@ionic/core';
const alert = await alertController.create({...});`);
}
}
/**
* Create an alert overlay with alert options.
*
* @param options The options to use to create the alert.
*/
@Method()
create(options: AlertOptions): Promise<HTMLIonAlertElement> {
return createOverlay('ion-alert', options);
}
/**
* Dismiss the open alert overlay.
*
* @param data Any data to emit in the dismiss events.
* @param role The role of the element that is dismissing the alert.
* This can be useful in a button handler for determining which button was
* clicked to dismiss the alert.
* Some examples include: ``"cancel"`, `"destructive"`, "selected"`, and `"backdrop"`.
* @param id The id of the alert to dismiss. If an id is not provided, it will dismiss the most recently opened alert.
*/
@Method()
dismiss(data?: any, role?: string, id?: string) {
return dismissOverlay(document, data, role, 'ion-alert', id);
}
/**
* Get the most recently opened alert overlay.
*/
@Method()
async getTop(): Promise<HTMLIonAlertElement | undefined> {
return getOverlay(document, 'ion-alert') as HTMLIonAlertElement;
}
}

View File

@@ -0,0 +1,46 @@
# ion-alert-controller
Alert controllers programmatically control the alert component. Alerts can be created and dismissed by the alert controller. View the [Alert](../alert) documentation for the list of options to pass upon creation and usage information.
<!-- Auto Generated Below -->
> **[DEPRECATED]** Use the `alertController` exported from core.
## Methods
### `create(options: AlertOptions) => Promise<HTMLIonAlertElement>`
Create an alert overlay with alert options.
#### Returns
Type: `Promise<HTMLIonAlertElement>`
### `dismiss(data?: any, role?: string | undefined, id?: string | undefined) => Promise<boolean>`
Dismiss the open alert overlay.
#### Returns
Type: `Promise<boolean>`
### `getTop() => Promise<HTMLIonAlertElement | undefined>`
Get the most recently opened alert overlay.
#### Returns
Type: `Promise<HTMLIonAlertElement | undefined>`
----------------------------------------------
*Built with [StencilJS](https://stenciljs.com/)*

View File

@@ -298,6 +298,6 @@
font-weight: $alert-ios-button-main-font-weight;
}
.alert-button.ion-activated {
.alert-button.activated {
background-color: $alert-ios-button-background-color-activated;
}

View File

@@ -1,7 +1,7 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Method, Prop, Watch, forceUpdate, h } from '@stencil/core';
import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Method, Prop, Watch, h } from '@stencil/core';
import { getIonMode } from '../../global/ionic-global';
import { AlertButton, AlertInput, AnimationBuilder, CssClassMap, OverlayEventDetail, OverlayInterface } from '../../interface';
import { AlertButton, AlertInput, Animation, AnimationBuilder, CssClassMap, OverlayEventDetail, OverlayInterface } from '../../interface';
import { BACKDROP, dismiss, eventMethod, isCancel, prepareOverlay, present, safeCall } from '../../utils/overlays';
import { sanitizeDOMString } from '../../utils/sanitization';
import { getClassMap } from '../../utils/theme';
@@ -30,6 +30,8 @@ export class Alert implements ComponentInterface, OverlayInterface {
private processedButtons: AlertButton[] = [];
presented = false;
animation?: Animation;
mode = getIonMode(this);
@Element() el!: HTMLIonAlertElement;
@@ -214,13 +216,13 @@ export class Alert implements ComponentInterface, OverlayInterface {
}
this.activeId = selectedInput.id;
safeCall(selectedInput.handler, selectedInput);
forceUpdate(this);
this.el.forceUpdate();
}
private cbClick(selectedInput: AlertInput) {
selectedInput.checked = !selectedInput.checked;
safeCall(selectedInput.handler, selectedInput);
forceUpdate(this);
this.el.forceUpdate();
}
private buttonClick(button: AlertButton) {

View File

@@ -11,11 +11,7 @@ export const iosEnterAnimation = (baseEl: HTMLElement): Animation => {
backdropAnimation
.addElement(baseEl.querySelector('ion-backdrop')!)
.fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
.beforeStyles({
'pointer-events': 'none'
})
.afterClearStyles(['pointer-events']);
.fromTo('opacity', 0.01, 'var(--backdrop-opacity)');
wrapperAnimation
.addElement(baseEl.querySelector('.alert-wrapper')!)

View File

@@ -11,11 +11,7 @@ export const mdEnterAnimation = (baseEl: HTMLElement): Animation => {
backdropAnimation
.addElement(baseEl.querySelector('ion-backdrop')!)
.fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
.beforeStyles({
'pointer-events': 'none'
})
.afterClearStyles(['pointer-events']);
.fromTo('opacity', 0.01, 'var(--backdrop-opacity)');
wrapperAnimation
.addElement(baseEl.querySelector('.alert-wrapper')!)

View File

@@ -2,6 +2,12 @@
An Alert is a dialog that presents users with information or collects information from the user using inputs. An alert appears on top of the app's content, and must be manually dismissed by the user before they can resume interaction with the app. It can also optionally have a `header`, `subHeader` and `message`.
### Creating
Alerts can be created using an [Alert Controller](../alert-controller). They can be customized by passing alert options in the alert controller's create method.
### Buttons
In the array of `buttons`, each button includes properties for its `text`, and optionally a `handler`. If a handler returns `false` then the alert will not automatically be dismissed when the button is clicked. All buttons will show up in the order they have been added to the `buttons` array from left to right. Note: The right most button (the last one in the array) is the main button.

View File

@@ -10,11 +10,7 @@
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script></head>
<script type="module">
import { alertController } from '../../../../dist/ionic/index.esm.js';
window.alertController = alertController;
</script>
<body>
<ion-app>
@@ -49,45 +45,50 @@
window.addEventListener('ionAlertDidDismiss', function (e) { console.log('didDismiss', e) })
window.addEventListener('ionAlertWillDismiss', function (e) { console.log('willDismiss', e) })
async function openAlert(opts) {
const alert = await alertController.create(opts);
await alert.present();
}
function presentAlert() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Alert',
subHeader: 'Subtitle',
message: 'This is an alert message.',
buttons: ['OK']
});
document.body.append(alert);
return alert.present();
}
function presentAlertLongMessage() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Alert',
message: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum hendrerit diam lorem, a faucibus turpis sagittis eu. In finibus augue in dui varius convallis. Donec vulputate nibh gravida odio vulputate commodo. Suspendisse imperdiet consequat egestas. Nulla feugiat consequat urna eu tincidunt. Cras nec blandit turpis, eu auctor nunc. Pellentesque finibus, magna eu vestibulum imperdiet, arcu ex lacinia massa, eget volutpat quam leo a orci. Etiam mauris est, elementum at feugiat at, dictum in sapien. Mauris efficitur eros sodales convallis egestas. Phasellus eu faucibus nisl. In eu diam vitae libero egestas lacinia. Integer sed convallis metus, nec commodo felis. Duis libero augue, ornare at tempus non, posuere vel augue. Cras mattis dui at tristique aliquam. Phasellus fermentum nibh ligula, porta hendrerit ligula elementum eu. Suspendisse sollicitudin enim at libero iaculis pulvinar. Donec ac massa id purus laoreet rutrum quis eu urna. Mauris luctus erat vel magna porttitor, vel varius erat rhoncus. Donec eu turpis vestibulum, feugiat urna id, gravida mauris. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer at lobortis tortor. Nam ultrices volutpat elit, sed pharetra nulla suscipit at. Nunc eu accumsan eros, id auctor libero. Suspendisse potenti. Nam vitae dapibus metus. Maecenas nisi dui, sagittis et condimentum eu, bibendum vel eros. Vivamus malesuada, tortor in accumsan iaculis, urna velit consectetur ante, nec semper sem diam a diam. In et semper ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus blandit, velit vel porttitor euismod, neque risus blandit nulla, non laoreet libero dolor et odio. Nulla enim risus, feugiat eu urna sed, ultrices semper felis. Sed blandit mi diam. Nunc quis mi ligula. Pellentesque a elit eu orci volutpat egestas. Aenean fermentum eleifend quam, ut tincidunt eros tristique et. Nam dapibus tincidunt ligula, id faucibus felis sodales quis. Donec tincidunt lectus ipsum, ac semper tellus cursus ac. Vestibulum nec dui a lectus accumsan vestibulum quis et velit. Aliquam finibus justo et odio euismod, viverra condimentum eros tristique. Sed eget luctus risus. Pellentesque lorem magna, dictum non congue sodales, laoreet eget quam. In sagittis vulputate dolor a ultricies. Donec viverra leo sed ex maximus, in finibus elit gravida. Aliquam posuere vulputate mi. Suspendisse potenti. Nunc consectetur congue arcu, at pharetra dui varius non. Etiam vestibulum congue felis, id ullamcorper neque convallis ultrices. Aenean congue, diam a iaculis mollis, nisl eros maximus arcu, nec hendrerit purus felis porta diam. Nullam vitae ultrices dui, ac dictum sapien. Phasellus eu magna luctus, varius urna id, molestie quam. Nulla in semper tellus. Curabitur lacinia tellus sit amet lacinia dapibus. Sed id condimentum tellus, nec aliquam sapien. Vivamus luctus at ante a tincidunt.',
buttons: ['Cancel', 'OK']
});
document.body.append(alert);
return alert.present();
}
function presentAlertMultipleButtons() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Alert',
subHeader: 'Subtitle',
message: 'This is an alert message.',
buttons: ['Cancel', 'Open Modal', 'Delete']
});
document.body.append(alert);
return alert.present();
}
function presentAlertNoMessage() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Alert',
buttons: ['OK']
});
document.body.append(alert);
return alert.present();
}
function presentAlertConfirm() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Confirm!',
message: 'Message <strong>text</strong>!!!',
buttons: [
@@ -106,10 +107,12 @@
}
]
});
document.body.append(alert);
return alert.present();
}
function presentAlertPrompt() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Prompt!',
inputs: [
{
@@ -179,10 +182,12 @@
}
]
});
document.body.append(alert);
return alert.present();
}
function presentAlertRadio() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Radio',
inputs: [
{
@@ -234,10 +239,12 @@
}
]
});
document.body.append(alert);
return alert.present();
}
function presentAlertCheckbox() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Checkbox',
inputs: [
{
@@ -294,10 +301,12 @@
}
]
});
document.body.append(alert);
return alert.present();
}
function presentWithCssClass() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Alert',
subHeader: 'Subtitle',
cssClass: 'my-class my-custom-class ',
@@ -310,6 +319,8 @@
}
}]
});
document.body.append(alert);
return alert.present();
}
</script>

View File

View File

@@ -10,11 +10,7 @@
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script></head>
<script type="module">
import { alertController } from '../../../../dist/ionic/index.esm.js';
window.alertController = alertController;
</script>
<body>
<button id="basic" onclick="presentAlert()">Alert</button>
<button id="longMessage" onclick="presentAlertLongMessage()">Alert Long Message</button>
@@ -79,45 +75,50 @@
<script>
window.addEventListener('ionAlertDidDismiss', function(e){console.log('didDismiss', e)})
window.addEventListener('ionAlertWillDismiss', function(e){console.log('willDismiss', e)})
async function openAlert(opts) {
const alert = await alertController.create(opts);
await alert.present();
}
function presentAlert() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Alert',
subHeader: 'Subtitle',
message: 'This is an alert message.',
buttons: ['OK']
});
document.body.appendChild(alert);
return alert.present();
}
function presentAlertLongMessage() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Alert',
message: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum hendrerit diam lorem, a faucibus turpis sagittis eu. In finibus augue in dui varius convallis. Donec vulputate nibh gravida odio vulputate commodo. Suspendisse imperdiet consequat egestas. Nulla feugiat consequat urna eu tincidunt. Cras nec blandit turpis, eu auctor nunc. Pellentesque finibus, magna eu vestibulum imperdiet, arcu ex lacinia massa, eget volutpat quam leo a orci. Etiam mauris est, elementum at feugiat at, dictum in sapien. Mauris efficitur eros sodales convallis egestas. Phasellus eu faucibus nisl. In eu diam vitae libero egestas lacinia. Integer sed convallis metus, nec commodo felis. Duis libero augue, ornare at tempus non, posuere vel augue. Cras mattis dui at tristique aliquam. Phasellus fermentum nibh ligula, porta hendrerit ligula elementum eu. Suspendisse sollicitudin enim at libero iaculis pulvinar. Donec ac massa id purus laoreet rutrum quis eu urna. Mauris luctus erat vel magna porttitor, vel varius erat rhoncus. Donec eu turpis vestibulum, feugiat urna id, gravida mauris. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer at lobortis tortor. Nam ultrices volutpat elit, sed pharetra nulla suscipit at. Nunc eu accumsan eros, id auctor libero. Suspendisse potenti. Nam vitae dapibus metus. Maecenas nisi dui, sagittis et condimentum eu, bibendum vel eros. Vivamus malesuada, tortor in accumsan iaculis, urna velit consectetur ante, nec semper sem diam a diam. In et semper ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus blandit, velit vel porttitor euismod, neque risus blandit nulla, non laoreet libero dolor et odio. Nulla enim risus, feugiat eu urna sed, ultrices semper felis. Sed blandit mi diam. Nunc quis mi ligula. Pellentesque a elit eu orci volutpat egestas. Aenean fermentum eleifend quam, ut tincidunt eros tristique et. Nam dapibus tincidunt ligula, id faucibus felis sodales quis. Donec tincidunt lectus ipsum, ac semper tellus cursus ac. Vestibulum nec dui a lectus accumsan vestibulum quis et velit. Aliquam finibus justo et odio euismod, viverra condimentum eros tristique. Sed eget luctus risus. Pellentesque lorem magna, dictum non congue sodales, laoreet eget quam. In sagittis vulputate dolor a ultricies. Donec viverra leo sed ex maximus, in finibus elit gravida. Aliquam posuere vulputate mi. Suspendisse potenti. Nunc consectetur congue arcu, at pharetra dui varius non. Etiam vestibulum congue felis, id ullamcorper neque convallis ultrices. Aenean congue, diam a iaculis mollis, nisl eros maximus arcu, nec hendrerit purus felis porta diam. Nullam vitae ultrices dui, ac dictum sapien. Phasellus eu magna luctus, varius urna id, molestie quam. Nulla in semper tellus. Curabitur lacinia tellus sit amet lacinia dapibus. Sed id condimentum tellus, nec aliquam sapien. Vivamus luctus at ante a tincidunt.',
buttons: ['Cancel', 'OK']
});
document.body.appendChild(alert);
return alert.present();
}
function presentAlertMultipleButtons() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Alert',
subHeader: 'Subtitle',
message: 'This is an alert message.',
buttons: ['Cancel', 'Open Modal', 'Delete']
});
document.body.appendChild(alert);
return alert.present();
}
function presentAlertNoMessage() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Alert',
buttons: ['OK']
});
document.body.appendChild(alert);
return alert.present();
}
function presentAlertConfirm() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Confirm!',
message: 'Message <strong>text</strong>!!!',
buttons: [
@@ -136,10 +137,12 @@
}
]
});
document.body.appendChild(alert);
return alert.present();
}
function presentAlertPrompt() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Prompt!',
inputs: [
{
@@ -196,10 +199,12 @@
}
]
});
document.body.appendChild(alert);
return alert.present();
}
function presentAlertRadio() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Radio',
inputs: [
{
@@ -250,10 +255,12 @@
}
]
});
document.body.appendChild(alert);
return alert.present();
}
function presentAlertCheckbox() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Checkbox',
inputs: [
{
@@ -309,10 +316,12 @@
}
]
});
document.body.appendChild(alert);
return alert.present();
}
function presentWithCssClass() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Alert',
subHeader: 'Subtitle',
cssClass: 'my-class my-customClass ',
@@ -325,6 +334,8 @@
}
}]
});
document.body.appendChild(alert);
return alert.present();
}
</script>

View File

@@ -10,11 +10,7 @@
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script></head>
<script type="module">
import { alertController } from '../../../../dist/ionic/index.esm.js';
window.alertController = alertController;
</script>
<body>
<ion-app>
@@ -54,49 +50,53 @@
</ion-app>
<script>
async function openAlert(opts) {
const alert = await alertController.create(opts);
await alert.present();
}
function presentAlert() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Alert',
subHeader: 'Subtitle',
message: 'This is an alert message.',
buttons: ['OK'],
translucent: true
});
document.body.appendChild(alert);
return alert.present();
}
function presentAlertLongMessage() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Alert',
message: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum hendrerit diam lorem, a faucibus turpis sagittis eu. In finibus augue in dui varius convallis. Donec vulputate nibh gravida odio vulputate commodo. Suspendisse imperdiet consequat egestas. Nulla feugiat consequat urna eu tincidunt. Cras nec blandit turpis, eu auctor nunc. Pellentesque finibus, magna eu vestibulum imperdiet, arcu ex lacinia massa, eget volutpat quam leo a orci. Etiam mauris est, elementum at feugiat at, dictum in sapien. Mauris efficitur eros sodales convallis egestas. Phasellus eu faucibus nisl. In eu diam vitae libero egestas lacinia. Integer sed convallis metus, nec commodo felis. Duis libero augue, ornare at tempus non, posuere vel augue. Cras mattis dui at tristique aliquam. Phasellus fermentum nibh ligula, porta hendrerit ligula elementum eu. Suspendisse sollicitudin enim at libero iaculis pulvinar. Donec ac massa id purus laoreet rutrum quis eu urna. Mauris luctus erat vel magna porttitor, vel varius erat rhoncus. Donec eu turpis vestibulum, feugiat urna id, gravida mauris. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer at lobortis tortor. Nam ultrices volutpat elit, sed pharetra nulla suscipit at. Nunc eu accumsan eros, id auctor libero. Suspendisse potenti. Nam vitae dapibus metus. Maecenas nisi dui, sagittis et condimentum eu, bibendum vel eros. Vivamus malesuada, tortor in accumsan iaculis, urna velit consectetur ante, nec semper sem diam a diam. In et semper ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus blandit, velit vel porttitor euismod, neque risus blandit nulla, non laoreet libero dolor et odio. Nulla enim risus, feugiat eu urna sed, ultrices semper felis. Sed blandit mi diam. Nunc quis mi ligula. Pellentesque a elit eu orci volutpat egestas. Aenean fermentum eleifend quam, ut tincidunt eros tristique et. Nam dapibus tincidunt ligula, id faucibus felis sodales quis. Donec tincidunt lectus ipsum, ac semper tellus cursus ac. Vestibulum nec dui a lectus accumsan vestibulum quis et velit. Aliquam finibus justo et odio euismod, viverra condimentum eros tristique. Sed eget luctus risus. Pellentesque lorem magna, dictum non congue sodales, laoreet eget quam. In sagittis vulputate dolor a ultricies. Donec viverra leo sed ex maximus, in finibus elit gravida. Aliquam posuere vulputate mi. Suspendisse potenti. Nunc consectetur congue arcu, at pharetra dui varius non. Etiam vestibulum congue felis, id ullamcorper neque convallis ultrices. Aenean congue, diam a iaculis mollis, nisl eros maximus arcu, nec hendrerit purus felis porta diam. Nullam vitae ultrices dui, ac dictum sapien. Phasellus eu magna luctus, varius urna id, molestie quam. Nulla in semper tellus. Curabitur lacinia tellus sit amet lacinia dapibus. Sed id condimentum tellus, nec aliquam sapien. Vivamus luctus at ante a tincidunt.',
buttons: ['Cancel', 'OK'],
translucent: true
});
document.body.appendChild(alert);
return alert.present();
}
function presentAlertMultipleButtons() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Alert',
subHeader: 'Subtitle',
message: 'This is an alert message.',
buttons: ['Cancel', 'Open Modal', 'Delete'],
translucent: true
});
document.body.appendChild(alert);
return alert.present();
}
function presentAlertNoMessage() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Alert',
buttons: ['OK'],
translucent: true
});
document.body.appendChild(alert);
return alert.present();
}
function presentAlertConfirm() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Confirm!',
message: 'Message <strong>text</strong>!!!',
buttons: [
@@ -116,10 +116,12 @@
],
translucent: true
});
document.body.appendChild(alert);
return alert.present();
}
function presentAlertPrompt() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Prompt!',
inputs: [
{
@@ -177,10 +179,12 @@
],
translucent: true
});
document.body.appendChild(alert);
return alert.present();
}
function presentAlertRadio() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Radio',
inputs: [
{
@@ -188,7 +192,6 @@
label: 'Radio 1',
value: 'value1',
checked: true
},
{
type: 'radio',
@@ -233,10 +236,12 @@
],
translucent: true
});
document.body.appendChild(alert);
return alert.present();
}
function presentAlertCheckbox() {
openAlert({
const alert = Object.assign(document.createElement('ion-alert'), {
header: 'Checkbox',
inputs: [
{
@@ -293,6 +298,8 @@
],
translucent: true
});
document.body.appendChild(alert);
return alert.present();
}
</script>

View File

@@ -60,7 +60,7 @@
const toast = Object.assign(document.createElement('ion-toast'), {
message: 'Hello world!',
buttons: [
{ text: 'Close', role: 'cancel' }
{ text: 'Close', role: 'close' }
]
});
document.body.appendChild(toast);
@@ -71,7 +71,7 @@
<body>
<ion-app>
<ion-menu content-id="main">
<ion-menu>
<ion-header>
<ion-toolbar>
<ion-title>Menu</ion-title>
@@ -94,7 +94,7 @@
</ion-toolbar>
</ion-header>
<ion-content id="main">
<ion-content main>
<ion-card>
<ion-card-header>
<ion-card-title>Card</ion-card-title>

View File

@@ -5,10 +5,7 @@
// --------------------------------------------------
:host {
--background-hover: transparent;
--background-hover-opacity: 1;
--background-focused: currentColor;
--background-focused-opacity: .1;
--background-focused: #{ion-color(primary, base, .1)};
--border-radius: 4px;
--color: #{$back-button-ios-color};
--icon-margin-end: -5px;
@@ -29,20 +26,21 @@
// Back Button States
// --------------------------------------------------
:host(.ion-activated) .button-native {
:host(.activated) .button-native {
opacity: .4;
}
@media (any-hover: hover) {
:host(:hover) {
opacity: .6;
--opacity: .6;
}
}
// Back Button Color: Focused
// --------------------------------------------------
:host(.ion-color.ion-focused) .button-native::after {
background: #{current-color(base)};
:host(.ion-color.ion-focused) .button-native {
background: #{current-color(base, .1)};
}

View File

@@ -6,10 +6,8 @@
:host {
--border-radius: 4px;
--background-focused: currentColor;
--background-focused-opacity: .12;
--background-hover: currentColor;
--background-hover-opacity: 0.04;
--background-focused: rgba(66, 66, 66, 0.24);
--background-hover: rgba(66, 66, 66, 0.08);
--color: #{$back-button-md-color};
--icon-margin-end: 0;
--icon-margin-start: 0;
@@ -52,8 +50,8 @@ ion-icon {
// --------------------------------------------------
@media (any-hover: hover) {
:host(.ion-color:hover) .button-native::after {
background: #{current-color(base)};
:host(.ion-color:hover) .button-native {
background: #{current-color(base, .08)};
}
}
@@ -61,6 +59,6 @@ ion-icon {
// Back Button Color: Focused
// --------------------------------------------------
:host(.ion-color.ion-focused) .button-native::after {
background: #{current-color(base)};
:host(.ion-color.ion-focused) .button-native {
background: #{current-color(base, .24)};
}

View File

@@ -7,13 +7,11 @@
/**
* @prop --background: Background of the button
* @prop --background-focused: Background of the button when focused with the tab key
* @prop --background-focused-opacity: Opacity of the button background when focused with the tab key
* @prop --background-hover: Background of the button on hover
* @prop --background-hover-opacity: Opacity of the background on hover
* @prop --background-hover: Background of the button when hover
*
* @prop --color: Text color of the button
* @prop --color-focused: Text color of the button when focused with the tab key
* @prop --color-hover: Text color of the button on hover
* @prop --color-hover: Text color of the button when hover
*
* @prop --min-width: Minimum width of the button
* @prop --min-height: Minimum height of the button
@@ -50,8 +48,8 @@
* @prop --icon-font-weight: Font weight of the button icon
*/
--background: transparent;
--color-focused: currentColor;
--color-hover: currentColor;
--color-focused: var(--color);
--color-hover: var(--color);
--icon-margin-top: 0;
--icon-margin-bottom: 0;
--icon-padding-top: 0;
@@ -104,6 +102,7 @@
// Back Button States
// --------------------------------------------------
:host-context(.can-go-back > ion-header),
:host(.show-back-button) {
display: block;
}
@@ -145,8 +144,6 @@
cursor: pointer;
opacity: var(--opacity);
overflow: hidden;
user-select: none;
z-index: 0;
appearance: none;
@@ -154,7 +151,6 @@
.button-inner {
display: flex;
position: relative;
flex-flow: row nowrap;
flex-shrink: 0;
@@ -163,8 +159,6 @@
width: 100%;
height: 100%;
z-index: 1;
}
@@ -184,45 +178,22 @@ ion-icon {
}
// Back Button: Hover
// --------------------------------------------------
@media (any-hover: hover) {
:host(:hover) .button-native {
background: var(--background-hover);
color: var(--color-hover);
}
}
// Back Button: Focused
// --------------------------------------------------
:host(.ion-focused) .button-native {
background: var(--background-focused);
color: var(--color-focused);
&::after {
background: var(--background-focused);
opacity: var(--background-focused-opacity);
}
}
// Back Button: Hover
// --------------------------------------------------
.button-native::after {
@include button-state();
}
@media (any-hover: hover) {
:host(:hover) .button-native {
color: var(--color-hover);
&::after {
background: var(--background-hover);
opacity: var(--background-hover-opacity);
}
}
}
// Back Button Color: Focused
// --------------------------------------------------
:host(.ion-color.ion-focused) .button-native {
color: #{current-color(base)};
}
@@ -236,9 +207,17 @@ ion-icon {
}
// Back Button Color: Focused
// --------------------------------------------------
:host(.ion-color.ion-focused) .button-native {
color: #{current-color(base)};
}
// Back Button in Toolbar: Global Theming
// --------------------------------------------------
:host(.in-toolbar:not(.in-toolbar-color)) {
:host-context(ion-toolbar:not(.ion-color)):not(.ion-color) {
color: #{var(--ion-toolbar-color, var(--color))};
}

View File

@@ -4,7 +4,7 @@ import { config } from '../../global/config';
import { getIonMode } from '../../global/ionic-global';
import { Color } from '../../interface';
import { ButtonInterface } from '../../utils/element-interface';
import { createColorClasses, hostContext, openURL } from '../../utils/theme';
import { createColorClasses, openURL } from '../../utils/theme';
/**
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
@@ -15,10 +15,11 @@ import { createColorClasses, hostContext, openURL } from '../../utils/theme';
ios: 'back-button.ios.scss',
md: 'back-button.md.scss'
},
shadow: true
scoped: true
})
export class BackButton implements ComponentInterface, ButtonInterface {
private mode = getIonMode(this);
@Element() el!: HTMLElement;
/**
@@ -53,32 +54,20 @@ export class BackButton implements ComponentInterface, ButtonInterface {
*/
@Prop() type: 'submit' | 'reset' | 'button' = 'button';
get backButtonIcon() {
const icon = this.icon;
if (icon != null) {
// icon is set on the component or by the config
return icon;
}
if (getIonMode(this) === 'ios') {
// default ios back button icon
return config.get('backButtonIcon', 'chevron-back');
}
// default md back button icon
return config.get('backButtonIcon', 'arrow-back-sharp');
private get backButtonIcon() {
return this.icon != null ? this.icon : config.get('backButtonIcon', 'arrow-back');
}
get backButtonText() {
const defaultBackButtonText = getIonMode(this) === 'ios' ? 'Back' : null;
private get backButtonText() {
const defaultBackButtonText = this.mode === 'ios' ? 'Back' : null;
return this.text != null ? this.text : config.get('backButtonText', defaultBackButtonText);
}
get hasIconOnly() {
private get hasIconOnly() {
return this.backButtonIcon && !this.backButtonText;
}
get rippleType() {
private get rippleType() {
// If the button only has an icon we use the unbounded
// "circular" ripple effect
if (this.hasIconOnly) {
@@ -99,9 +88,8 @@ export class BackButton implements ComponentInterface, ButtonInterface {
}
render() {
const { color, defaultHref, disabled, type, hasIconOnly, backButtonIcon, backButtonText } = this;
const { color, defaultHref, disabled, type, mode, hasIconOnly, backButtonIcon, backButtonText } = this;
const showBackButton = defaultHref !== undefined;
const mode = getIonMode(this);
return (
<Host
@@ -113,17 +101,15 @@ export class BackButton implements ComponentInterface, ButtonInterface {
'button': true, // ion-buttons target .button
'back-button-disabled': disabled,
'back-button-has-icon-only': hasIconOnly,
'in-toolbar': hostContext('ion-toolbar', this.el),
'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
'ion-activatable': true,
'ion-focusable': true,
'show-back-button': showBackButton
}}
>
<button type={type} disabled={disabled} class="button-native" part="button">
<button type={type} disabled={disabled} class="button-native">
<span class="button-inner">
{backButtonIcon && <ion-icon icon={backButtonIcon} lazy={false} part="icon"></ion-icon>}
{backButtonText && <span class="button-text" part="text">{backButtonText}</span>}
{backButtonIcon && <ion-icon icon={backButtonIcon} lazy={false}></ion-icon>}
{backButtonText && <span class="button-text">{backButtonText}</span>}
</span>
{mode === 'md' && <ion-ripple-effect type={this.rippleType}></ion-ripple-effect>}
</button>

View File

@@ -245,40 +245,38 @@ export const BackButtonExample: React.FC = () => (
## CSS Custom Properties
| Name | Description |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------- |
| `--background` | Background of the button |
| `--background-focused` | Background of the button when focused with the tab key |
| `--background-focused-opacity` | Opacity of the button background when focused with the tab key |
| `--background-hover` | Background of the button on hover |
| `--background-hover-opacity` | Opacity of the background on hover |
| `--border-radius` | Border radius of the button |
| `--color` | Text color of the button |
| `--color-focused` | Text color of the button when focused with the tab key |
| `--color-hover` | Text color of the button on hover |
| `--icon-font-size` | Font size of the button icon |
| `--icon-font-weight` | Font weight of the button icon |
| `--icon-margin-bottom` | Bottom margin of the button icon |
| `--icon-margin-end` | Right margin if direction is left-to-right, and left margin if direction is right-to-left of the button icon |
| `--icon-margin-start` | Left margin if direction is left-to-right, and right margin if direction is right-to-left of the button icon |
| `--icon-margin-top` | Top margin of the button icon |
| `--icon-padding-bottom` | Bottom padding of the button icon |
| `--icon-padding-end` | Right padding if direction is left-to-right, and left padding if direction is right-to-left of the button icon |
| `--icon-padding-start` | Left padding if direction is left-to-right, and right padding if direction is right-to-left of the button icon |
| `--icon-padding-top` | Top padding of the button icon |
| `--margin-bottom` | Bottom margin of the button |
| `--margin-end` | Right margin if direction is left-to-right, and left margin if direction is right-to-left of the button |
| `--margin-start` | Left margin if direction is left-to-right, and right margin if direction is right-to-left of the button |
| `--margin-top` | Top margin of the button |
| `--min-height` | Minimum height of the button |
| `--min-width` | Minimum width of the button |
| `--opacity` | Opacity of the button |
| `--padding-bottom` | Bottom padding of the button |
| `--padding-end` | Right padding if direction is left-to-right, and left padding if direction is right-to-left of the button |
| `--padding-start` | Left padding if direction is left-to-right, and right padding if direction is right-to-left of the button |
| `--padding-top` | Top padding of the button |
| `--ripple-color` | Color of the button ripple effect |
| `--transition` | Transition of the button |
| Name | Description |
| ----------------------- | -------------------------------------------------------------------------------------------------------------- |
| `--background` | Background of the button |
| `--background-focused` | Background of the button when focused with the tab key |
| `--background-hover` | Background of the button when hover |
| `--border-radius` | Border radius of the button |
| `--color` | Text color of the button |
| `--color-focused` | Text color of the button when focused with the tab key |
| `--color-hover` | Text color of the button when hover |
| `--icon-font-size` | Font size of the button icon |
| `--icon-font-weight` | Font weight of the button icon |
| `--icon-margin-bottom` | Bottom margin of the button icon |
| `--icon-margin-end` | Right margin if direction is left-to-right, and left margin if direction is right-to-left of the button icon |
| `--icon-margin-start` | Left margin if direction is left-to-right, and right margin if direction is right-to-left of the button icon |
| `--icon-margin-top` | Top margin of the button icon |
| `--icon-padding-bottom` | Bottom padding of the button icon |
| `--icon-padding-end` | Right padding if direction is left-to-right, and left padding if direction is right-to-left of the button icon |
| `--icon-padding-start` | Left padding if direction is left-to-right, and right padding if direction is right-to-left of the button icon |
| `--icon-padding-top` | Top padding of the button icon |
| `--margin-bottom` | Bottom margin of the button |
| `--margin-end` | Right margin if direction is left-to-right, and left margin if direction is right-to-left of the button |
| `--margin-start` | Left margin if direction is left-to-right, and right margin if direction is right-to-left of the button |
| `--margin-top` | Top margin of the button |
| `--min-height` | Minimum height of the button |
| `--min-width` | Minimum width of the button |
| `--opacity` | Opacity of the button |
| `--padding-bottom` | Bottom padding of the button |
| `--padding-end` | Right padding if direction is left-to-right, and left padding if direction is right-to-left of the button |
| `--padding-start` | Left padding if direction is left-to-right, and right padding if direction is right-to-left of the button |
| `--padding-top` | Top padding of the button |
| `--ripple-color` | Color of the button ripple effect |
| `--transition` | Transition of the button |
## Dependencies

View File

@@ -1,73 +0,0 @@
import { newSpecPage } from '@stencil/core/testing';
import { BackButton } from "../back-button";
import { config } from "../../../global/config";
import { setMode } from '@stencil/core';
describe('back button', () => {
beforeEach(() => {
config.reset({});
});
const newBackButton = async (mode: string = 'md'): Promise<BackButton> => {
setMode(() => mode);
const { rootInstance } = await newSpecPage({
components: [BackButton],
html: `<ion-back-button></ion-back-button>`
})
return rootInstance;
};
describe('backButtonIcon', () => {
it('set custom icon on the instance, override config', async () => {
const bb = await newBackButton();
bb.icon = 'custom-icon-instance';
config.reset({
backButtonIcon: 'custom-icon-config'
});
expect(bb.backButtonIcon).toBe('custom-icon-instance');
});
it('set custom icon in the config', async () => {
const bb = await newBackButton();
config.reset({
backButtonIcon: 'custom-icon-config'
});
expect(bb.backButtonIcon).toBe('custom-icon-config');
});
it('set custom icon on the instance', async () => {
const bb = await newBackButton();
bb.icon = 'custom-icon-instance';
expect(bb.backButtonIcon).toBe('custom-icon-instance');
});
it('default icon for ios mode', async () => {
const bb = await newBackButton('ios');
expect(bb.backButtonIcon).toBe('chevron-back');
});
it('default icon', async () => {
const bb = await newBackButton();
expect(bb.backButtonIcon).toBe('arrow-back-sharp');
});
});
describe('backButtonText', () => {
it('default text for ios mode', async () => {
const bb = await newBackButton('ios');
expect(bb.backButtonText).toBe('Back');
});
it('default text', async () => {
const bb = await newBackButton();
expect(bb.backButtonText).toBe(null);
});
});
});

View File

@@ -10,8 +10,7 @@
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
</head>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script></head>
<body>
<ion-app>
@@ -76,63 +75,19 @@
<p>
<ion-back-button class="custom"></ion-back-button>
<ion-back-button color="secondary" class="custom"></ion-back-button>
</p>
<p>
<ion-back-button class="custom ion-focused"></ion-back-button>
<ion-back-button color="secondary" class="custom ion-focused"></ion-back-button>
</p>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
<ion-back-button class="ion-focused"></ion-back-button>
</ion-buttons>
<ion-title>Default</ion-title>
</ion-toolbar>
<ion-toolbar color="primary">
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
<ion-back-button class="ion-focused"></ion-back-button>
</ion-buttons>
<ion-title>Primary</ion-title>
</ion-toolbar>
<ion-toolbar color="light">
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
<ion-back-button class="ion-focused"></ion-back-button>
</ion-buttons>
<ion-title>Light</ion-title>
</ion-toolbar>
<ion-toolbar color="success">
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
<ion-back-button class="ion-focused"></ion-back-button>
</ion-buttons>
<ion-title>Success</ion-title>
</ion-toolbar>
<ion-toolbar class="themed">
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
<ion-back-button class="ion-focused"></ion-back-button>
</ion-buttons>
<ion-title>Themed</ion-title>
</ion-toolbar>
<ion-toolbar color="dark">
<ion-buttons slot="start">
<ion-back-button class="ion-hide"></ion-back-button>
</ion-buttons>
<ion-title>Hidden</ion-title>
</ion-toolbar>
</ion-content>
</ion-app>
<script>
var buttons = document.querySelectorAll('ion-back-button');
for (var i = 0; i < buttons.length; i++) {
for(var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', (event) => onClick(event));
}
@@ -158,9 +113,7 @@
.wide {
--background: #d1f3ff;
--background-hover: #add8e6;
--background-hover-opacity: 1;
--background-focused: #84c5db;
--background-focused-opacity: 1;
height: 50px;
width: 150px;
@@ -187,14 +140,6 @@
--padding-end: 10px;
}
.custom:hover {
opacity: 1;
}
.themed {
--ion-toolbar-background: #222;
--ion-toolbar-color: #ddd;
}
</style>
</body>

View File

@@ -34,15 +34,15 @@
<ion-back-button color="dark"></ion-back-button>
</p>
<p>
<ion-back-button color="primary" class="ion-activated"></ion-back-button>
<ion-back-button color="secondary" class="ion-activated"></ion-back-button>
<ion-back-button color="tertiary" class="ion-activated"></ion-back-button>
<ion-back-button color="success" class="ion-activated"></ion-back-button>
<ion-back-button color="warning" class="ion-activated"></ion-back-button>
<ion-back-button color="danger" class="ion-activated"></ion-back-button>
<ion-back-button color="light" class="ion-activated"></ion-back-button>
<ion-back-button color="medium" class="ion-activated"></ion-back-button>
<ion-back-button color="dark" class="ion-activated"></ion-back-button>
<ion-back-button color="primary" class="activated"></ion-back-button>
<ion-back-button color="secondary" class="activated"></ion-back-button>
<ion-back-button color="tertiary" class="activated"></ion-back-button>
<ion-back-button color="success" class="activated"></ion-back-button>
<ion-back-button color="warning" class="activated"></ion-back-button>
<ion-back-button color="danger" class="activated"></ion-back-button>
<ion-back-button color="light" class="activated"></ion-back-button>
<ion-back-button color="medium" class="activated"></ion-back-button>
<ion-back-button color="dark" class="activated"></ion-back-button>
</p>
<h3>Custom</h3>
@@ -54,13 +54,13 @@
<!-- Custom Colors -->
<ion-back-button class="custom"></ion-back-button>
<ion-back-button class="custom ion-activated"></ion-back-button>
<ion-back-button class="custom activated"></ion-back-button>
<ion-back-button color="secondary" class="custom"></ion-back-button>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
<ion-back-button class="ion-activated"></ion-back-button>
<ion-back-button class="activated"></ion-back-button>
</ion-buttons>
<ion-title>Default</ion-title>
</ion-toolbar>
@@ -68,7 +68,7 @@
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button class="custom"></ion-back-button>
<ion-back-button class="custom ion-activated"></ion-back-button>
<ion-back-button class="custom activated"></ion-back-button>
</ion-buttons>
<ion-title>Custom</ion-title>
</ion-toolbar>
@@ -76,7 +76,7 @@
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button color="secondary"></ion-back-button>
<ion-back-button color="secondary" class="ion-activated"></ion-back-button>
<ion-back-button color="secondary" class="activated"></ion-back-button>
</ion-buttons>
<ion-title>Secondary</ion-title>
</ion-toolbar>
@@ -84,7 +84,7 @@
<ion-toolbar color="danger">
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
<ion-back-button class="ion-activated"></ion-back-button>
<ion-back-button class="activated"></ion-back-button>
</ion-buttons>
<ion-title>Danger</ion-title>
</ion-toolbar>
@@ -92,7 +92,7 @@
<ion-toolbar color="dark">
<ion-buttons slot="start">
<ion-back-button text="Back" icon=""></ion-back-button>
<ion-back-button text="Back" icon="" class="ion-activated"></ion-back-button>
<ion-back-button text="Back" icon="" class="activated"></ion-back-button>
</ion-buttons>
<ion-title>Dark</ion-title>
</ion-toolbar>

View File

@@ -114,13 +114,13 @@ export const BackdropExample: React.FC = () => (
<ion-backdrop visible="false"></ion-backdrop>
<!-- Backdrop with propagation -->
<ion-backdrop stop-propagation="false"></ion-backdrop>
<ion-backdrop stopPropagation="false"></ion-backdrop>
<!-- Backdrop that sets dynamic properties -->
<ion-backdrop
:tappable="enableBackdropDismiss"
:visible="showBackdrop"
:stop-propagation="shouldPropagate">
:stopPropagation="shouldPropagate">
</ion-backdrop>
</template>

View File

@@ -10,13 +10,13 @@
<ion-backdrop visible="false"></ion-backdrop>
<!-- Backdrop with propagation -->
<ion-backdrop stop-propagation="false"></ion-backdrop>
<ion-backdrop stopPropagation="false"></ion-backdrop>
<!-- Backdrop that sets dynamic properties -->
<ion-backdrop
:tappable="enableBackdropDismiss"
:visible="showBackdrop"
:stop-propagation="shouldPropagate">
:stopPropagation="shouldPropagate">
</ion-backdrop>
</template>

View File

@@ -22,11 +22,7 @@
<ion-content id="content">
<ion-list>
<ion-list-header>
<ion-label>
Badges Right
</ion-label>
</ion-list-header>
<ion-list-header>Badges Right</ion-list-header>
<ion-item>
<ion-label>Default Badge</ion-label>
<ion-badge slot="end">00</ion-badge>
@@ -74,11 +70,7 @@
</ion-list>
<ion-list>
<ion-list-header>
<ion-label>
Badges Left
</ion-label>
</ion-list-header>
<ion-list-header>Badges Left</ion-list-header>
<ion-item>
<ion-label>Default Badge</ion-label>
<ion-badge slot="start">00</ion-badge>

View File

@@ -23,19 +23,20 @@
letter-spacing: #{$button-ios-letter-spacing};
}
// iOS Solid Button
// --------------------------------------------------
:host(.button-solid) {
--background-activated: #{ion-color(primary, shade)};
--background-focused: #{ion-color(primary, shade)};
--background-hover: #{ion-color(primary, tint)};
--background-activated-opacity: 1;
--background-focused-opacity: 1;
--background-hover-opacity: 1;
}
:host(.button-solid.activated) {
--opacity: #{$button-ios-opacity-activated};
}
:host(.button-solid.activated.ion-color) .button-native {
background: current-color(shade);
}
// iOS Outline Button
// --------------------------------------------------
@@ -45,26 +46,28 @@
--border-width: #{$button-ios-outline-border-width};
--border-style: #{$button-ios-outline-border-style};
--background-activated: #{ion-color(primary, base)};
--background-focused: #{ion-color(primary, base)};
--background-hover: transparent;
--background-focused-opacity: .1;
--background-focused: #{ion-color(primary, base, .1)};
--color-activated: #{ion-color(primary, contrast)};
}
:host(.button-outline.activated.ion-color) .button-native {
background: current-color(base);
color: current-color(contrast);
}
// iOS Clear Button
// --------------------------------------------------
:host(.button-clear.activated) {
--opacity: #{$button-ios-clear-opacity-activated};
}
:host(.button-clear) {
--background-activated: transparent;
--background-focused: #{ion-color(primary, base)};
--background-hover: transparent;
--background-focused-opacity: .1;
font-size: #{$button-ios-clear-font-size};
font-weight: #{$button-ios-clear-font-weight};
letter-spacing: #{$button-ios-clear-letter-spacing};
--background-focused: #{ion-color(primary, base, .1)};
--color-activated: #{ion-color(primary, base)};
--color-focused: #{ion-color(primary, base)};
}
@@ -116,71 +119,29 @@
}
// iOS Button Activated
// --------------------------------------------------
:host(.button-clear.ion-activated) {
opacity: #{$button-ios-clear-opacity-activated};
}
:host(.button-outline.ion-activated.ion-color) .button-native {
color: current-color(contrast);
&::after {
background: current-color(base);
}
}
:host(.button-solid.ion-color.ion-activated) .button-native::after {
background: #{current-color(shade)};
}
// iOS Button Focused
// --------------------------------------------------
:host(.button-outline.ion-focused.ion-color) .button-native,
:host(.button-clear.ion-focused.ion-color) .button-native {
color: current-color(base);
&::after {
background: current-color(base);
}
}
:host(.button-solid.ion-color.ion-focused) .button-native::after {
background: #{current-color(shade)};
}
// iOS Button Hover
// iOS Button Focus
// --------------------------------------------------
@media (any-hover: hover) {
// Clear and outline buttons use opacity so set
// background to transparent
:host(.button-solid:hover) {
--opacity: #{$button-ios-opacity-hover};
}
:host(.button-clear:hover),
:host(.button-outline:hover) {
opacity: #{$button-ios-clear-opacity-hover};
--opacity: #{$button-ios-clear-opacity-hover};
}
:host(.button-clear.ion-color:hover) .button-native,
:host(.button-outline.ion-color:hover) .button-native {
color: #{current-color(base)};
&::after {
background: transparent;
}
// Since iOS changes the opacity on hover,
// we want to keep the background if focused
// or activated
:host(.ion-focused:hover) {
--background-hover: var(--background-focused);
--color-hover: var(--color-focused);
}
// Solid buttons use the tint background
:host(.button-solid.ion-color:hover) .button-native::after {
background: #{current-color(tint)};
}
// Solid buttons inside of a toolbar should use a tint of the current
// background so use white to tint it
:host(:hover.button-solid.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native::after {
background: #fff;
opacity: 0.10;
:host(.activated:hover) {
--background-hover: var(--background-activated);
--color-hover: var(--color-activated);
}
}

View File

@@ -153,15 +153,6 @@ $button-ios-outline-background-color-focused: ion-color(primary, base, $
// iOS Clear Button
// --------------------------------------------------
/// @prop - Font size of the clear button
$button-ios-clear-font-size: 17px !default;
/// @prop - Font weight of the clear button
$button-ios-clear-font-weight: normal !default;
/// @prop - Letter spacing of the clear button
$button-ios-clear-letter-spacing: 0 !default;
/// @prop - Border color of the clear button
$button-ios-clear-border-color: transparent !default;

View File

@@ -30,16 +30,11 @@
// --------------------------------------------------
:host(.button-solid) {
--background-activated: transparent;
--background-hover: #{ion-color(primary, contrast)};
--background-focused: #{ion-color(primary, contrast)};
--background-activated-opacity: 0;
--background-focused-opacity: .24;
--background-hover-opacity: .08;
--background-activated: var(--background);
--box-shadow: #{$button-md-box-shadow};
}
:host(.button-solid.ion-activated) {
:host(.button-solid.activated) {
--box-shadow: #{$button-md-box-shadow-activated};
}
@@ -51,14 +46,12 @@
--border-style: solid;
--box-shadow: none;
--background-activated: transparent;
--background-focused: #{ion-color(primary, base)};
--background-hover: #{ion-color(primary, base)};
--background-activated-opacity: 0;
--background-focused-opacity: .12;
--background-hover-opacity: .04;
--background-focused: #{ion-color(primary, base, .1)};
--background-hover: #{ion-color(primary, base, .04)};
--color-activated: #{ion-color(primary, base)};
}
:host(.button-outline.ion-activated.ion-color) .button-native {
:host(.button-outline.activated.ion-color) .button-native {
background: transparent;
}
@@ -68,11 +61,10 @@
:host(.button-clear) {
--background-activated: transparent;
--background-focused: #{ion-color(primary, base)};
--background-hover: #{ion-color(primary, base)};
--background-activated-opacity: 0;
--background-focused-opacity: .12;
--background-hover-opacity: .04;
--background-focused: #{ion-color(primary, base, .1)};
--background-hover: #{ion-color(primary, base, .04)};
--color-activated: #{ion-color(primary, base)};
--color-focused: #{ion-color(primary, base)};
}
@@ -129,30 +121,13 @@
// Material Design Button: Hover
// --------------------------------------------------
:host(.button-solid.ion-color.ion-focused) .button-native::after {
background: #{current-color(contrast)};
opacity: .24;
}
:host(.button-clear.ion-color.ion-focused) .button-native::after,
:host(.button-outline.ion-color.ion-focused) .button-native::after {
background: #{current-color(base)};
opacity: .12;
}
@media (any-hover: hover) {
:host(.button-solid.ion-color:hover) .button-native::after {
background: #{current-color(contrast)};
opacity: .08;
:host(.button-solid.ion-color:hover) .button-native {
background: #{current-color(tint)};
}
:host(.button-clear.ion-color:hover) .button-native::after,
:host(.button-outline.ion-color:hover) .button-native::after {
background: #{current-color(base)};
opacity: .04;
:host(.button-clear.ion-color:hover) .button-native,
:host(.button-outline.ion-color:hover) .button-native {
background: #{current-color(base, .04)};
}
}

View File

@@ -6,12 +6,9 @@
:host {
/**
* @prop --background: Background of the button
* @prop --background-activated: Background of the button when pressed. Note: setting this will interfere with the Material Design ripple.
* @prop --background-activated-opacity: Opacity of the button when pressed
* @prop --background-activated: Background of the button when pressed
* @prop --background-focused: Background of the button when focused with the tab key
* @prop --background-focused-opacity: Opacity of the button when focused with the tab key
* @prop --background-hover: Background of the button on hover
* @prop --background-hover-opacity: Opacity of the background on hover
*
* @prop --color: Text color of the button
* @prop --color-activated: Text color of the button when pressed
@@ -40,9 +37,7 @@
--border-width: initial;
--border-color: initial;
--border-style: initial;
--color-activated: var(--color);
--color-focused: var(--color);
--color-hover: var(--color);
--color-hover: initial;
--box-shadow: none;
display: inline-block;
@@ -68,8 +63,12 @@
}
:host(.button-disabled) {
--opacity: .5;
pointer-events: none;
}
:host(.button-disabled) .button-native {
cursor: default;
opacity: .5;
pointer-events: none;
}
@@ -79,7 +78,22 @@
// Default Solid Color
:host(.button-solid) {
--background: #{ion-color(primary, base)};
--background-focused: #{ion-color(primary, shade)};
--background-hover: #{ion-color(primary, tint)};
--color: #{ion-color(primary, contrast)};
--color-activated: #{ion-color(primary, contrast)};
--color-focused: #{ion-color(primary, contrast)};
}
// Solid Button with Color
:host(.button-solid.ion-color) .button-native {
background: current-color(base);
color: current-color(contrast);
}
// Focused/Activated Solid Button with Color
:host(.button-solid.ion-color.ion-focused) .button-native {
background: #{current-color(shade)};
}
@@ -91,6 +105,20 @@
--border-color: #{ion-color(primary, base)};
--background: transparent;
--color: #{ion-color(primary, base)};
--color-focused: #{ion-color(primary, base)};
}
// Outline Button with Color
:host(.button-outline.ion-color) .button-native {
border-color: current-color(base);
background: transparent;
color: current-color(base);
}
:host(.button-outline.ion-focused.ion-color) .button-native {
background: current-color(base, .1);
color: current-color(base);
}
@@ -104,6 +132,23 @@
--color: #{ion-color(primary, base)};
}
// Clear Button with Color
:host(.button-clear.ion-color) .button-native {
background: transparent;
color: current-color(base);
}
// Focused Clear Button with Color
:host(.button-clear.ion-focused.ion-color) .button-native {
background: current-color(base, .1);
color: current-color(base);
}
// Activated Clear Button with Color
:host(.button-clear.activated.ion-color) .button-native {
background: transparent;
}
// Block Button
// --------------------------------------------------
@@ -179,10 +224,8 @@
line-height: 1;
box-shadow: var(--box-shadow);
contain: layout style;
cursor: pointer;
opacity: var(--opacity);
overflow: var(--overflow);
@@ -197,7 +240,6 @@
.button-inner {
display: flex;
position: relative;
flex-flow: row nowrap;
flex-shrink: 0;
@@ -206,8 +248,6 @@
width: 100%;
height: 100%;
z-index: 1;
}
@@ -239,85 +279,22 @@ ion-ripple-effect {
color: var(--ripple-color);
}
// Button: States
// Button: Hover
// --------------------------------------------------
.button-native::after {
@include button-state();
}
// Button Activated
:host(.ion-activated) {
color: var(--color-activated);
}
:host(.ion-activated) .button-native::after {
background: var(--background-activated);
opacity: var(--background-activated-opacity);
}
// Button Focused
:host(.ion-focused) {
:host(.ion-focused) .button-native {
background: var(--background-focused);
color: var(--color-focused);
}
:host(.ion-focused) .button-native::after {
background: var(--background-focused);
opacity: var(--background-focused-opacity);
:host(.activated) .button-native {
background: var(--background-activated);
color: var(--color-activated);
}
// Button Hover
@media (any-hover: hover) {
:host(:hover) {
:host(:hover) .button-native {
background: var(--background-hover);
color: var(--color-hover);
}
:host(:hover) .button-native::after {
background: var(--background-hover);
opacity: var(--background-hover-opacity);
}
}
// Button Colors
// --------------------------------------------------
// Solid Button with Color
:host(.button-solid.ion-color) .button-native {
background: current-color(base);
color: current-color(contrast);
}
// Outline Button with Color
:host(.button-outline.ion-color) .button-native {
border-color: current-color(base);
background: transparent;
color: current-color(base);
}
// Clear Button with Color
:host(.button-clear.ion-color) .button-native {
background: transparent;
color: current-color(base);
}
// Button in Toolbar
// --------------------------------------------------
:host(.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native {
color: #{var(--ion-toolbar-color, var(--color))};
}
:host(.button-outline.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native {
border-color: #{var(--ion-toolbar-color, var(--color, var(--border-color)))};
}
:host(.button-solid.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native {
background: #{var(--ion-toolbar-color, var(--background))};
color: #{var(--ion-toolbar-background, var(--color))};
}

View File

@@ -4,7 +4,7 @@ import { getIonMode } from '../../global/ionic-global';
import { Color, RouterDirection } from '../../interface';
import { AnchorInterface, ButtonInterface } from '../../utils/element-interface';
import { hasShadowDom } from '../../utils/helpers';
import { createColorClasses, hostContext, openURL } from '../../utils/theme';
import { createColorClasses, openURL } from '../../utils/theme';
/**
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
@@ -13,9 +13,6 @@ import { createColorClasses, hostContext, openURL } from '../../utils/theme';
* @slot icon-only - Should be used on an icon in a button that has no text.
* @slot start - Content is placed to the left of the button text in LTR, and to the right in RTL.
* @slot end - Content is placed to the right of the button text in LTR, and to the left in RTL.
*
* @TODOpart button - The native button or anchor tag that is rendered.
* @TODOpart button-inner - The span inside of the native button or anchor.
*/
@Component({
tag: 'ion-button',
@@ -26,9 +23,9 @@ import { createColorClasses, hostContext, openURL } from '../../utils/theme';
shadow: true,
})
export class Button implements ComponentInterface, AnchorInterface, ButtonInterface {
private inItem = false;
private inListHeader = false;
private inToolbar = false;
private inItem = false;
@Element() el!: HTMLElement;
@@ -127,7 +124,6 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
componentWillLoad() {
this.inToolbar = !!this.el.closest('ion-buttons');
this.inListHeader = !!this.el.closest('ion-list-header');
this.inItem = !!this.el.closest('ion-item') || !!this.el.closest('ion-item-divider');
}
@@ -193,7 +189,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
let fill = this.fill;
if (fill === undefined) {
fill = this.inToolbar || this.inListHeader ? 'clear' : 'solid';
fill = this.inToolbar ? 'clear' : 'solid';
}
return (
<Host
@@ -208,8 +204,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
[`${buttonType}-${shape}`]: shape !== undefined,
[`${buttonType}-${fill}`]: true,
[`${buttonType}-strong`]: strong,
'in-toolbar': hostContext('ion-toolbar', this.el),
'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
'button-has-icon-only': hasIconOnly,
'button-disabled': disabled,
'ion-activatable': true,
@@ -222,9 +217,8 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
disabled={disabled}
onFocus={this.onFocus}
onBlur={this.onBlur}
part="button"
>
<span class="button-inner" part="button-inner">
<span class="button-inner">
<slot name="icon-only"></slot>
<slot name="start"></slot>
<slot></slot>

View File

@@ -97,7 +97,6 @@ This attribute specifies the size of the button. Setting this attribute will cha
import React from 'react';
import { IonButton, IonIcon, IonContent } from '@ionic/react';
import { star } from 'ionicons/icons';
export const ButtonExample: React.FC = () => (
<IonContent>
@@ -132,17 +131,17 @@ export const ButtonExample: React.FC = () => (
{/*-- Icons --*/}
<IonButton>
<IonIcon slot="start" icon={star} />
<IonIcon slot="start" name="star" />
Left Icon
</IonButton>
<IonButton>
Right Icon
<IonIcon slot="end" icon={star} />
<IonIcon slot="end" name="star" />
</IonButton>
<IonButton>
<IonIcon slot="icon-only" icon={star} />
<IonIcon slot="icon-only" name="star" />
</IonButton>
{/*-- Sizes --*/}
@@ -253,31 +252,28 @@ export const ButtonExample: React.FC = () => (
## CSS Custom Properties
| Name | Description |
| -------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `--background` | Background of the button |
| `--background-activated` | Background of the button when pressed. Note: setting this will interfere with the Material Design ripple. |
| `--background-activated-opacity` | Opacity of the button when pressed |
| `--background-focused` | Background of the button when focused with the tab key |
| `--background-focused-opacity` | Opacity of the button when focused with the tab key |
| `--background-hover` | Background of the button on hover |
| `--background-hover-opacity` | Opacity of the background on hover |
| `--border-color` | Border color of the button |
| `--border-radius` | Border radius of the button |
| `--border-style` | Border style of the button |
| `--border-width` | Border width of the button |
| `--box-shadow` | Box shadow of the button |
| `--color` | Text color of the button |
| `--color-activated` | Text color of the button when pressed |
| `--color-focused` | Text color of the button when focused with the tab key |
| `--color-hover` | Text color of the button when hover |
| `--opacity` | Opacity of the button |
| `--padding-bottom` | Bottom padding of the button |
| `--padding-end` | Right padding if direction is left-to-right, and left padding if direction is right-to-left of the button |
| `--padding-start` | Left padding if direction is left-to-right, and right padding if direction is right-to-left of the button |
| `--padding-top` | Top padding of the button |
| `--ripple-color` | Color of the button ripple effect |
| `--transition` | Transition of the button |
| Name | Description |
| ------------------------ | --------------------------------------------------------------------------------------------------------- |
| `--background` | Background of the button |
| `--background-activated` | Background of the button when pressed |
| `--background-focused` | Background of the button when focused with the tab key |
| `--background-hover` | Background of the button on hover |
| `--border-color` | Border color of the button |
| `--border-radius` | Border radius of the button |
| `--border-style` | Border style of the button |
| `--border-width` | Border width of the button |
| `--box-shadow` | Box shadow of the button |
| `--color` | Text color of the button |
| `--color-activated` | Text color of the button when pressed |
| `--color-focused` | Text color of the button when focused with the tab key |
| `--color-hover` | Text color of the button when hover |
| `--opacity` | Opacity of the button |
| `--padding-bottom` | Bottom padding of the button |
| `--padding-end` | Right padding if direction is left-to-right, and left padding if direction is right-to-left of the button |
| `--padding-start` | Left padding if direction is left-to-right, and right padding if direction is right-to-left of the button |
| `--padding-top` | Top padding of the button |
| `--ripple-color` | Color of the button ripple effect |
| `--transition` | Transition of the button |
## Dependencies

View File

@@ -23,43 +23,43 @@
<ion-content class="ion-padding" id="content" no-bounce>
<p>
<ion-button href="#">Default</ion-button>
<ion-button href="#" class="ion-activated">Default.activated</ion-button>
<ion-button href="#" class="activated">Default.activated</ion-button>
</p>
<p>
<ion-button href="#" color="primary">Primary</ion-button>
<ion-button href="#" class="ion-activated" color="primary">Primary.activated</ion-button>
<ion-button href="#" class="activated" color="primary">Primary.activated</ion-button>
</p>
<p>
<ion-button href="#" color="secondary">Secondary</ion-button>
<ion-button href="#" class="ion-activated" color="secondary">Secondary.activated</ion-button>
<ion-button href="#" class="activated" color="secondary">Secondary.activated</ion-button>
</p>
<p>
<ion-button href="#" color="tertiary">Tertiary</ion-button>
<ion-button href="#" class="ion-activated" color="tertiary">Tertiary.activated</ion-button>
<ion-button href="#" class="activated" color="tertiary">Tertiary.activated</ion-button>
</p>
<p>
<ion-button href="#" color="success">Success</ion-button>
<ion-button href="#" class="ion-activated" color="success">Success.activated</ion-button>
<ion-button href="#" class="activated" color="success">Success.activated</ion-button>
</p>
<p>
<ion-button href="#" color="warning">Warning</ion-button>
<ion-button href="#" class="ion-activated" color="warning">Warning.activated</ion-button>
<ion-button href="#" class="activated" color="warning">Warning.activated</ion-button>
</p>
<p>
<ion-button href="#" color="danger">Danger</ion-button>
<ion-button href="#" class="ion-activated" color="danger">Danger.activated</ion-button>
<ion-button href="#" class="activated" color="danger">Danger.activated</ion-button>
</p>
<p>
<ion-button href="#" color="light">Light</ion-button>
<ion-button href="#" class="ion-activated" color="light">Light.activated</ion-button>
<ion-button href="#" class="activated" color="light">Light.activated</ion-button>
</p>
<p>
<ion-button href="#" color="medium">Medium</ion-button>
<ion-button href="#" class="ion-activated" color="medium">Medium.activated</ion-button>
<ion-button href="#" class="activated" color="medium">Medium.activated</ion-button>
</p>
<p>
<ion-button href="#" color="dark">Dark</ion-button>
<ion-button href="#" class="ion-activated" color="dark">Dark.activated</ion-button>
<ion-button href="#" class="activated" color="dark">Dark.activated</ion-button>
</p>
<p>
<ion-button href="#" disabled>Disabled</ion-button>

View File

@@ -24,61 +24,61 @@
<p>
<ion-button>Default</ion-button>
<ion-button class="ion-focused">Default.focused</ion-button>
<ion-button class="ion-activated">Default.activated</ion-button>
<ion-button class="activated">Default.activated</ion-button>
</p>
<p>
<ion-button color="primary">Primary</ion-button>
<ion-button class="ion-focused" color="primary">Primary.focused</ion-button>
<ion-button class="ion-activated" color="primary">Primary.activated</ion-button>
<ion-button class="activated" color="primary">Primary.activated</ion-button>
</p>
<p>
<ion-button color="secondary">Secondary</ion-button>
<ion-button class="ion-focused" color="secondary">Secondary.focused</ion-button>
<ion-button class="ion-activated" color="secondary">Secondary.activated</ion-button>
<ion-button class="activated" color="secondary">Secondary.activated</ion-button>
</p>
<p>
<ion-button color="tertiary">Tertiary</ion-button>
<ion-button class="ion-focused" color="tertiary">Tertiary.focused</ion-button>
<ion-button class="ion-activated" color="tertiary">Tertiary.activated</ion-button>
<ion-button class="activated" color="tertiary">Tertiary.activated</ion-button>
</p>
<p>
<ion-button color="success">Success</ion-button>
<ion-button class="ion-focused" color="success">Success.focused</ion-button>
<ion-button class="ion-activated" color="success">Success.activated</ion-button>
<ion-button class="activated" color="success">Success.activated</ion-button>
</p>
<p>
<ion-button color="warning">Warning</ion-button>
<ion-button class="ion-focused" color="warning">Warning.focused</ion-button>
<ion-button class="ion-activated" color="warning">Warning.activated</ion-button>
<ion-button class="activated" color="warning">Warning.activated</ion-button>
</p>
<p>
<ion-button color="danger">Danger</ion-button>
<ion-button class="ion-focused" color="danger">Danger.focused</ion-button>
<ion-button class="ion-activated" color="danger">Danger.activated</ion-button>
<ion-button class="activated" color="danger">Danger.activated</ion-button>
</p>
<p>
<ion-button color="light">Light</ion-button>
<ion-button class="ion-focused" color="light">Light.focused</ion-button>
<ion-button class="ion-activated" color="light">Light.activated</ion-button>
<ion-button class="activated" color="light">Light.activated</ion-button>
</p>
<p>
<ion-button color="medium">Medium</ion-button>
<ion-button class="ion-focused" color="medium">Medium.focused</ion-button>
<ion-button class="ion-activated" color="medium">Medium.activated</ion-button>
<ion-button class="activated" color="medium">Medium.activated</ion-button>
</p>
<p>
<ion-button color="dark">Dark</ion-button>
<ion-button class="ion-focused" color="dark">Dark.focused</ion-button>
<ion-button class="ion-activated" color="dark">Dark.activated</ion-button>
<ion-button class="activated" color="dark">Dark.activated</ion-button>
</p>
<p>

View File

@@ -23,72 +23,72 @@
<ion-content class="ion-padding" id="content" no-bounce>
<p>
<ion-button fill="clear">Default</ion-button>
<ion-button fill="clear" class="ion-activated">Default.activated</ion-button>
<ion-button fill="clear" class="activated">Default.activated</ion-button>
<ion-button fill="clear" class="ion-focused">Default.focused</ion-button>
<ion-button fill="clear" class="ion-activated ion-focused">Default.activated.focused</ion-button>
<ion-button fill="clear" class="activated ion-focused">Default.activated.focused</ion-button>
</p>
<p>
<ion-button fill="clear" color="primary">Primary</ion-button>
<ion-button fill="clear" class="ion-activated" color="primary">Primary.activated</ion-button>
<ion-button fill="clear" class="activated" color="primary">Primary.activated</ion-button>
<ion-button fill="clear" class="ion-focused" color="primary">Primary.focused</ion-button>
<ion-button fill="clear" class="ion-activated ion-focused" color="primary">Primary.activated.focused</ion-button>
<ion-button fill="clear" class="activated ion-focused" color="primary">Primary.activated.focused</ion-button>
</p>
<p>
<ion-button fill="clear" color="secondary">Secondary</ion-button>
<ion-button fill="clear" class="ion-activated" color="secondary">Secondary.activated</ion-button>
<ion-button fill="clear" class="activated" color="secondary">Secondary.activated</ion-button>
<ion-button fill="clear" class="ion-focused" color="secondary">Secondary.focused</ion-button>
<ion-button fill="clear" class="ion-activated ion-focused" color="secondary">Secondary.activated.focused</ion-button>
<ion-button fill="clear" class="activated ion-focused" color="secondary">Secondary.activated.focused</ion-button>
</p>
<p>
<ion-button fill="clear" color="tertiary">Tertiary</ion-button>
<ion-button fill="clear" class="ion-activated" color="tertiary">Tertiary.activated</ion-button>
<ion-button fill="clear" class="activated" color="tertiary">Tertiary.activated</ion-button>
<ion-button fill="clear" class="ion-focused" color="tertiary">Tertiary.focused</ion-button>
<ion-button fill="clear" class="ion-activated ion-focused" color="tertiary">Tertiary.activated.focused</ion-button>
<ion-button fill="clear" class="activated ion-focused" color="tertiary">Tertiary.activated.focused</ion-button>
</p>
<p>
<ion-button fill="clear" color="success">Success</ion-button>
<ion-button fill="clear" class="ion-activated" color="success">Success.activated</ion-button>
<ion-button fill="clear" class="activated" color="success">Success.activated</ion-button>
<ion-button fill="clear" class="ion-focused" color="success">Success.focused</ion-button>
<ion-button fill="clear" class="ion-activated ion-focused" color="success">Success.activated.focused</ion-button>
<ion-button fill="clear" class="activated ion-focused" color="success">Success.activated.focused</ion-button>
</p>
<p>
<ion-button fill="clear" color="warning">Warning</ion-button>
<ion-button fill="clear" class="ion-activated" color="warning">Warning.activated</ion-button>
<ion-button fill="clear" class="activated" color="warning">Warning.activated</ion-button>
<ion-button fill="clear" class="ion-focused" color="warning">Warning.focused</ion-button>
<ion-button fill="clear" class="ion-activated ion-focused" color="warning">Warning.activated.focused</ion-button>
<ion-button fill="clear" class="activated ion-focused" color="warning">Warning.activated.focused</ion-button>
</p>
<p>
<ion-button fill="clear" color="danger">Danger</ion-button>
<ion-button fill="clear" class="ion-activated" color="danger">Danger.activated</ion-button>
<ion-button fill="clear" class="activated" color="danger">Danger.activated</ion-button>
<ion-button fill="clear" class="ion-focused" color="danger">Danger.focused</ion-button>
<ion-button fill="clear" class="ion-activated ion-focused" color="danger">Danger.activated.focused</ion-button>
<ion-button fill="clear" class="activated ion-focused" color="danger">Danger.activated.focused</ion-button>
</p>
<p>
<ion-button fill="clear" color="light">Light</ion-button>
<ion-button fill="clear" class="ion-activated" color="light">Light.activated</ion-button>
<ion-button fill="clear" class="activated" color="light">Light.activated</ion-button>
<ion-button fill="clear" class="ion-focused" color="light">Light.focused</ion-button>
<ion-button fill="clear" class="ion-activated ion-focused" color="light">Light.activated.focused</ion-button>
<ion-button fill="clear" class="activated ion-focused" color="light">Light.activated.focused</ion-button>
</p>
<p>
<ion-button fill="clear" color="medium">Medium</ion-button>
<ion-button fill="clear" class="ion-activated" color="medium">Medium.activated</ion-button>
<ion-button fill="clear" class="activated" color="medium">Medium.activated</ion-button>
<ion-button fill="clear" class="ion-focused" color="medium">Medium.focused</ion-button>
<ion-button fill="clear" class="ion-activated ion-focused" color="medium">Medium.activated.focused</ion-button>
<ion-button fill="clear" class="activated ion-focused" color="medium">Medium.activated.focused</ion-button>
</p>
<p>
<ion-button fill="clear" color="dark">Dark</ion-button>
<ion-button fill="clear" class="ion-activated" color="dark">Dark.activated</ion-button>
<ion-button fill="clear" class="activated" color="dark">Dark.activated</ion-button>
<ion-button fill="clear" class="ion-focused" color="dark">Dark.focused</ion-button>
<ion-button fill="clear" class="ion-activated ion-focused" color="dark">Dark.activated.focused</ion-button>
<ion-button fill="clear" class="activated ion-focused" color="dark">Dark.activated.focused</ion-button>
</p>
<p>
<ion-button fill="clear" disabled>Disabled</ion-button>

Some files were not shown because too many files have changed in this diff Show More