Compare commits

..

34 Commits

Author SHA1 Message Date
Liam DeBeasi
674bfeb0c8 add wip 2024-04-19 09:46:44 -04:00
Brandy Carney
6b13e1323f test: remove hardcoded dark palette from tests (#29357)
Issue number: N/A

---------

## What is the current behavior?
Dark palette is hardcoded in style tags in tests. 

## What is the new behavior?

Updated the following tests:
- **datetime/basic** - added an import for `dark.class.css` which works
with the checkbox to toggle the `ion-palette-dark` class
- does not update the e2e test to include dark palette because this was
not tested previously
- **datetime/color** - added an import for `dark.class.css` which works
with the checkbox to toggle the `ion-palette-dark` class
    - updates the e2e test to use the dark palette
- **modal/dark-mode** - added an import for `dark.always.css` which
always applies the dark palette
- does not update the e2e test to include dark palette because this test
needs to be moved but I am not sure where it should go yet
- **toggle/enable-on-off-labels** - added an import for `dark.class.css`
which works with the checkbox to toggle the `ion-palette-dark` class
- updates the e2e test to use the dark palette & splits the color into a
separate screenshot test

Did not update the following tests:
- **item/buttons** - has already been updated to remove the dark palette
- **toggle/legacy/enable-on-off-labels** - test was removed in v8

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

## Other information

- We could probably remove the checkbox toggles entirely when we add
support for the `palette` query param.

---------

Co-authored-by: ionitron <hi@ionicframework.com>
2024-04-17 19:46:48 +00:00
Liam DeBeasi
eb7ba2355a chore: update issue assignment list (#29356)
This PR revises the list of who gets automatically assigned to issues.
2024-04-17 17:32:14 +00:00
Liam DeBeasi
30552f1cef merge release-8.0.0 (#29352) 2024-04-17 10:03:58 -04:00
ionitron
2d8c9f4942 chore(): update package lock files 2024-04-17 13:52:16 +00:00
ionitron
bf1ae7b6fe v8.0.0 2024-04-17 13:51:23 +00:00
Liam DeBeasi
84ea30db4e merge release-8.0.0.rc.2 (#29351) 2024-04-17 09:42:58 -04:00
Liam DeBeasi
f7aa4a7e6b chore: clean up changelog 2024-04-17 09:32:04 -04:00
ionitron
ffd1bf5139 chore(): update package lock files 2024-04-17 13:27:46 +00:00
ionitron
73af759906 v8.0.0-rc.2 2024-04-17 13:27:08 +00:00
Liam DeBeasi
4f68044f84 chore: sync with main (#29349) 2024-04-17 09:19:23 -04:00
Liam DeBeasi
c69adbf988 merge release-7.8.5 (#29348) 2024-04-17 09:11:01 -04:00
Liam DeBeasi
cde84983b2 chore: sync with main 2024-04-17 09:08:24 -04:00
ionitron
3f3f196a24 chore(): update package lock files 2024-04-17 13:01:00 +00:00
ionitron
ffce443585 v7.8.5 2024-04-17 12:59:14 +00:00
Liam DeBeasi
4698d22413 fix(dark-palette): improve base colors (#29239)
Issue number: resolves #29219

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->

We got feedback that the current dark theme is a bit jarring when
compared with native. In particular, devs are expecting the contrast to
be white for many of these colors to match native iOS. Currently, text
inside of a primary button is black on dark mode, but devs expect it to
be white. Additionally, the dark mode colors appear to be too washed out
when compared with their light mode counterparts.

The team discussed this and we think we can find a way to make the
colors more in line with what devs expect while still allowing for AA
color contrast levels.

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

- Adjusted the secondary and danger colors to be slightly more
vibrant/inline with what developers expect in mobile apps while still
meeting AA color contrast.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!--
  If this introduces a breaking change:
1. Describe the impact and migration path for existing applications
below.
  2. Update the BREAKING.md file with the breaking change.
3. Add "BREAKING CHANGE: [...]" to the commit description when merging.
See
https://github.com/ionic-team/ionic-framework/blob/main/.github/CONTRIBUTING.md#footer
for more information.
-->


## Other information

I intentionally did not change the contrast color, and I intentionally
did not significantly change the vibrancy of each color token. I did
some research into how the native platforms handle colors. I'll place
this information here, because there are some subtle differences between
web and native that make a difference.

### Material Design


[Source](https://m2.material.io/design/color/dark-theme.html#ui-application)

Material Design 2 calls for desaturated color tokens as well as flipping
contrast colors. For example, a vibrant purple background with light
text on light mode is a washed purple with dark text on dark mode. The
colors in Ionic <=7 did not follow these patterns. The tokens in Ionic 8
now follows these patterns, so what we have in `main` means we are
aligning closer with native MD than have in the past.


![image](https://github.com/ionic-team/ionic-framework/assets/2721089/b1067e7c-ee51-4170-91b1-27c0753fae72)

### iOS


[Source](https://developer.apple.com/design/human-interface-guidelines/accessibility#Color-and-effects)

iOS is a bit tricky. On the docs, Apple references the WCAG color
contrast formula (what Ionic follows). However, the table they present
below is slightly different:

| Text Size | Text Weight | Minimum Contrast Ratio |
| - | - | - |
| Up to 17 points | All | 4.5:1 |
| 18 points and larger | All | 3:1 |
| All | Bold | 3:1 |

The last row is the main difference. WCAG states that text that is bold
AND >=14pts (~18.66px) needs to meet a minimum contrast ratio of 3:1.
Apple's guidelines state that any text that is bold (regardless of size)
needs to meet a minimum contrast ratio of 3:1. In other words, **Apple
is using different guidelines to choose colors which is why colored dark
mode buttons on iOS typically use white text**.

However, Apple is inconsistent in implementing its own guidelines.
Consider the following red buttons in the Apple Music app.

| Screenshot | Meets Web guidelines | Meets Apple guidelines | Notes |
| - | - | - | - |
| <img
src="https://github.com/ionic-team/ionic-framework/assets/2721089/6bb0e0b3-c29e-4b96-9ad5-e45e59bf0415"
width="300" /> |  |  | Text is not bold which makes it not meet either
guidelines. |
| <img
src="https://github.com/ionic-team/ionic-framework/assets/2721089/8ce93b45-0b2b-4160-97a4-19852134684c"
width="300" /> |  |  | Text is bold which makes it pass the Apple
guidelines, but it's still too small to also pass the Web guidelines. |

### Ionic

One of the things I tried is adjusting the base color to work well with
white and black backgrounds. It's common to have a blue background with
white text (such as a button) AND to have a blue link on a black
background (such as an `a` element). This approach does not work well
for the shade/tint colors used for hover/focus states. These colors also
need to meet Web guidelines.

Consider the following example:

| Screenshot | Notes | Text/Link passes AA guidelines | Tint passes AA
guidelines |
| - | - | - | - |
| ![Screenshot 2024-04-15 at 3 28
47 PM](https://github.com/ionic-team/ionic-framework/assets/2721089/3d8c56a6-6d0c-4c93-bc13-9c93508f76bc)
| This uses the same primary color found in the light palette |  |  |
| ![Screenshot 2024-04-15 at 3 29
21 PM](https://github.com/ionic-team/ionic-framework/assets/2721089/beaf26c9-c30f-4a39-900e-74b0f2433280)
| This changes the base color such that the Text/Link passes with a
4.5:1 ratio |  |  |
| ![Screenshot 2024-04-15 at 3 34
14 PM](https://github.com/ionic-team/ionic-framework/assets/2721089/43dbd81c-1338-4fff-af30-efbe51fce08a)
| This changes the base color such that the Tint passes with a 4:5:1
ratio |  |  |

We also considered adjusting the `a` and `ion-text` colors to use the
tint color. We decided against that because it a) felt a little odd
given that tint is typically used for states (hover, focus, etc) and b)
we were concerned that making this change would impose future
restrictions on how this color palette can evolve.

### Conclusion

While Ionic's colors don't exactly match the iOS colors, the reality is
that we are a web-based tool, so we are going to be evaluated using
web-based tools/standards. As a result, it's recommended that we align
closer with the Web guidelines than Apple's guidelines.

## Testing

Testing:

Developers can look at the colors by opening
http://localhost:3333/src/themes/test/colors

In the video below, the first state is the dark theme in `main`. The
second state is the proposed changes.
| Visual Comparison |
| - |
| <video
src="https://github.com/ionic-team/ionic-framework/assets/2721089/241fb1b6-212b-4f03-83cd-9558b9a53761"></video>
|
2024-04-15 17:00:36 -04:00
Liam DeBeasi
bfaf528e61 docs(test): clarify docker usage for windows (#29274)
Team members on Windows were having trouble running tests inside of
Docker. Given that headed tests must use WSL, I think it makes sense to
have Windows devs use WSL for any E2E tests run inside of Docker. That
way they aren't switching back and forth between shells.

This PR clarifies the Docker docs that instruct devs on how to use WSL.
2024-04-15 17:46:17 +00:00
Brandy Carney
9b59138011 fix(form-controls): adjust flex properties inside of an item (#29328)
Issue number: resolves #29319

---------

## What is the current behavior?
Icons (not slotted) alongside a checkbox, toggle, or radio in an item
using the modern syntax cause the icon to shrink in width.

## What is the new behavior?
Allow the checkbox, toggle, and radio to shrink to accommodate the icon.
This matches the select behavior:
f0da2c1727/core/src/components/select/select.scss (L84)

| Before | After |
| --- | --- |
|
![before](https://github.com/ionic-team/ionic-framework/assets/6577830/ca32e2a7-ee10-427e-b060-3c554e9e7fec)
|
![after](https://github.com/ionic-team/ionic-framework/assets/6577830/8be2d918-0caa-4b7a-8fc7-a57456307a84)
|

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

---------

Co-authored-by: ionitron <hi@ionicframework.com>
2024-04-12 11:36:05 -04:00
renovate[bot]
4efdc88a29 chore(deps): update dependency @stencil/core to v4.15.0 (#29332)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@stencil/core](https://stenciljs.com/)
([source](https://togithub.com/ionic-team/stencil)) | [`4.14.1` ->
`4.15.0`](https://renovatebot.com/diffs/npm/@stencil%2fcore/4.14.1/4.15.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@stencil%2fcore/4.15.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@stencil%2fcore/4.15.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@stencil%2fcore/4.14.1/4.15.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@stencil%2fcore/4.14.1/4.15.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>ionic-team/stencil (@&#8203;stencil/core)</summary>

###
[`v4.15.0`](https://togithub.com/ionic-team/stencil/blob/HEAD/CHANGELOG.md#-4150-2024-04-08)

[Compare
Source](https://togithub.com/ionic-team/stencil/compare/v4.14.1...v4.15.0)

##### Features

- **compiler:** perform automatic key insertion in more situations
([#&#8203;5594](https://togithub.com/ionic-team/stencil/issues/5594))
([8ee071b](8ee071bf3a))
- **typescript:** Update dependency typescript to v5.4.4
([#&#8203;5636](https://togithub.com/ionic-team/stencil/issues/5636))
([a463871](a463871230))

#### 🏋
[4.14.1](https://togithub.com/ionic-team/stencil/compare/v4.14.0...v4.14.1)
(2024-04-04)

##### Bug Fixes

- **compiler:** don't mistake aliased paths for collections imports
([#&#8203;5620](https://togithub.com/ionic-team/stencil/issues/5620))
([af22bb8](af22bb858d)),
closes
[#&#8203;2319](https://togithub.com/ionic-team/stencil/issues/2319)
- **runtime:** nested multiple default slot relocation
([#&#8203;5403](https://togithub.com/ionic-team/stencil/issues/5403))
([363c07b](363c07b472)),
partially closes
[#&#8203;5335](https://togithub.com/ionic-team/stencil/issues/5335)
- **runtime:** prevent ref callbacks from being called too early
([#&#8203;5614](https://togithub.com/ionic-team/stencil/issues/5614))
([81fa375](81fa37587e)),
closes
[#&#8203;4074](https://togithub.com/ionic-team/stencil/issues/4074)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "every weekday before 11am" (UTC),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Never, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/ionic-team/ionic-framework).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4yNjkuMiIsInVwZGF0ZWRJblZlciI6IjM3LjI2OS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiJ9-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-12 14:39:54 +00:00
renovate[bot]
7b90025d31 chore(deps): update pozil/auto-assign-issue action to v1.14.0 (#29293)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[pozil/auto-assign-issue](https://togithub.com/pozil/auto-assign-issue)
| action | minor | `v1.13.0` -> `v1.14.0` |

---

### Release Notes

<details>
<summary>pozil/auto-assign-issue (pozil/auto-assign-issue)</summary>

###
[`v1.14.0`](https://togithub.com/pozil/auto-assign-issue/releases/tag/v1.14.0):
- Random assignments with weights

[Compare
Source](https://togithub.com/pozil/auto-assign-issue/compare/v1.13.0...v1.14.0)

- feat: support for weights in random assignments (addresses
[#&#8203;120](https://togithub.com/pozil/auto-assign-issue/issues/120))
-   build: bumped dependencies

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "every weekday before 11am" (UTC),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Never, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/ionic-team/ionic-framework).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4yNjkuMiIsInVwZGF0ZWRJblZlciI6IjM3LjI2OS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiJ9-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-10 21:41:10 +00:00
Liam DeBeasi
176bb43262 chore(ci): ignore images when uploading to vercel (#29310)
As part of the Vercel flow for creating public previews of the test
files, we'd like to exclude screenshots from being downloaded as they
are not required to create the previews.
2024-04-10 21:04:57 +00:00
renovate[bot]
c9916ff4b5 chore(deps): update dependency @stencil/core to v4.14.1 (#29301)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@stencil/core](https://stenciljs.com/)
([source](https://togithub.com/ionic-team/stencil)) | [`4.14.0` ->
`4.14.1`](https://renovatebot.com/diffs/npm/@stencil%2fcore/4.14.0/4.14.1)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@stencil%2fcore/4.14.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@stencil%2fcore/4.14.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@stencil%2fcore/4.14.0/4.14.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@stencil%2fcore/4.14.0/4.14.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>ionic-team/stencil (@&#8203;stencil/core)</summary>

###
[`v4.14.1`](https://togithub.com/ionic-team/stencil/blob/HEAD/CHANGELOG.md#-4141-2024-04-04)

[Compare
Source](https://togithub.com/ionic-team/stencil/compare/v4.14.0...v4.14.1)

##### Bug Fixes

- **compiler:** don't mistake aliased paths for collections imports
([#&#8203;5620](https://togithub.com/ionic-team/stencil/issues/5620))
([af22bb8](af22bb858d)),
closes
[#&#8203;2319](https://togithub.com/ionic-team/stencil/issues/2319)
- **runtime:** nested multiple default slot relocation
([#&#8203;5403](https://togithub.com/ionic-team/stencil/issues/5403))
([363c07b](363c07b472)),
partially closes
[#&#8203;5335](https://togithub.com/ionic-team/stencil/issues/5335)
- **runtime:** prevent ref callbacks from being called too early
([#&#8203;5614](https://togithub.com/ionic-team/stencil/issues/5614))
([81fa375](81fa37587e)),
closes
[#&#8203;4074](https://togithub.com/ionic-team/stencil/issues/4074)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "every weekday before 11am" (UTC),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Never, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/ionic-team/ionic-framework).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4yNjkuMiIsInVwZGF0ZWRJblZlciI6IjM3LjI2OS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiJ9-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-10 18:28:11 +00:00
Liam DeBeasi
9738228bc0 fix(modal): improve sheet modal scrolling and gesture behavior (#29312)
Issue number: resolves #24583

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->

See
https://github.com/ionic-team/ionic-framework/issues/24583#issuecomment-2033478601

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

- See https://github.com/ionic-team/ionic-framework/pull/29260 and
https://github.com/ionic-team/ionic-framework/pull/29259. This PR is a
combination of previously reviewed fixes.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!--
  If this introduces a breaking change:
1. Describe the impact and migration path for existing applications
below.
  2. Update the BREAKING.md file with the breaking change.
3. Add "BREAKING CHANGE: [...]" to the commit description when merging.
See
https://github.com/ionic-team/ionic-framework/blob/main/docs/CONTRIBUTING.md#footer
for more information.
-->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->


Dev build: `7.8.3-dev.11712695191.1d7ec370`
2024-04-10 17:24:54 +00:00
Liam DeBeasi
f0da2c1727 merge release-8.0.0-rc.1 (#29317) 2024-04-10 10:36:57 -04:00
Liam DeBeasi
368fb2fc70 chore: add correct links 2024-04-10 10:19:11 -04:00
Liam DeBeasi
8259cd0cd9 chore: clean up changelog 2024-04-10 10:18:14 -04:00
ionitron
638ad30b59 chore(): update package lock files 2024-04-10 14:12:43 +00:00
ionitron
ea8e220861 v8.0.0-rc.1 2024-04-10 14:11:56 +00:00
Liam DeBeasi
8ee5790d1f chore: sync with main (#29316) 2024-04-10 10:04:35 -04:00
Liam DeBeasi
2562392a62 chore: push vue package changes 2024-04-10 09:53:53 -04:00
Liam DeBeasi
d8599b3282 chore: sync with main 2024-04-10 09:50:08 -04:00
Liam DeBeasi
1388014b65 merge release-7.8.4 (#29314) 2024-04-10 09:45:06 -04:00
ionitron
1073d22b56 chore(): update package lock files 2024-04-10 13:34:52 +00:00
ionitron
cea0b493fc v7.8.4 2024-04-10 13:34:07 +00:00
509 changed files with 3018 additions and 9280 deletions

View File

@@ -29,4 +29,4 @@ runs:
with:
name: ionic-core
output: core/CoreBuild.zip
paths: core/dist core/components core/src/foundations core/css core/hydrate core/loader core/src/components.d.ts
paths: core/dist core/components core/css core/hydrate core/loader core/src/components.d.ts

View File

@@ -31,4 +31,4 @@ runs:
with:
name: ionic-core
output: core/CoreBuild.zip
paths: core/dist core/components core/src/foundations core/css core/hydrate core/loader core/src/components.d.ts core/api.txt
paths: core/dist core/components core/css core/hydrate core/loader core/src/components.d.ts core/api.txt

View File

@@ -11,8 +11,8 @@ jobs:
issues: write
steps:
- name: 'Auto-assign issue'
uses: pozil/auto-assign-issue@edee9537367a8fbc625d27f9e10aa8bad47b8723 # v1.13.0
uses: pozil/auto-assign-issue@65947009a243e6b3993edeef4e64df3ca85d760c # v1.14.0
with:
assignees: liamdebeasi, sean-perkins, brandyscarney, amandaejohnston, thetaPC
assignees: liamdebeasi, sean-perkins, brandyscarney, thetaPC
numOfAssignee: 1
allowSelfAssign: false

1
.vercelignore Normal file
View File

@@ -0,0 +1 @@
core/src/components/**/*/*.png

View File

@@ -3,6 +3,58 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [8.0.0](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-rc.2...v8.0.0) (2024-04-17)
**Note:** Version bump only for package ionic-framework
# [8.0.0-rc.2](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-rc.1...v8.0.0-rc.2) (2024-04-17)
### Bug Fixes
* **dark-palette:** improve base colors ([#29239](https://github.com/ionic-team/ionic-framework/issues/29239)) ([4698d22](https://github.com/ionic-team/ionic-framework/commit/4698d22413966b59f9fa65b4e2533695cf00ed70)), closes [#29219](https://github.com/ionic-team/ionic-framework/issues/29219)
* **form-controls:** adjust flex properties inside of an item ([#29328](https://github.com/ionic-team/ionic-framework/issues/29328)) ([9b59138](https://github.com/ionic-team/ionic-framework/commit/9b59138011fd1e71def209ec3a43fb7f91b58949)), closes [#29319](https://github.com/ionic-team/ionic-framework/issues/29319)
## [7.8.5](https://github.com/ionic-team/ionic-framework/compare/v7.8.4...v7.8.5) (2024-04-17)
### Bug Fixes
* **modal:** improve sheet modal scrolling and gesture behavior ([#29312](https://github.com/ionic-team/ionic-framework/issues/29312)) ([9738228](https://github.com/ionic-team/ionic-framework/commit/9738228bc05abe3e2012e57b0e6b85f0ec06f66b)), closes [#24583](https://github.com/ionic-team/ionic-framework/issues/24583)
# [8.0.0-rc.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-rc.0...v8.0.0-rc.1) (2024-04-10)
### Bug Fixes
* **button:** use clamp for font sizes on circle shape ([#29200](https://github.com/ionic-team/ionic-framework/issues/29200)) ([4d6edee](https://github.com/ionic-team/ionic-framework/commit/4d6edee89c7bb2cb669d67730d7ddf24c78b3cb1))
## [7.8.4](https://github.com/ionic-team/ionic-framework/compare/v7.8.3...v7.8.4) (2024-04-10)
### Performance Improvements
* **styles:** compress distributed global stylesheets ([#29275](https://github.com/ionic-team/ionic-framework/issues/29275)) ([b3cd49b](https://github.com/ionic-team/ionic-framework/commit/b3cd49bf2219aacffc1ac34acbae7c76ef243765))
## [7.8.3](https://github.com/ionic-team/ionic-framework/compare/v7.8.2...v7.8.3) (2024-04-03)

View File

@@ -23,10 +23,10 @@ rules:
at-rule-empty-line-before:
- always
- except:
- blockless-after-blockless
- first-nested
- blockless-after-blockless
- first-nested
ignore:
- after-comment
- after-comment
block-closing-brace-newline-before:
- always
@@ -40,13 +40,14 @@ rules:
custom-property-empty-line-before:
- always
- except:
- after-comment
- after-custom-property
- first-nested
- after-comment
- after-custom-property
- first-nested
declaration-no-important:
- true
order/order:
- custom-properties
- dollar-variables
@@ -56,212 +57,216 @@ rules:
# https://github.com/sasstools/sass-lint/blob/develop/lib/config/property-sort-orders/smacss.yml
order/properties-order:
# Box
- emptyLineBefore: always
properties:
- display
- position
- top
- right
- bottom
- left
- display
- position
- top
- right
- bottom
- left
- emptyLineBefore: always
properties:
- flex
- flex-basis
- flex-direction
- flex-flow
- flex-grow
- flex-shrink
- flex-wrap
- align-content
- align-items
- align-self
- justify-content
- order
- flex
- flex-basis
- flex-direction
- flex-flow
- flex-grow
- flex-shrink
- flex-wrap
- align-content
- align-items
- align-self
- justify-content
- order
- emptyLineBefore: always
properties:
- width
- min-width
- max-width
- width
- min-width
- max-width
- height
- min-height
- max-height
- height
- min-height
- max-height
- emptyLineBefore: always
properties:
- margin
- margin-top
- margin-right
- margin-bottom
- margin-left
- margin
- margin-top
- margin-right
- margin-bottom
- margin-left
- emptyLineBefore: always
properties:
- padding
- padding-top
- padding-right
- padding-bottom
- padding-left
- padding
- padding-top
- padding-right
- padding-bottom
- padding-left
- emptyLineBefore: always
properties:
- float
- clear
- float
- clear
- emptyLineBefore: always
properties:
- columns
- column-gap
- column-fill
- column-rule
- column-span
- column-count
- column-width
- columns
- column-gap
- column-fill
- column-rule
- column-span
- column-count
- column-width
- emptyLineBefore: always
properties:
- transform
- transform-box
- transform-origin
- transform-style
- transform
- transform-box
- transform-origin
- transform-style
- emptyLineBefore: always
properties:
- transition
- transition-delay
- transition-duration
- transition-property
- transition-timing-function
- transition
- transition-delay
- transition-duration
- transition-property
- transition-timing-function
# Border
- emptyLineBefore: always
properties:
- border
- border-top
- border-right
- border-bottom
- border-left
- border-width
- border-top-width
- border-right-width
- border-bottom-width
- border-left-width
- border
- border-top
- border-right
- border-bottom
- border-left
- border-width
- border-top-width
- border-right-width
- border-bottom-width
- border-left-width
- border-style
- border-top-style
- border-right-style
- border-bottom-style
- border-left-style
- border-style
- border-top-style
- border-right-style
- border-bottom-style
- border-left-style
- border-radius
- border-top-left-radius
- border-top-right-radius
- border-bottom-left-radius
- border-bottom-right-radius
- border-radius
- border-top-left-radius
- border-top-right-radius
- border-bottom-left-radius
- border-bottom-right-radius
- border-color
- border-top-color
- border-right-color
- border-bottom-color
- border-left-color
- border-color
- border-top-color
- border-right-color
- border-bottom-color
- border-left-color
- emptyLineBefore: always
properties:
- outline
- outline-color
- outline-offset
- outline-style
- outline-width
- outline
- outline-color
- outline-offset
- outline-style
- outline-width
# Background
- emptyLineBefore: always
properties:
- background
- background-attachment
- background-clip
- background-color
- background-image
- background-repeat
- background-position
- background-size
- background
- background-attachment
- background-clip
- background-color
- background-image
- background-repeat
- background-position
- background-size
# Text
# Text
- color
- color
- emptyLineBefore: always
properties:
- font
- font-family
- font-size
- font-smoothing
- font-style
- font-variant
- font-weight
- font
- font-family
- font-size
- font-smoothing
- font-style
- font-variant
- font-weight
- emptyLineBefore: always
properties:
- letter-spacing
- line-height
- list-style
- letter-spacing
- line-height
- list-style
- emptyLineBefore: always
properties:
- text-align
- text-decoration
- text-indent
- text-overflow
- text-rendering
- text-shadow
- text-transform
- text-wrap
- text-align
- text-decoration
- text-indent
- text-overflow
- text-rendering
- text-shadow
- text-transform
- text-wrap
- emptyLineBefore: always
properties:
- white-space
- word-spacing
- white-space
- word-spacing
# Other
- emptyLineBefore: always
properties:
- border-collapse
- border-spacing
- box-shadow
- caption-side
- contain
- content
- cursor
- direction
- empty-cells
- object-fit
- opacity
- overflow
- quotes
- speak
- table-layout
- touch-action
- user-select
- vertical-align
- visibility
- z-index
- border-collapse
- border-spacing
- box-shadow
- caption-side
- contain
- content
- cursor
- direction
- empty-cells
- object-fit
- opacity
- overflow
- quotes
- speak
- table-layout
- touch-action
- user-select
- vertical-align
- visibility
- z-index
property-disallowed-list:
- background-position
- right
- left
- float
- padding
- padding-left
- padding-right
- margin
- margin-left
- margin-right
- border-radius
- border-top-left-radius
- border-top-right-radius
- border-bottom-right-radius

View File

@@ -3,6 +3,58 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [8.0.0](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-rc.2...v8.0.0) (2024-04-17)
**Note:** Version bump only for package @ionic/core
# [8.0.0-rc.2](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-rc.1...v8.0.0-rc.2) (2024-04-17)
### Bug Fixes
* **dark-palette:** improve base colors ([#29239](https://github.com/ionic-team/ionic-framework/issues/29239)) ([4698d22](https://github.com/ionic-team/ionic-framework/commit/4698d22413966b59f9fa65b4e2533695cf00ed70)), closes [#29219](https://github.com/ionic-team/ionic-framework/issues/29219)
* **form-controls:** adjust flex properties inside of an item ([#29328](https://github.com/ionic-team/ionic-framework/issues/29328)) ([9b59138](https://github.com/ionic-team/ionic-framework/commit/9b59138011fd1e71def209ec3a43fb7f91b58949)), closes [#29319](https://github.com/ionic-team/ionic-framework/issues/29319)
## [7.8.5](https://github.com/ionic-team/ionic-framework/compare/v7.8.4...v7.8.5) (2024-04-17)
### Bug Fixes
* **modal:** improve sheet modal scrolling and gesture behavior ([#29312](https://github.com/ionic-team/ionic-framework/issues/29312)) ([9738228](https://github.com/ionic-team/ionic-framework/commit/9738228bc05abe3e2012e57b0e6b85f0ec06f66b)), closes [#24583](https://github.com/ionic-team/ionic-framework/issues/24583)
# [8.0.0-rc.1](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-rc.0...v8.0.0-rc.1) (2024-04-10)
### Bug Fixes
* **button:** use clamp for font sizes on circle shape ([#29200](https://github.com/ionic-team/ionic-framework/issues/29200)) ([4d6edee](https://github.com/ionic-team/ionic-framework/commit/4d6edee89c7bb2cb669d67730d7ddf24c78b3cb1))
## [7.8.4](https://github.com/ionic-team/ionic-framework/compare/v7.8.3...v7.8.4) (2024-04-10)
### Performance Improvements
* **styles:** compress distributed global stylesheets ([#29275](https://github.com/ionic-team/ionic-framework/issues/29275)) ([b3cd49b](https://github.com/ionic-team/ionic-framework/commit/b3cd49bf2219aacffc1ac34acbae7c76ef243765))
## [7.8.3](https://github.com/ionic-team/ionic-framework/compare/v7.8.2...v7.8.3) (2024-04-03)

View File

@@ -3,7 +3,6 @@ ion-accordion,shadow
ion-accordion,prop,disabled,boolean,false,false,false
ion-accordion,prop,mode,"ios" | "md",undefined,false,false
ion-accordion,prop,readonly,boolean,false,false,false
ion-accordion,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-accordion,prop,toggleIcon,string,chevronDown,false,false
ion-accordion,prop,toggleIconSlot,"end" | "start",'end',false,false
ion-accordion,prop,value,string,`ion-accordion-${accordionIds++}`,false,false
@@ -18,7 +17,6 @@ ion-accordion-group,prop,expand,"compact" | "inset",'compact',false,false
ion-accordion-group,prop,mode,"ios" | "md",undefined,false,false
ion-accordion-group,prop,multiple,boolean | undefined,undefined,false,false
ion-accordion-group,prop,readonly,boolean,false,false,false
ion-accordion-group,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-accordion-group,prop,value,null | string | string[] | undefined,undefined,false,false
ion-accordion-group,event,ionChange,AccordionGroupChangeEventDetail<any>,true
@@ -35,7 +33,6 @@ ion-action-sheet,prop,keyboardClose,boolean,true,false,false
ion-action-sheet,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-action-sheet,prop,mode,"ios" | "md",undefined,false,false
ion-action-sheet,prop,subHeader,string | undefined,undefined,false,false
ion-action-sheet,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-action-sheet,prop,translucent,boolean,false,false,false
ion-action-sheet,prop,trigger,string | undefined,undefined,false,false
ion-action-sheet,method,dismiss,dismiss(data?: any, role?: string) => Promise<boolean>
@@ -90,7 +87,6 @@ ion-alert,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefin
ion-alert,prop,message,IonicSafeString | string | undefined,undefined,false,false
ion-alert,prop,mode,"ios" | "md",undefined,false,false
ion-alert,prop,subHeader,string | undefined,undefined,false,false
ion-alert,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-alert,prop,translucent,boolean,false,false,false
ion-alert,prop,trigger,string | undefined,undefined,false,false
ion-alert,method,dismiss,dismiss(data?: any, role?: string) => Promise<boolean>
@@ -115,12 +111,8 @@ ion-alert,css-prop,--min-width
ion-alert,css-prop,--width
ion-app,none
ion-app,prop,mode,"ios" | "md",undefined,false,false
ion-app,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-avatar,shadow
ion-avatar,prop,mode,"ios" | "md",undefined,false,false
ion-avatar,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-avatar,css-prop,--border-radius
ion-back-button,shadow
@@ -131,7 +123,6 @@ ion-back-button,prop,icon,null | string | undefined,undefined,false,false
ion-back-button,prop,mode,"ios" | "md",undefined,false,false
ion-back-button,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-back-button,prop,text,null | string | undefined,undefined,false,false
ion-back-button,prop,theme,"ios" | "md" | "ionic",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
@@ -170,17 +161,14 @@ ion-back-button,part,native
ion-back-button,part,text
ion-backdrop,shadow
ion-backdrop,prop,mode,"ios" | "md",undefined,false,false
ion-backdrop,prop,stopPropagation,boolean,true,false,false
ion-backdrop,prop,tappable,boolean,true,false,false
ion-backdrop,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-backdrop,prop,visible,boolean,true,false,false
ion-backdrop,event,ionBackdropTap,void,true
ion-badge,shadow
ion-badge,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-badge,prop,mode,"ios" | "md",undefined,false,false
ion-badge,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-badge,css-prop,--background
ion-badge,css-prop,--color
ion-badge,css-prop,--padding-bottom
@@ -200,7 +188,6 @@ ion-breadcrumb,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | u
ion-breadcrumb,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
ion-breadcrumb,prop,separator,boolean | undefined,undefined,false,false
ion-breadcrumb,prop,target,string | undefined,undefined,false,false
ion-breadcrumb,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-breadcrumb,event,ionBlur,void,true
ion-breadcrumb,event,ionFocus,void,true
ion-breadcrumb,css-prop,--background-focused
@@ -218,7 +205,6 @@ ion-breadcrumbs,prop,itemsAfterCollapse,number,1,false,false
ion-breadcrumbs,prop,itemsBeforeCollapse,number,1,false,false
ion-breadcrumbs,prop,maxItems,number | undefined,undefined,false,false
ion-breadcrumbs,prop,mode,"ios" | "md",undefined,false,false
ion-breadcrumbs,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-breadcrumbs,event,ionCollapsedClick,BreadcrumbCollapsedClickEventDetail,true
ion-button,shadow
@@ -234,11 +220,10 @@ ion-button,prop,mode,"ios" | "md",undefined,false,false
ion-button,prop,rel,string | undefined,undefined,false,false
ion-button,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-button,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
ion-button,prop,shape,"rectangular" | "round" | undefined,undefined,false,true
ion-button,prop,size,"default" | "large" | "small" | "xlarge" | "xsmall" | undefined,undefined,false,true
ion-button,prop,shape,"round" | undefined,undefined,false,true
ion-button,prop,size,"default" | "large" | "small" | undefined,undefined,false,true
ion-button,prop,strong,boolean,false,false,false
ion-button,prop,target,string | undefined,undefined,false,false
ion-button,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-button,prop,type,"button" | "reset" | "submit",'button',false,false
ion-button,event,ionBlur,void,true
ion-button,event,ionFocus,void,true
@@ -269,8 +254,6 @@ ion-button,part,native
ion-buttons,scoped
ion-buttons,prop,collapse,boolean,false,false,false
ion-buttons,prop,mode,"ios" | "md",undefined,false,false
ion-buttons,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-card,shadow
ion-card,prop,button,boolean,false,false,false
@@ -282,9 +265,7 @@ ion-card,prop,mode,"ios" | "md",undefined,false,false
ion-card,prop,rel,string | undefined,undefined,false,false
ion-card,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-card,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
ion-card,prop,shape,"rectangular" | "round" | undefined,undefined,false,true
ion-card,prop,target,string | undefined,undefined,false,false
ion-card,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-card,prop,type,"button" | "reset" | "submit",'button',false,false
ion-card,css-prop,--background
ion-card,css-prop,--color
@@ -292,24 +273,20 @@ ion-card,part,native
ion-card-content,none
ion-card-content,prop,mode,"ios" | "md",undefined,false,false
ion-card-content,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-card-header,shadow
ion-card-header,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-card-header,prop,mode,"ios" | "md",undefined,false,false
ion-card-header,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-card-header,prop,translucent,boolean,false,false,false
ion-card-subtitle,shadow
ion-card-subtitle,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-card-subtitle,prop,mode,"ios" | "md",undefined,false,false
ion-card-subtitle,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-card-subtitle,css-prop,--color
ion-card-title,shadow
ion-card-title,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-card-title,prop,mode,"ios" | "md",undefined,false,false
ion-card-title,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-card-title,css-prop,--color
ion-checkbox,shadow
@@ -322,7 +299,6 @@ ion-checkbox,prop,justify,"end" | "space-between" | "start",'space-between',fals
ion-checkbox,prop,labelPlacement,"end" | "fixed" | "stacked" | "start",'start',false,false
ion-checkbox,prop,mode,"ios" | "md",undefined,false,false
ion-checkbox,prop,name,string,this.inputId,false,false
ion-checkbox,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-checkbox,prop,value,any,'on',false,false
ion-checkbox,event,ionBlur,void,true
ion-checkbox,event,ionChange,CheckboxChangeEventDetail<any>,true
@@ -347,13 +323,10 @@ ion-chip,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "second
ion-chip,prop,disabled,boolean,false,false,false
ion-chip,prop,mode,"ios" | "md",undefined,false,false
ion-chip,prop,outline,boolean,false,false,false
ion-chip,prop,shape,"rectangular" | "round" | undefined,undefined,false,false
ion-chip,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-chip,css-prop,--background
ion-chip,css-prop,--color
ion-col,shadow
ion-col,prop,mode,"ios" | "md",undefined,false,false
ion-col,prop,offset,string | undefined,undefined,false,false
ion-col,prop,offsetLg,string | undefined,undefined,false,false
ion-col,prop,offsetMd,string | undefined,undefined,false,false
@@ -378,7 +351,6 @@ ion-col,prop,sizeMd,string | undefined,undefined,false,false
ion-col,prop,sizeSm,string | undefined,undefined,false,false
ion-col,prop,sizeXl,string | undefined,undefined,false,false
ion-col,prop,sizeXs,string | undefined,undefined,false,false
ion-col,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-col,css-prop,--ion-grid-column-padding
ion-col,css-prop,--ion-grid-column-padding-lg
ion-col,css-prop,--ion-grid-column-padding-md
@@ -389,14 +361,11 @@ ion-col,css-prop,--ion-grid-columns
ion-content,shadow
ion-content,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-content,prop,fixedSlotPlacement,"after" | "before",'after',false,false
ion-content,prop,forceOverscroll,boolean | undefined,undefined,false,false
ion-content,prop,fullscreen,boolean,false,false,false
ion-content,prop,mode,"ios" | "md",undefined,false,false
ion-content,prop,scrollEvents,boolean,false,false,false
ion-content,prop,scrollX,boolean,false,false,false
ion-content,prop,scrollY,boolean,true,false,false
ion-content,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-content,method,getScrollElement,getScrollElement() => Promise<HTMLElement>
ion-content,method,scrollByPoint,scrollByPoint(x: number, y: number, duration: number) => Promise<void>
ion-content,method,scrollToBottom,scrollToBottom(duration?: number) => Promise<void>
@@ -446,7 +415,6 @@ ion-datetime,prop,showDefaultButtons,boolean,false,false,false
ion-datetime,prop,showDefaultTimeLabel,boolean,true,false,false
ion-datetime,prop,showDefaultTitle,boolean,false,false,false
ion-datetime,prop,size,"cover" | "fixed",'fixed',false,false
ion-datetime,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-datetime,prop,titleSelectedDatesFormatter,((selectedDates: string[]) => string) | undefined,undefined,false,false
ion-datetime,prop,value,null | string | string[] | undefined,undefined,false,false
ion-datetime,prop,yearValues,number | number[] | string | undefined,undefined,false,false
@@ -478,15 +446,12 @@ ion-datetime-button,prop,color,"danger" | "dark" | "light" | "medium" | "primary
ion-datetime-button,prop,datetime,string | undefined,undefined,false,false
ion-datetime-button,prop,disabled,boolean,false,false,true
ion-datetime-button,prop,mode,"ios" | "md",undefined,false,false
ion-datetime-button,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-datetime-button,part,native
ion-fab,shadow
ion-fab,prop,activated,boolean,false,false,false
ion-fab,prop,edge,boolean,false,false,false
ion-fab,prop,horizontal,"center" | "end" | "start" | undefined,undefined,false,false
ion-fab,prop,mode,"ios" | "md",undefined,false,false
ion-fab,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-fab,prop,vertical,"bottom" | "center" | "top" | undefined,undefined,false,false
ion-fab,method,close,close() => Promise<void>
@@ -504,7 +469,6 @@ ion-fab-button,prop,routerDirection,"back" | "forward" | "root",'forward',false,
ion-fab-button,prop,show,boolean,false,false,false
ion-fab-button,prop,size,"small" | undefined,undefined,false,false
ion-fab-button,prop,target,string | undefined,undefined,false,false
ion-fab-button,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-fab-button,prop,translucent,boolean,false,false,false
ion-fab-button,prop,type,"button" | "reset" | "submit",'button',false,false
ion-fab-button,event,ionBlur,void,true
@@ -537,20 +501,15 @@ ion-fab-button,part,native
ion-fab-list,shadow
ion-fab-list,prop,activated,boolean,false,false,false
ion-fab-list,prop,mode,"ios" | "md",undefined,false,false
ion-fab-list,prop,side,"bottom" | "end" | "start" | "top",'bottom',false,false
ion-fab-list,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-footer,none
ion-footer,prop,collapse,"fade" | undefined,undefined,false,false
ion-footer,prop,mode,"ios" | "md",undefined,false,false
ion-footer,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-footer,prop,translucent,boolean,false,false,false
ion-grid,shadow
ion-grid,prop,fixed,boolean,false,false,false
ion-grid,prop,mode,"ios" | "md",undefined,false,false
ion-grid,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-grid,css-prop,--ion-grid-padding
ion-grid,css-prop,--ion-grid-padding-lg
ion-grid,css-prop,--ion-grid-padding-md
@@ -567,14 +526,11 @@ ion-grid,css-prop,--ion-grid-width-xs
ion-header,none
ion-header,prop,collapse,"condense" | "fade" | undefined,undefined,false,false
ion-header,prop,mode,"ios" | "md",undefined,false,false
ion-header,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-header,prop,translucent,boolean,false,false,false
ion-img,shadow
ion-img,prop,alt,string | undefined,undefined,false,false
ion-img,prop,mode,"ios" | "md",undefined,false,false
ion-img,prop,src,string | undefined,undefined,false,false
ion-img,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-img,event,ionError,void,true
ion-img,event,ionImgDidLoad,void,true
ion-img,event,ionImgWillLoad,void,true
@@ -582,9 +538,7 @@ ion-img,part,image
ion-infinite-scroll,none
ion-infinite-scroll,prop,disabled,boolean,false,false,false
ion-infinite-scroll,prop,mode,"ios" | "md",undefined,false,false
ion-infinite-scroll,prop,position,"bottom" | "top",'bottom',false,false
ion-infinite-scroll,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-infinite-scroll,prop,threshold,string,'15%',false,false
ion-infinite-scroll,method,complete,complete() => Promise<void>
ion-infinite-scroll,event,ionInfinite,void,true
@@ -592,8 +546,6 @@ ion-infinite-scroll,event,ionInfinite,void,true
ion-infinite-scroll-content,none
ion-infinite-scroll-content,prop,loadingSpinner,"bubbles" | "circles" | "circular" | "crescent" | "dots" | "lines" | "lines-sharp" | "lines-sharp-small" | "lines-small" | null | undefined,undefined,false,false
ion-infinite-scroll-content,prop,loadingText,IonicSafeString | string | undefined,undefined,false,false
ion-infinite-scroll-content,prop,mode,"ios" | "md",undefined,false,false
ion-infinite-scroll-content,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-input,scoped
ion-input,prop,autocapitalize,string,'off',false,false
@@ -601,7 +553,6 @@ ion-input,prop,autocomplete,"name" | "email" | "tel" | "url" | "on" | "off" | "h
ion-input,prop,autocorrect,"off" | "on",'off',false,false
ion-input,prop,autofocus,boolean,false,false,false
ion-input,prop,clearInput,boolean,false,false,false
ion-input,prop,clearInputIcon,string | undefined,undefined,false,false
ion-input,prop,clearOnEdit,boolean | undefined,undefined,false,false
ion-input,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-input,prop,counter,boolean,false,false,false
@@ -629,7 +580,6 @@ ion-input,prop,required,boolean,false,false,false
ion-input,prop,shape,"round" | undefined,undefined,false,false
ion-input,prop,spellcheck,boolean,false,false,false
ion-input,prop,step,string | undefined,undefined,false,false
ion-input,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-input,prop,type,"date" | "datetime-local" | "email" | "month" | "number" | "password" | "search" | "tel" | "text" | "time" | "url" | "week",'text',false,false
ion-input,prop,value,null | number | string | undefined,'',false,false
ion-input,method,getInputElement,getInputElement() => Promise<HTMLInputElement>
@@ -677,7 +627,6 @@ ion-item,prop,rel,string | undefined,undefined,false,false
ion-item,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-item,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
ion-item,prop,target,string | undefined,undefined,false,false
ion-item,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-item,prop,type,"button" | "reset" | "submit",'button',false,false
ion-item,css-prop,--background
ion-item,css-prop,--background-activated
@@ -717,7 +666,6 @@ ion-item-divider,shadow
ion-item-divider,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-item-divider,prop,mode,"ios" | "md",undefined,false,false
ion-item-divider,prop,sticky,boolean,false,false,false
ion-item-divider,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-item-divider,css-prop,--background
ion-item-divider,css-prop,--color
ion-item-divider,css-prop,--inner-padding-bottom
@@ -730,8 +678,6 @@ ion-item-divider,css-prop,--padding-start
ion-item-divider,css-prop,--padding-top
ion-item-group,none
ion-item-group,prop,mode,"ios" | "md",undefined,false,false
ion-item-group,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-item-option,shadow
ion-item-option,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
@@ -742,22 +688,17 @@ ion-item-option,prop,href,string | undefined,undefined,false,false
ion-item-option,prop,mode,"ios" | "md",undefined,false,false
ion-item-option,prop,rel,string | undefined,undefined,false,false
ion-item-option,prop,target,string | undefined,undefined,false,false
ion-item-option,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-item-option,prop,type,"button" | "reset" | "submit",'button',false,false
ion-item-option,css-prop,--background
ion-item-option,css-prop,--color
ion-item-option,part,native
ion-item-options,none
ion-item-options,prop,mode,"ios" | "md",undefined,false,false
ion-item-options,prop,side,"end" | "start",'end',false,false
ion-item-options,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-item-options,event,ionSwipe,any,true
ion-item-sliding,none
ion-item-sliding,prop,disabled,boolean,false,false,false
ion-item-sliding,prop,mode,"ios" | "md",undefined,false,false
ion-item-sliding,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-item-sliding,method,close,close() => Promise<void>
ion-item-sliding,method,closeOpened,closeOpened() => Promise<boolean>
ion-item-sliding,method,getOpenAmount,getOpenAmount() => Promise<number>
@@ -769,21 +710,18 @@ ion-label,scoped
ion-label,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-label,prop,mode,"ios" | "md",undefined,false,false
ion-label,prop,position,"fixed" | "floating" | "stacked" | undefined,undefined,false,false
ion-label,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-label,css-prop,--color
ion-list,none
ion-list,prop,inset,boolean,false,false,false
ion-list,prop,lines,"full" | "inset" | "none" | undefined,undefined,false,false
ion-list,prop,mode,"ios" | "md",undefined,false,false
ion-list,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-list,method,closeSlidingItems,closeSlidingItems() => Promise<boolean>
ion-list-header,shadow
ion-list-header,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
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,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-list-header,css-prop,--background
ion-list-header,css-prop,--border-color
ion-list-header,css-prop,--border-style
@@ -805,7 +743,6 @@ ion-loading,prop,message,IonicSafeString | string | undefined,undefined,false,fa
ion-loading,prop,mode,"ios" | "md",undefined,false,false
ion-loading,prop,showBackdrop,boolean,true,false,false
ion-loading,prop,spinner,"bubbles" | "circles" | "circular" | "crescent" | "dots" | "lines" | "lines-sharp" | "lines-sharp-small" | "lines-small" | null | undefined,undefined,false,false
ion-loading,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-loading,prop,translucent,boolean,false,false,false
ion-loading,prop,trigger,string | undefined,undefined,false,false
ion-loading,method,dismiss,dismiss(data?: any, role?: string) => Promise<boolean>
@@ -835,10 +772,8 @@ ion-menu,prop,contentId,string | undefined,undefined,false,true
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,mode,"ios" | "md",undefined,false,false
ion-menu,prop,side,"end" | "start",'start',false,true
ion-menu,prop,swipeGesture,boolean,true,false,false
ion-menu,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-menu,prop,type,"overlay" | "push" | "reveal" | undefined,undefined,false,false
ion-menu,method,close,close(animated?: boolean) => Promise<boolean>
ion-menu,method,isActive,isActive() => Promise<boolean>
@@ -866,7 +801,6 @@ ion-menu-button,prop,color,"danger" | "dark" | "light" | "medium" | "primary" |
ion-menu-button,prop,disabled,boolean,false,false,false
ion-menu-button,prop,menu,string | undefined,undefined,false,false
ion-menu-button,prop,mode,"ios" | "md",undefined,false,false
ion-menu-button,prop,theme,"ios" | "md" | "ionic",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
@@ -887,8 +821,6 @@ ion-menu-button,part,native
ion-menu-toggle,shadow
ion-menu-toggle,prop,autoHide,boolean,true,false,false
ion-menu-toggle,prop,menu,string | undefined,undefined,false,false
ion-menu-toggle,prop,mode,"ios" | "md",undefined,false,false
ion-menu-toggle,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-modal,shadow
ion-modal,prop,animated,boolean,true,false,false
@@ -908,7 +840,6 @@ ion-modal,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefin
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,theme,"ios" | "md" | "ionic",undefined,false,false
ion-modal,prop,trigger,string | undefined,undefined,false,false
ion-modal,method,dismiss,dismiss(data?: any, role?: string) => Promise<boolean>
ion-modal,method,getCurrentBreakpoint,getCurrentBreakpoint() => Promise<number | undefined>
@@ -944,11 +875,9 @@ ion-modal,part,handle
ion-nav,shadow
ion-nav,prop,animated,boolean,true,false,false
ion-nav,prop,animation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-nav,prop,mode,"ios" | "md",undefined,false,false
ion-nav,prop,root,Function | HTMLElement | ViewController | null | string | undefined,undefined,false,false
ion-nav,prop,rootParams,undefined | { [key: string]: any; },undefined,false,false
ion-nav,prop,swipeGesture,boolean | undefined,undefined,false,false
ion-nav,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-nav,method,canGoBack,canGoBack(view?: ViewController) => Promise<boolean>
ion-nav,method,getActive,getActive() => Promise<ViewController | undefined>
ion-nav,method,getByIndex,getByIndex(index: number) => Promise<ViewController | undefined>
@@ -969,20 +898,16 @@ ion-nav,event,ionNavWillChange,void,false
ion-nav-link,none
ion-nav-link,prop,component,Function | HTMLElement | ViewController | null | string | undefined,undefined,false,false
ion-nav-link,prop,componentProps,undefined | { [key: string]: any; },undefined,false,false
ion-nav-link,prop,mode,"ios" | "md",undefined,false,false
ion-nav-link,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-nav-link,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
ion-nav-link,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-note,shadow
ion-note,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-note,prop,mode,"ios" | "md",undefined,false,false
ion-note,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-note,css-prop,--color
ion-picker,shadow
ion-picker,prop,mode,"ios" | "md",undefined,false,false
ion-picker,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-picker,css-prop,--fade-background-rgb
ion-picker,css-prop,--highlight-background
ion-picker,css-prop,--highlight-border-radius
@@ -991,7 +916,6 @@ ion-picker-column,shadow
ion-picker-column,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,'primary',false,true
ion-picker-column,prop,disabled,boolean,false,false,false
ion-picker-column,prop,mode,"ios" | "md",undefined,false,false
ion-picker-column,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-picker-column,prop,value,number | string | undefined,undefined,false,false
ion-picker-column,method,setFocus,setFocus() => Promise<void>
ion-picker-column,event,ionChange,PickerColumnChangeEventDetail,true
@@ -999,8 +923,6 @@ ion-picker-column,event,ionChange,PickerColumnChangeEventDetail,true
ion-picker-column-option,shadow
ion-picker-column-option,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,'primary',false,true
ion-picker-column-option,prop,disabled,boolean,false,false,false
ion-picker-column-option,prop,mode,"ios" | "md",undefined,false,false
ion-picker-column-option,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-picker-column-option,prop,value,any,undefined,false,false
ion-picker-legacy,scoped
@@ -1017,7 +939,6 @@ ion-picker-legacy,prop,keyboardClose,boolean,true,false,false
ion-picker-legacy,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-picker-legacy,prop,mode,"ios" | "md",undefined,false,false
ion-picker-legacy,prop,showBackdrop,boolean,true,false,false
ion-picker-legacy,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-picker-legacy,prop,trigger,string | undefined,undefined,false,false
ion-picker-legacy,method,dismiss,dismiss(data?: any, role?: string) => Promise<boolean>
ion-picker-legacy,method,getColumn,getColumn(name: string) => Promise<PickerColumn | undefined>
@@ -1066,7 +987,6 @@ ion-popover,prop,reference,"event" | "trigger",'trigger',false,false
ion-popover,prop,showBackdrop,boolean,true,false,false
ion-popover,prop,side,"bottom" | "end" | "left" | "right" | "start" | "top",'bottom',false,false
ion-popover,prop,size,"auto" | "cover",'auto',false,false
ion-popover,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-popover,prop,translucent,boolean,false,false,false
ion-popover,prop,trigger,string | undefined,undefined,false,false
ion-popover,prop,triggerAction,"click" | "context-menu" | "hover",'click',false,false
@@ -1102,7 +1022,6 @@ ion-progress-bar,prop,buffer,number,1,false,false
ion-progress-bar,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-progress-bar,prop,mode,"ios" | "md",undefined,false,false
ion-progress-bar,prop,reversed,boolean,false,false,false
ion-progress-bar,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-progress-bar,prop,type,"determinate" | "indeterminate",'determinate',false,false
ion-progress-bar,prop,value,number,0,false,false
ion-progress-bar,css-prop,--background
@@ -1119,7 +1038,6 @@ ion-radio,prop,justify,"end" | "space-between" | "start",'space-between',false,f
ion-radio,prop,labelPlacement,"end" | "fixed" | "stacked" | "start",'start',false,false
ion-radio,prop,mode,"ios" | "md",undefined,false,false
ion-radio,prop,name,string,this.inputId,false,false
ion-radio,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-radio,prop,value,any,undefined,false,false
ion-radio,event,ionBlur,void,true
ion-radio,event,ionFocus,void,true
@@ -1134,9 +1052,7 @@ ion-radio,part,mark
ion-radio-group,none
ion-radio-group,prop,allowEmptySelection,boolean,false,false,false
ion-radio-group,prop,compareWith,((currentValue: any, compareValue: any) => boolean) | null | string | undefined,undefined,false,false
ion-radio-group,prop,mode,"ios" | "md",undefined,false,false
ion-radio-group,prop,name,string,this.inputId,false,false
ion-radio-group,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-radio-group,prop,value,any,undefined,false,false
ion-radio-group,event,ionChange,RadioGroupChangeEventDetail<any>,true
@@ -1156,7 +1072,6 @@ ion-range,prop,pin,boolean,false,false,false
ion-range,prop,pinFormatter,(value: number) => string | number,(value: number): number => Math.round(value),false,false
ion-range,prop,snaps,boolean,false,false,false
ion-range,prop,step,number,1,false,false
ion-range,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-range,prop,ticks,boolean,true,false,false
ion-range,prop,value,number | { lower: number; upper: number; },0,false,false
ion-range,event,ionBlur,void,true
@@ -1192,7 +1107,6 @@ ion-refresher,prop,pullFactor,number,1,false,false
ion-refresher,prop,pullMax,number,this.pullMin + 60,false,false
ion-refresher,prop,pullMin,number,60,false,false
ion-refresher,prop,snapbackDuration,string,'280ms',false,false
ion-refresher,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-refresher,method,cancel,cancel() => Promise<void>
ion-refresher,method,complete,complete() => Promise<void>
ion-refresher,method,getProgress,getProgress() => Promise<number>
@@ -1201,28 +1115,20 @@ ion-refresher,event,ionRefresh,RefresherEventDetail,true
ion-refresher,event,ionStart,void,true
ion-refresher-content,none
ion-refresher-content,prop,mode,"ios" | "md",undefined,false,false
ion-refresher-content,prop,pullingIcon,null | string | undefined,undefined,false,false
ion-refresher-content,prop,pullingText,IonicSafeString | string | undefined,undefined,false,false
ion-refresher-content,prop,refreshingSpinner,"bubbles" | "circles" | "circular" | "crescent" | "dots" | "lines" | "lines-sharp" | "lines-sharp-small" | "lines-small" | null | undefined,undefined,false,false
ion-refresher-content,prop,refreshingText,IonicSafeString | string | undefined,undefined,false,false
ion-refresher-content,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-reorder,shadow
ion-reorder,prop,mode,"ios" | "md",undefined,false,false
ion-reorder,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-reorder,part,icon
ion-reorder-group,none
ion-reorder-group,prop,disabled,boolean,true,false,false
ion-reorder-group,prop,mode,"ios" | "md",undefined,false,false
ion-reorder-group,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-reorder-group,method,complete,complete(listOrReorder?: boolean | any[]) => Promise<any>
ion-reorder-group,event,ionItemReorder,ItemReorderEventDetail,true
ion-ripple-effect,shadow
ion-ripple-effect,prop,mode,"ios" | "md",undefined,false,false
ion-ripple-effect,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-ripple-effect,prop,type,"bounded" | "unbounded",'bounded',false,false
ion-ripple-effect,method,addRipple,addRipple(x: number, y: number) => Promise<() => void>
@@ -1231,8 +1137,6 @@ ion-route,prop,beforeEnter,(() => NavigationHookResult | Promise<NavigationHookR
ion-route,prop,beforeLeave,(() => NavigationHookResult | Promise<NavigationHookResult>) | undefined,undefined,false,false
ion-route,prop,component,string,undefined,true,false
ion-route,prop,componentProps,undefined | { [key: string]: any; },undefined,false,false
ion-route,prop,mode,"ios" | "md",undefined,false,false
ion-route,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-route,prop,url,string,'',false,false
ion-route,event,ionRouteDataChanged,any,true
@@ -1242,9 +1146,7 @@ ion-route-redirect,prop,to,null | string | undefined,undefined,true,false
ion-route-redirect,event,ionRouteRedirectChanged,any,true
ion-router,none
ion-router,prop,mode,"ios" | "md",undefined,false,false
ion-router,prop,root,string,'/',false,false
ion-router,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-router,prop,useHash,boolean,true,false,false
ion-router,method,back,back() => Promise<void>
ion-router,method,push,push(path: string, direction?: RouterDirection, animation?: AnimationBuilder) => Promise<boolean>
@@ -1254,12 +1156,10 @@ ion-router,event,ionRouteWillChange,RouterEventDetail,true
ion-router-link,shadow
ion-router-link,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-router-link,prop,href,string | undefined,undefined,false,false
ion-router-link,prop,mode,"ios" | "md",undefined,false,false
ion-router-link,prop,rel,string | undefined,undefined,false,false
ion-router-link,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-router-link,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
ion-router-link,prop,target,string | undefined,undefined,false,false
ion-router-link,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-router-link,css-prop,--background
ion-router-link,css-prop,--color
@@ -1267,11 +1167,8 @@ ion-router-outlet,shadow
ion-router-outlet,prop,animated,boolean,true,false,false
ion-router-outlet,prop,animation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-router-outlet,prop,mode,"ios" | "md",getIonMode(this),false,false
ion-router-outlet,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-row,shadow
ion-row,prop,mode,"ios" | "md",undefined,false,false
ion-row,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-searchbar,scoped
ion-searchbar,prop,animated,boolean,false,false,false
@@ -1295,7 +1192,6 @@ ion-searchbar,prop,searchIcon,string | undefined,undefined,false,false
ion-searchbar,prop,showCancelButton,"always" | "focus" | "never",'never',false,false
ion-searchbar,prop,showClearButton,"always" | "focus" | "never",'always',false,false
ion-searchbar,prop,spellcheck,boolean,false,false,false
ion-searchbar,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-searchbar,prop,type,"email" | "number" | "password" | "search" | "tel" | "text" | "url",'search',false,false
ion-searchbar,prop,value,null | string | undefined,'',false,false
ion-searchbar,method,getInputElement,getInputElement() => Promise<HTMLInputElement>
@@ -1325,7 +1221,6 @@ ion-segment,prop,mode,"ios" | "md",undefined,false,false
ion-segment,prop,scrollable,boolean,false,false,false
ion-segment,prop,selectOnFocus,boolean,false,false,false
ion-segment,prop,swipeGesture,boolean,true,false,false
ion-segment,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-segment,prop,value,number | string | undefined,undefined,false,false
ion-segment,event,ionChange,SegmentChangeEventDetail,true
ion-segment,css-prop,--background
@@ -1334,7 +1229,6 @@ ion-segment-button,shadow
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,theme,"ios" | "md" | "ionic",undefined,false,false
ion-segment-button,prop,type,"button" | "reset" | "submit",'button',false,false
ion-segment-button,prop,value,number | string,'ion-sb-' + ids++,false,false
ion-segment-button,css-prop,--background
@@ -1388,7 +1282,6 @@ ion-select,prop,okText,string,'OK',false,false
ion-select,prop,placeholder,string | undefined,undefined,false,false
ion-select,prop,selectedText,null | string | undefined,undefined,false,false
ion-select,prop,shape,"round" | undefined,undefined,false,false
ion-select,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-select,prop,toggleIcon,string | undefined,undefined,false,false
ion-select,prop,value,any,undefined,false,false
ion-select,method,open,open(event?: UIEvent) => Promise<any>
@@ -1421,14 +1314,10 @@ ion-select,part,text
ion-select-option,shadow
ion-select-option,prop,disabled,boolean,false,false,false
ion-select-option,prop,mode,"ios" | "md",undefined,false,false
ion-select-option,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-select-option,prop,value,any,undefined,false,false
ion-skeleton-text,shadow
ion-skeleton-text,prop,animated,boolean,false,false,false
ion-skeleton-text,prop,mode,"ios" | "md",undefined,false,false
ion-skeleton-text,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-skeleton-text,css-prop,--background
ion-skeleton-text,css-prop,--background-rgb
ion-skeleton-text,css-prop,--border-radius
@@ -1436,17 +1325,13 @@ ion-skeleton-text,css-prop,--border-radius
ion-spinner,shadow
ion-spinner,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-spinner,prop,duration,number | undefined,undefined,false,false
ion-spinner,prop,mode,"ios" | "md",undefined,false,false
ion-spinner,prop,name,"bubbles" | "circles" | "circular" | "crescent" | "dots" | "lines" | "lines-sharp" | "lines-sharp-small" | "lines-small" | undefined,undefined,false,false
ion-spinner,prop,paused,boolean,false,false,false
ion-spinner,prop,theme,"ios" | "md" | "ionic",undefined,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,disabled,boolean,false,false,false
ion-split-pane,prop,mode,"ios" | "md",undefined,false,false
ion-split-pane,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-split-pane,prop,when,boolean | string,QUERY['lg'],false,false
ion-split-pane,event,ionSplitPaneVisible,{ visible: boolean; },true
ion-split-pane,css-prop,--border
@@ -1456,16 +1341,13 @@ ion-split-pane,css-prop,--side-width
ion-tab,shadow
ion-tab,prop,component,Function | HTMLElement | null | string | undefined,undefined,false,false
ion-tab,prop,mode,"ios" | "md",undefined,false,false
ion-tab,prop,tab,string,undefined,true,false
ion-tab,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-tab,method,setActive,setActive() => Promise<void>
ion-tab-bar,shadow
ion-tab-bar,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-tab-bar,prop,mode,"ios" | "md",undefined,false,false
ion-tab-bar,prop,selectedTab,string | undefined,undefined,false,false
ion-tab-bar,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-tab-bar,prop,translucent,boolean,false,false,false
ion-tab-bar,css-prop,--background
ion-tab-bar,css-prop,--border
@@ -1481,7 +1363,6 @@ ion-tab-button,prop,rel,string | undefined,undefined,false,false
ion-tab-button,prop,selected,boolean,false,false,false
ion-tab-button,prop,tab,string | undefined,undefined,false,false
ion-tab-button,prop,target,string | undefined,undefined,false,false
ion-tab-button,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-tab-button,css-prop,--background
ion-tab-button,css-prop,--background-focused
ion-tab-button,css-prop,--background-focused-opacity
@@ -1496,8 +1377,6 @@ ion-tab-button,css-prop,--ripple-color
ion-tab-button,part,native
ion-tabs,shadow
ion-tabs,prop,mode,"ios" | "md",undefined,false,false
ion-tabs,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-tabs,method,getSelected,getSelected() => Promise<string | undefined>
ion-tabs,method,getTab,getTab(tab: string | HTMLIonTabElement) => Promise<HTMLIonTabElement | undefined>
ion-tabs,method,select,select(tab: string | HTMLIonTabElement) => Promise<boolean>
@@ -1507,7 +1386,6 @@ ion-tabs,event,ionTabsWillChange,{ tab: string; },false
ion-text,shadow
ion-text,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-text,prop,mode,"ios" | "md",undefined,false,false
ion-text,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-textarea,scoped
ion-textarea,prop,autoGrow,boolean,false,false,true
@@ -1537,7 +1415,6 @@ ion-textarea,prop,required,boolean,false,false,false
ion-textarea,prop,rows,number | undefined,undefined,false,false
ion-textarea,prop,shape,"round" | undefined,undefined,false,false
ion-textarea,prop,spellcheck,boolean,false,false,false
ion-textarea,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-textarea,prop,value,null | string | undefined,'',false,false
ion-textarea,prop,wrap,"hard" | "off" | "soft" | undefined,undefined,false,false
ion-textarea,method,getInputElement,getInputElement() => Promise<HTMLTextAreaElement>
@@ -1566,16 +1443,12 @@ ion-textarea,css-prop,--placeholder-font-weight
ion-textarea,css-prop,--placeholder-opacity
ion-thumbnail,shadow
ion-thumbnail,prop,mode,"ios" | "md",undefined,false,false
ion-thumbnail,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-thumbnail,css-prop,--border-radius
ion-thumbnail,css-prop,--size
ion-title,shadow
ion-title,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-title,prop,mode,"ios" | "md",undefined,false,false
ion-title,prop,size,"large" | "small" | undefined,undefined,false,false
ion-title,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-title,css-prop,--color
ion-toast,shadow
@@ -1597,7 +1470,6 @@ ion-toast,prop,mode,"ios" | "md",undefined,false,false
ion-toast,prop,position,"bottom" | "middle" | "top",'bottom',false,false
ion-toast,prop,positionAnchor,HTMLElement | string | undefined,undefined,false,false
ion-toast,prop,swipeGesture,"vertical" | undefined,undefined,false,false
ion-toast,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-toast,prop,translucent,boolean,false,false,false
ion-toast,prop,trigger,string | undefined,undefined,false,false
ion-toast,method,dismiss,dismiss(data?: any, role?: string) => Promise<boolean>
@@ -1646,7 +1518,6 @@ ion-toggle,prop,justify,"end" | "space-between" | "start",'space-between',false,
ion-toggle,prop,labelPlacement,"end" | "fixed" | "stacked" | "start",'start',false,false
ion-toggle,prop,mode,"ios" | "md",undefined,false,false
ion-toggle,prop,name,string,this.inputId,false,false
ion-toggle,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-toggle,prop,value,null | string | undefined,'on',false,false
ion-toggle,event,ionBlur,void,true
ion-toggle,event,ionChange,ToggleChangeEventDetail<any>,true
@@ -1670,7 +1541,6 @@ ion-toggle,part,track
ion-toolbar,shadow
ion-toolbar,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-toolbar,prop,mode,"ios" | "md",undefined,false,false
ion-toolbar,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-toolbar,css-prop,--background
ion-toolbar,css-prop,--border-color
ion-toolbar,css-prop,--border-style

2378
core/package-lock.json generated
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/core",
"version": "8.0.0-rc.0",
"version": "8.0.0",
"description": "Base components for Ionic",
"keywords": [
"ionic",
@@ -54,12 +54,13 @@
"@types/node": "^14.6.0",
"@typescript-eslint/eslint-plugin": "^6.7.2",
"@typescript-eslint/parser": "^6.7.2",
"chalk": "^5.3.0",
"clean-css-cli": "^5.6.1",
"domino": "^2.1.6",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-custom-rules": "file:custom-rules",
"execa": "^5.0.0",
"execa": "^8.0.1",
"fs-extra": "^9.0.1",
"jest": "^29.7.0",
"jest-cli": "^29.7.0",
@@ -67,16 +68,14 @@
"rollup": "^2.26.4",
"sass": "^1.33.0",
"serve": "^14.0.1",
"style-dictionary": "^3.9.2",
"stylelint": "^13.13.1",
"stylelint-order": "^4.1.0"
},
"scripts": {
"build": "npm run clean && npm run build.tokens && npm run build.css && stencil build --es5 --docs-json dist/docs.json",
"build": "npm run clean && npm run build.css && stencil build --es5 --docs-json dist/docs.json",
"build.css": "npm run css.sass && npm run css.minify",
"build.debug": "npm run clean && stencil build --debug",
"build.docs.json": "stencil build --docs-json dist/docs.json",
"build.tokens": "node ./scripts/tokens.js && npm run lint.sass.fix",
"clean": "node scripts/clean.js",
"css.minify": "cleancss -O2 -o ./css/ionic.bundle.css ./css/ionic.bundle.css",
"css.sass": "sass --embed-sources --style compressed src/css:./css",
@@ -98,10 +97,9 @@
"test.treeshake": "node scripts/treeshaking.js dist/index.js",
"validate": "npm run lint && npm run test && npm run build && npm run test.treeshake",
"docker.build": "docker build -t ionic-playwright .",
"test.e2e.docker": "npm run docker.build && docker run -it --rm -e DISPLAY=$(cat docker-display.txt) -v $(cat docker-display-volume.txt) --ipc=host --mount=type=bind,source=./,target=/ionic ionic-playwright npm run test.e2e --",
"test.e2e.docker": "npm run docker.build && node ./scripts/docker.mjs",
"test.e2e.docker.update-snapshots": "npm run test.e2e.docker -- --update-snapshots",
"test.e2e.docker.ci": "npm run docker.build && docker run -e CI='true' --rm --ipc=host --mount=type=bind,source=./,target=/ionic ionic-playwright npm run test.e2e --",
"test.report": "npx playwright show-report"
"test.e2e.docker.ci": "npm run docker.build && CI=true node ./scripts/docker.mjs"
},
"author": "Ionic Team",
"license": "MIT",

56
core/scripts/docker.mjs Normal file
View File

@@ -0,0 +1,56 @@
import { execa } from 'execa';
import * as fs from 'fs';
import { resolve } from 'path';
import chalk from 'chalk';
const removeNewline = (string) => {
return string.replace(/(\r\n|\n|\r)/gm, "");
}
const readConfigFile = (file) => {
if (fs.existsSync(file)) {
return fs.readFileSync(file, { encoding: 'utf-8' });
}
return '';
}
// These files are optional, so we don't want to error if they don't exist
const display = removeNewline(readConfigFile('docker-display.txt'));
const displayVolume = removeNewline(readConfigFile('docker-display-volume.txt'));
// Using --mount requires an absolute path which is what this gives us.
const pwd = resolve('./');
/**
* -it will let the user gracefully kill the process using Ctrl+C (or equivalent)
* -e DISPLAY and -v handle configuration for headed mode
* --ipc=host is recommended when using Chromium to avoid out of memory crashes: https://playwright.dev/docs/ci#docker
* --init is recommended to avoid zombie processes: https://playwright.dev/docs/ci#docker
* --mount allow us to mount the local Ionic project inside of the Docker container so devs do not need to re-build the project in Docker.
*/
const args = ['run', '--rm', '--init', `-e DISPLAY=${display}`, `-v ${displayVolume}`, '--ipc=host', `--mount=type=bind,source=${pwd},target=/ionic`, 'ionic-playwright', 'npm run test.e2e --', ...process.argv.slice(2)];
// Set the CI env variable so Playwright uses the CI config
if (process.env.CI) {
args.splice(1, 0, '-e CI=true');
/**
* Otherwise, we should let the session be interactive locally. This will
* not work on CI which is why we do not apply it there.
*/
} else {
args.splice(1, 0, '-it');
}
/**
* While these config files are optional to run the tests, they are required to run
* the tests in headed mode. Add a warning if dev tries to run headed tests without
* the correct config files.
*/
const requestHeaded = process.argv.find(arg => arg.includes('headed'));
const hasHeadedConfigFiles = display && displayVolume;
if (requestHeaded && !hasHeadedConfigFiles) {
console.warn(chalk.yellow.bold('\n⚠ You are running tests in headed mode, but one or more of your headed config files was not found.\nPlease ensure that both docker-display.txt and docker-display-volume.txt have been created in the correct location.\n'));
}
execa('docker', args, { shell: true, stdio: 'inherit' });

View File

@@ -1,174 +0,0 @@
/* For generating Design Tokens, we use Style Dictionary for several reasons:
- It's prepared to easily generate tokens for multiple types of outputs (CSS, SCSS, iOS, Android, documentation, etc.).
- It also works very well out of the box with any kind of Design Tokens formats, like Figma Tokens, as well as APIs to adjust to more custom ones.
- It is probably the most well-known and widely used Design Tokens tool. It has also been regularly maintained for a long time.
- It can easily scale to different necessities we might have in the future.
*/
// eslint-disable-next-line @typescript-eslint/no-var-requires
const StyleDictionary = require('style-dictionary');
const { fileHeader } = StyleDictionary.formatHelpers;
// Empty for as an example of how we can add some extra variables, not from the tokens JSON
const customVariables = ``;
// Prefix for all generated variables
const variablesPrefix = 'ionic';
// CSS vanilla :root format
StyleDictionary.registerFormat({
name: 'rootFormat',
formatter({ dictionary, file }) {
// Add a prefix to all variable names
const prefixedVariables = dictionary.allProperties.map((prop) => {
return ` --${variablesPrefix}-${prop.name}: ${prop.value};`;
});
return (
fileHeader({ file }) +
':root {\n' +
prefixedVariables.join('\n') + // Join all prefixed variables with a newline
customVariables +
'\n}\n'
);
},
});
// scss variables format
StyleDictionary.registerFormat({
name: 'scssVariablesFormat',
formatter({ dictionary, file }) {
// Add a prefix to all variable names
const prefixedVariables = dictionary.allProperties.map((prop) => {
return `$${variablesPrefix}-${prop.name}: var(--${variablesPrefix}-${prop.name}, ${prop.value});`;
});
return (
fileHeader({ file }) +
prefixedVariables.join('\n') + // Join all prefixed variables with a newline
customVariables +
'\n'
);
},
});
// Create utility-classes
StyleDictionary.registerFormat({
name: 'cssUtilityClassesFormat',
formatter({ dictionary, file }) {
const utilityClasses = dictionary.allProperties.map((prop) => {
let tokenType = prop.attributes.category;
const className = `${prop.name}`;
let utilityClass = '';
switch (tokenType) {
case 'color':
utilityClass = `.${variablesPrefix}-${className} {\n color: $ionic-${prop.name};\n}
.${variablesPrefix}-background-${className} {\n background-color: $ionic-${prop.name};\n}`;
break;
case 'border':
const borderAttribute = prop.attributes.type === 'radius' ? 'border-radius' : 'border-width';
utilityClass = `.${variablesPrefix}-${className} {\n ${borderAttribute}: $ionic-${prop.name};\n}`;
break;
case 'font':
let fontAttribute;
switch (prop.attributes.type) {
case 'size':
fontAttribute = 'font-size';
break;
case 'weight':
fontAttribute = 'font-weight';
break;
case 'line-height':
fontAttribute = 'line-height';
break;
case 'letter-spacing':
fontAttribute = 'letter-spacing';
break;
case 'family':
return;
}
utilityClass = `.${variablesPrefix}-${className} {\n ${fontAttribute}: $ionic-${prop.name};\n}`;
break;
case 'elevation':
utilityClass = `.${variablesPrefix}-${className} {\n box-shadow: $ionic-${prop.name};\n}`;
break;
case 'space':
utilityClass = `.${variablesPrefix}-margin-${className} {\n margin: $ionic-${prop.name};\n};
.${variablesPrefix}-padding-${className} {\n padding: $ionic-${prop.name};\n}`;
break;
default:
utilityClass = `.${variablesPrefix}-${className} {\n ${tokenType}: $ionic-${prop.name};\n}`;
}
return utilityClass;
});
return [fileHeader({ file }), '@import "./ionic.vars";\n', utilityClasses.join('\n')].join('\n');
},
});
// Make Style Dictionary comply with the $ format on properties from W3C Guidelines
const w3cTokenJsonParser = {
pattern: /\.json|\.tokens\.json|\.tokens$/,
parse(_a) {
var contents = _a.contents;
// replace $value with value so that style dictionary recognizes it
var preparedContent = (contents || '{}')
.replace(/"\$?value":/g, '"value":')
// convert $description to comment
.replace(/"\$?description":/g, '"comment":');
//
return JSON.parse(preparedContent);
},
};
StyleDictionary.registerParser(w3cTokenJsonParser);
// Generate Tokens
StyleDictionary.extend({
source: ['./src/foundations/*.json'],
platforms: {
css: {
buildPath: './src/foundations/',
transformGroup: 'css',
files: [
{
destination: 'ionic.root.scss',
format: 'rootFormat',
options: {
outputReferences: true,
fileHeader: `myFileHeader`,
},
},
],
},
scss: {
buildPath: './src/foundations/',
transformGroup: 'scss',
files: [
{
destination: 'ionic.vars.scss',
format: 'scssVariablesFormat',
options: {
outputReferences: true,
fileHeader: `myFileHeader`,
},
},
{
destination: 'ionic.utility.scss',
format: 'cssUtilityClassesFormat',
options: {
outputReferences: true,
fileHeader: `myFileHeader`,
},
},
],
},
},
fileHeader: {
myFileHeader: () => {
return [`This is an auto-generated file, please do not change it directly.`, `Ionic Design System`];
},
},
}).buildAllPlatforms();

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

File diff suppressed because it is too large Load Diff

View File

@@ -2,20 +2,18 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core';
import { Component, Element, Event, Host, Listen, Method, Prop, Watch, h } from '@stencil/core';
import { printIonWarning } from '@utils/logging';
import { getIonTheme } from '../../global/ionic-global';
import { getIonMode } from '../../global/ionic-global';
import type { AccordionGroupChangeEventDetail } from './accordion-group-interface';
/**
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the visual appearance of the component.
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
*/
@Component({
tag: 'ion-accordion-group',
styleUrls: {
ios: 'accordion-group.ios.scss',
md: 'accordion-group.md.scss',
ionic: 'accordion-group.md.scss',
},
shadow: true,
})
@@ -281,12 +279,12 @@ export class AccordionGroup implements ComponentInterface {
render() {
const { disabled, readonly, expand } = this;
const theme = getIonTheme(this);
const mode = getIonMode(this);
return (
<Host
class={{
[theme]: true,
[mode]: true,
'accordion-group-disabled': disabled,
'accordion-group-readonly': readonly,
[`accordion-group-expand-${expand}`]: true,

View File

@@ -4,7 +4,7 @@ import { addEventListener, getElementRoot, raf, removeEventListener, transitionE
import { chevronDown } from 'ionicons/icons';
import { config } from '../../global/config';
import { getIonTheme } from '../../global/ionic-global';
import { getIonMode } from '../../global/ionic-global';
const enum AccordionState {
Collapsed = 1 << 0,
@@ -14,8 +14,7 @@ const enum AccordionState {
}
/**
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the visual appearance of the component.
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
*
* @slot header - Content is placed at the top and is used to
* expand or collapse the accordion item.
@@ -32,7 +31,6 @@ const enum AccordionState {
styleUrls: {
ios: 'accordion.ios.scss',
md: 'accordion.md.scss',
ionic: 'accordion.md.scss',
},
shadow: {
delegatesFocus: true,
@@ -404,7 +402,7 @@ export class Accordion implements ComponentInterface {
render() {
const { disabled, readonly } = this;
const theme = getIonTheme(this);
const mode = getIonMode(this);
const expanded = this.state === AccordionState.Expanded || this.state === AccordionState.Expanding;
const headerPart = expanded ? 'header expanded' : 'header';
const contentPart = expanded ? 'content expanded' : 'content';
@@ -414,7 +412,7 @@ export class Accordion implements ComponentInterface {
return (
<Host
class={{
[theme]: true,
[mode]: true,
'accordion-expanding': this.state === AccordionState.Expanding,
'accordion-expanded': this.state === AccordionState.Expanded,
'accordion-collapsing': this.state === AccordionState.Collapsing,

View File

@@ -1,16 +1,20 @@
import type { OverlayOptions } from '@utils/overlays-interface';
import type { AnimationBuilder, LiteralUnion, Mode } from '../../interface';
import type { LiteralUnion } from '../../interface';
export interface ActionSheetOptions extends OverlayOptions {
export interface ActionSheetOptions {
header?: string;
subHeader?: string;
cssClass?: string | string[];
buttons: (ActionSheetButton | string)[];
backdropDismiss?: boolean;
translucent?: boolean;
animated?: boolean;
mode?: Mode;
keyboardClose?: boolean;
id?: string;
htmlAttributes?: { [key: string]: any };
enterAnimation?: AnimationBuilder;
leaveAnimation?: AnimationBuilder;
}
export interface ActionSheetButton<T = any> {

View File

@@ -18,7 +18,7 @@ import {
} from '@utils/overlays';
import { getClassMap } from '@utils/theme';
import { getIonMode, getIonTheme } from '../../global/ionic-global';
import { getIonMode } from '../../global/ionic-global';
import type { AnimationBuilder, CssClassMap, FrameworkDelegate, OverlayInterface } from '../../interface';
import type { OverlayEventDetail } from '../../utils/overlays-interface';
@@ -29,15 +29,13 @@ import { mdEnterAnimation } from './animations/md.enter';
import { mdLeaveAnimation } from './animations/md.leave';
/**
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the visual appearance of the component.
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
*/
@Component({
tag: 'ion-action-sheet',
styleUrls: {
ios: 'action-sheet.ios.scss',
md: 'action-sheet.md.scss',
ionic: 'action-sheet.md.scss',
},
scoped: true,
})
@@ -107,7 +105,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
/**
* If `true`, the action sheet will be translucent.
* Only applies when the theme is `"ios"` and the device supports
* Only applies when the mode is `"ios"` and the device supports
* [`backdrop-filter`](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter#Browser_compatibility).
*/
@Prop() translucent = false;
@@ -316,7 +314,6 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
}
componentDidLoad() {
const mode = getIonMode(this);
/**
* Only create gesture if:
* 1. A gesture does not already exist
@@ -325,7 +322,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
* 4. A group ref exists
*/
const { groupEl, wrapperEl } = this;
if (!this.gesture && mode === 'ios' && wrapperEl && groupEl) {
if (!this.gesture && getIonMode(this) === 'ios' && wrapperEl && groupEl) {
readTask(() => {
const isScrollable = groupEl.scrollHeight > groupEl.clientHeight;
if (!isScrollable) {
@@ -359,7 +356,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
render() {
const { header, htmlAttributes, overlayIndex } = this;
const theme = getIonTheme(this);
const mode = getIonMode(this);
const allButtons = this.getButtons();
const cancelButton = allButtons.find((b) => b.role === 'cancel');
const buttons = allButtons.filter((b) => b.role !== 'cancel');
@@ -376,7 +373,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
zIndex: `${20000 + this.overlayIndex}`,
}}
class={{
[theme]: true,
[mode]: true,
...getClassMap(this.cssClass),
'overlay-hidden': true,
'action-sheet-translucent': this.translucent,
@@ -416,7 +413,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
{b.icon && <ion-icon icon={b.icon} aria-hidden="true" lazy={false} class="action-sheet-icon" />}
{b.text}
</span>
{theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
</button>
))}
</div>
@@ -440,7 +437,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
)}
{cancelButton.text}
</span>
{theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
</button>
</div>
)}

View File

@@ -1,9 +1,7 @@
import type { OverlayOptions } from '@utils/overlays-interface';
import type { LiteralUnion, TextFieldTypes } from '../../interface';
import type { AnimationBuilder, LiteralUnion, Mode, TextFieldTypes } from '../../interface';
import type { IonicSafeString } from '../../utils/sanitization';
export interface AlertOptions extends OverlayOptions {
export interface AlertOptions {
header?: string;
subHeader?: string;
message?: string | IonicSafeString;
@@ -12,9 +10,15 @@ export interface AlertOptions extends OverlayOptions {
buttons?: (AlertButton | string)[];
backdropDismiss?: boolean;
translucent?: boolean;
animated?: boolean;
htmlAttributes?: { [key: string]: any };
mode?: Mode;
keyboardClose?: boolean;
id?: string;
enterAnimation?: AnimationBuilder;
leaveAnimation?: AnimationBuilder;
}
export interface AlertInput {

View File

@@ -21,7 +21,7 @@ import { sanitizeDOMString } from '@utils/sanitization';
import { getClassMap } from '@utils/theme';
import { config } from '../../global/config';
import { getIonMode, getIonTheme } from '../../global/ionic-global';
import { getIonMode } from '../../global/ionic-global';
import type { AnimationBuilder, CssClassMap, OverlayInterface, FrameworkDelegate } from '../../interface';
import type { OverlayEventDetail } from '../../utils/overlays-interface';
import type { IonicSafeString } from '../../utils/sanitization';
@@ -35,15 +35,13 @@ import { mdLeaveAnimation } from './animations/md.leave';
// TODO(FW-2832): types
/**
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the visual appearance of the component.
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
*/
@Component({
tag: 'ion-alert',
styleUrls: {
ios: 'alert.ios.scss',
md: 'alert.md.scss',
ionic: 'alert.md.scss',
},
scoped: true,
})
@@ -137,7 +135,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
/**
* If `true`, the alert will be translucent.
* Only applies when the theme is `"ios"` and the device supports
* Only applies when the mode is `"ios"` and the device supports
* [`backdrop-filter`](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter#Browser_compatibility).
*/
@Prop() translucent = false;
@@ -535,7 +533,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
private renderCheckbox() {
const inputs = this.processedInputs;
const theme = getIonTheme(this);
const mode = getIonMode(this);
if (inputs.length === 0) {
return null;
@@ -567,7 +565,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
</div>
<div class="alert-checkbox-label">{i.label}</div>
</div>
{theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
</button>
))}
</div>
@@ -684,7 +682,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
private renderAlertButtons() {
const buttons = this.processedButtons;
const theme = getIonTheme(this);
const mode = getIonMode(this);
const alertButtonGroupClass = {
'alert-button-group': true,
'alert-button-group-vertical': buttons.length > 2,
@@ -701,7 +699,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
onClick={() => this.buttonClick(button)}
>
<span class="alert-button-inner">{button.text}</span>
{theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
</button>
))}
</div>
@@ -723,7 +721,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
render() {
const { overlayIndex, header, subHeader, message, htmlAttributes } = this;
const theme = getIonTheme(this);
const mode = getIonMode(this);
const hdrId = `alert-${overlayIndex}-hdr`;
const subHdrId = `alert-${overlayIndex}-sub-hdr`;
const msgId = `alert-${overlayIndex}-msg`;
@@ -748,7 +746,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
}}
class={{
...getClassMap(this.cssClass),
[theme]: true,
[mode]: true,
'overlay-hidden': true,
'alert-translucent': this.translucent,
}}

View File

@@ -6,12 +6,8 @@ import { printIonWarning } from '@utils/logging';
import { isPlatform } from '@utils/platform';
import { config } from '../../global/config';
import { getIonTheme } from '../../global/ionic-global';
import { getIonMode } from '../../global/ionic-global';
/**
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the visual appearance of the component.
*/
@Component({
tag: 'ion-app',
styleUrl: 'app.scss',
@@ -82,11 +78,11 @@ export class App implements ComponentInterface {
}
render() {
const theme = getIonTheme(this);
const mode = getIonMode(this);
return (
<Host
class={{
[theme]: true,
[mode]: true,
'ion-page': true,
'force-statusbar-padding': config.getBoolean('_forceStatusbarPadding'),
}}

View File

@@ -1,30 +1,20 @@
import type { ComponentInterface } from '@stencil/core';
import { Component, Host, h } from '@stencil/core';
import { getIonTheme } from '../../global/ionic-global';
import { getIonMode } from '../../global/ionic-global';
/**
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the visual appearance of the component.
*/
@Component({
tag: 'ion-avatar',
styleUrls: {
ios: 'avatar.ios.scss',
md: 'avatar.md.scss',
ionic: 'avatar.md.scss',
},
shadow: true,
})
export class Avatar implements ComponentInterface {
render() {
const theme = getIonTheme(this);
return (
<Host
class={{
[theme]: true,
}}
>
<Host class={getIonMode(this)}>
<slot></slot>
</Host>
);

View File

@@ -7,12 +7,11 @@ import { createColorClasses, hostContext, openURL } from '@utils/theme';
import { arrowBackSharp, chevronBack } from 'ionicons/icons';
import { config } from '../../global/config';
import { getIonTheme } from '../../global/ionic-global';
import { getIonMode } from '../../global/ionic-global';
import type { AnimationBuilder, Color } from '../../interface';
/**
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the visual appearance of the component.
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
*
* @part native - The native HTML button element that wraps all child elements.
* @part icon - The back button icon (uses ion-icon).
@@ -23,7 +22,6 @@ import type { AnimationBuilder, Color } from '../../interface';
styleUrls: {
ios: 'back-button.ios.scss',
md: 'back-button.md.scss',
ionic: 'back-button.md.scss',
},
shadow: true,
})
@@ -86,7 +84,7 @@ export class BackButton implements ComponentInterface, ButtonInterface {
return icon;
}
if (getIonTheme(this) === 'ios') {
if (getIonMode(this) === 'ios') {
// default ios back button icon
return config.get('backButtonIcon', chevronBack);
}
@@ -96,7 +94,7 @@ export class BackButton implements ComponentInterface, ButtonInterface {
}
get backButtonText() {
const defaultBackButtonText = getIonTheme(this) === 'ios' ? 'Back' : null;
const defaultBackButtonText = getIonMode(this) === 'ios' ? 'Back' : null;
return this.text != null ? this.text : config.get('backButtonText', defaultBackButtonText);
}
@@ -137,14 +135,14 @@ export class BackButton implements ComponentInterface, ButtonInterface {
inheritedAttributes,
} = this;
const showBackButton = defaultHref !== undefined;
const theme = getIonTheme(this);
const mode = getIonMode(this);
const ariaLabel = inheritedAttributes['aria-label'] || backButtonText || 'back';
return (
<Host
onClick={this.onClick}
class={createColorClasses(color, {
[theme]: true,
[mode]: true,
button: true, // ion-buttons target .button
'back-button-disabled': disabled,
'back-button-has-icon-only': hasIconOnly,
@@ -172,7 +170,7 @@ export class BackButton implements ComponentInterface, ButtonInterface {
</span>
)}
</span>
{theme === 'md' && <ion-ripple-effect type={this.rippleType}></ion-ripple-effect>}
{mode === 'md' && <ion-ripple-effect type={this.rippleType}></ion-ripple-effect>}
</button>
</Host>
);

View File

@@ -1,18 +1,13 @@
import type { ComponentInterface, EventEmitter } from '@stencil/core';
import { Component, Event, Host, Listen, Prop, h } from '@stencil/core';
import { getIonTheme } from '../../global/ionic-global';
import { getIonMode } from '../../global/ionic-global';
/**
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the visual appearance of the component.
*/
@Component({
tag: 'ion-backdrop',
styleUrls: {
ios: 'backdrop.ios.scss',
md: 'backdrop.md.scss',
ionic: 'backdrop.md.scss',
},
shadow: true,
})
@@ -53,13 +48,13 @@ export class Backdrop implements ComponentInterface {
}
render() {
const theme = getIonTheme(this);
const mode = getIonMode(this);
return (
<Host
tabindex="-1"
aria-hidden="true"
class={{
[theme]: true,
[mode]: true,
'backdrop-hide': !this.visible,
'backdrop-no-tappable': !this.tappable,
}}

View File

@@ -2,19 +2,17 @@ import type { ComponentInterface } from '@stencil/core';
import { Component, Host, Prop, h } from '@stencil/core';
import { createColorClasses } from '@utils/theme';
import { getIonTheme } from '../../global/ionic-global';
import { getIonMode } from '../../global/ionic-global';
import type { Color } from '../../interface';
/**
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the visual appearance of the component.
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
*/
@Component({
tag: 'ion-badge',
styleUrls: {
ios: 'badge.ios.scss',
md: 'badge.md.scss',
ionic: 'badge.md.scss',
},
shadow: true,
})
@@ -27,11 +25,11 @@ export class Badge implements ComponentInterface {
@Prop({ reflect: true }) color?: Color;
render() {
const theme = getIonTheme(this);
const mode = getIonMode(this);
return (
<Host
class={createColorClasses(this.color, {
[theme]: true,
[mode]: true,
})}
>
<slot></slot>

View File

@@ -5,15 +5,14 @@ import { inheritAriaAttributes } from '@utils/helpers';
import { createColorClasses, hostContext, openURL } from '@utils/theme';
import { chevronForwardOutline, ellipsisHorizontal } from 'ionicons/icons';
import { getIonTheme } from '../../global/ionic-global';
import { getIonMode } from '../../global/ionic-global';
import type { AnimationBuilder, Color } from '../../interface';
import type { RouterDirection } from '../router/utils/interface';
import type { BreadcrumbCollapsedClickEventDetail } from './breadcrumb-interface';
/**
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the visual appearance of the component.
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
*
* @part native - The native HTML anchor or div element that wraps all child elements.
* @part separator - The separator element between each breadcrumb.
@@ -24,7 +23,6 @@ import type { BreadcrumbCollapsedClickEventDetail } from './breadcrumb-interface
styleUrls: {
ios: 'breadcrumb.ios.scss',
md: 'breadcrumb.md.scss',
ionic: 'breadcrumb.md.scss',
},
shadow: true,
})
@@ -170,7 +168,7 @@ export class Breadcrumb implements ComponentInterface {
// Links can still be tabbed to when set to disabled if they have an href
// in order to truly disable them we can keep it as an anchor but remove the href
const href = disabled ? undefined : this.href;
const theme = getIonTheme(this);
const mode = getIonMode(this);
const attrs =
TagType === 'span'
? {}
@@ -190,7 +188,7 @@ export class Breadcrumb implements ComponentInterface {
onClick={(ev: Event) => openURL(href, ev, routerDirection, routerAnimation)}
aria-disabled={disabled ? 'true' : null}
class={createColorClasses(color, {
[theme]: true,
[mode]: true,
'breadcrumb-active': active,
'breadcrumb-collapsed': collapsed,
'breadcrumb-disabled': disabled,
@@ -235,7 +233,7 @@ export class Breadcrumb implements ComponentInterface {
*/
<span class="breadcrumb-separator" part="separator" aria-hidden="true">
<slot name="separator">
{theme === 'ios' ? (
{mode === 'ios' ? (
<ion-icon icon={chevronForwardOutline} lazy={false} flip-rtl></ion-icon>
) : (
<span>/</span>

View File

@@ -2,20 +2,19 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core';
import { Component, Element, Event, Host, Listen, Prop, State, Watch, h } from '@stencil/core';
import { createColorClasses, hostContext } from '@utils/theme';
import { getIonTheme } from '../../global/ionic-global';
import { getIonMode } from '../../global/ionic-global';
import type { Color } from '../../interface';
import type { BreadcrumbCollapsedClickEventDetail } from '../breadcrumb/breadcrumb-interface';
/**
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the visual appearance of the component.
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
*
*/
@Component({
tag: 'ion-breadcrumbs',
styleUrls: {
ios: 'breadcrumbs.ios.scss',
md: 'breadcrumbs.md.scss',
ionic: 'breadcrumbs.md.scss',
},
shadow: true,
})
@@ -171,12 +170,12 @@ export class Breadcrumbs implements ComponentInterface {
render() {
const { color, collapsed } = this;
const theme = getIonTheme(this);
const mode = getIonMode(this);
return (
<Host
class={createColorClasses(color, {
[theme]: true,
[mode]: true,
'in-toolbar': hostContext('ion-toolbar', this.el),
'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
'breadcrumbs-collapsed': collapsed,

View File

@@ -1,237 +0,0 @@
@import "./button";
@import "./button.ionic.vars";
// Ionic Button
// -------------------------------------------------------------------------------
:host {
--border-radius: #{$button-ionic-border-radius};
--padding-bottom: var(--padding-top);
--padding-end: #{$button-ionic-padding-end};
--padding-start: var(--padding-end);
--padding-top: #{$button-ionic-padding-top};
--focus-ring-color: #9ec4fd;
--focus-ring-width: 2px;
position: relative;
min-height: #{$button-ionic-min-height};
font-size: #{$button-ionic-font-size};
// Target area
&::after {
@include position(50%, 0, null, 0);
position: absolute;
height: 100%;
min-height: px-to-rem(48);
transform: translateY(-50%);
content: "";
cursor: pointer;
z-index: 1;
}
::slotted(ion-icon[slot="start"]) {
@include margin-horizontal(null, px-to-rem(8));
}
::slotted(ion-icon[slot="end"]) {
@include margin-horizontal(px-to-rem(8), null);
}
}
// Button Sizes
// -------------------------------------------------------------------------------
/* Extra Small and Small Button */
:host(.button-xsmall),
:host(.button-small) {
::slotted(ion-icon[slot="start"]) {
@include margin-horizontal(null, px-to-rem(4));
}
::slotted(ion-icon[slot="end"]) {
@include margin-horizontal(px-to-rem(4), null);
}
}
/* Extra Small Button */
:host(.button-xsmall) {
--border-radius: #{$button-ionic-xsmall-border-radius};
--padding-top: #{$button-ionic-xsmall-padding-top};
--padding-end: #{$button-ionic-xsmall-padding-end};
min-height: #{$button-ionic-xsmall-min-height};
font-size: #{$button-ionic-xsmall-font-size};
}
/* Small Button */
:host(.button-small) {
--border-radius: #{$button-ionic-small-border-radius};
--padding-top: #{$button-ionic-small-padding-top};
--padding-end: #{$button-ionic-small-padding-end};
min-height: #{$button-ionic-small-min-height};
font-size: #{$button-ionic-small-font-size};
}
/* Large Button */
:host(.button-large) {
--padding-top: #{$button-ionic-large-padding-top};
--padding-end: #{$button-ionic-large-padding-end};
min-height: #{$button-ionic-large-min-height};
font-size: #{$button-ionic-large-font-size};
}
/* Extra Large Button */
:host(.button-xlarge) {
--padding-top: #{$button-ionic-xlarge-padding-top};
--padding-end: #{$button-ionic-xlarge-padding-end};
min-height: #{$button-ionic-xlarge-min-height};
font-size: #{$button-ionic-xlarge-font-size};
}
// Button with Icons
// -------------------------------------------------------------------------------
/* Button containing only an icon */
::slotted(ion-icon[slot="start"]),
::slotted(ion-icon[slot="end"]),
::slotted(ion-icon[slot="icon-only"]) {
font-size: px-to-rem(16);
}
:host(.button-xsmall),
:host(.button-small),
:host(.button-large),
:host(.button-xlarge) {
::slotted(ion-icon[slot="start"]),
::slotted(ion-icon[slot="end"]),
::slotted(ion-icon[slot="icon-only"]) {
font-size: 1em;
}
}
/* Button extra small */
:host(.button-has-icon-only.button-xsmall) {
--padding-end: #{$button-has-icon-only-padding-end-xsmall};
}
/* Button small */
:host(.button-has-icon-only.button-small) {
--padding-end: #{$button-has-icon-only-padding-end-small};
}
/* Default */
:host(.button-has-icon-only) {
--padding-end: #{$button-has-icon-only-padding-end};
}
/* Button large */
:host(.button-has-icon-only.button-large) {
--padding-end: #{$button-has-icon-only-padding-end-large};
}
/* Button extra large */
:host(.button-has-icon-only.button-xlarge) {
--padding-end: #{$button-has-icon-only-padding-end-xlarge};
}
// Button Shapes
// -------------------------------------------------------------------------------
// Button Shape Rectangular
// -------------------------------------------------------------------------------
:host(.button-rectangular) {
--border-radius: #{$button-ionic-rectangular-border};
}
// Button Shape Round
// -------------------------------------------------------------------------------
:host(.button-round) {
--border-radius: #{$button-ionic-round-border};
}
// Button Focused
// -------------------------------------------------------------------------------
// Only show the focus ring when the button is focused
:host(.ion-focused) .button-native {
outline: var(--focus-ring-width) solid var(--focus-ring-color);
outline-offset: 2px;
}
// Fill Solid Button
// -------------------------------------------------------------------------------
:host(.button-solid) {
--background-activated: #{ion-color(primary, shade)};
}
:host(.button-solid.ion-color.ion-activated) .button-native::after {
background: #{current-color(shade)};
}
// Fill Outline Button
// --------------------------------------------------
:host(.button-outline) {
--border-width: #{$button-ionic-outline-border-width};
--border-style: #{$button-ionic-outline-border-style};
--background-activated: #e3e3e3;
--background-activated-opacity: 1;
--background-focused: transparent;
--background-hover: transparent;
--background-focused-opacity: 0.1;
--color-activated: #{ion-color(primary, base)};
}
:host(.button-outline.ion-focused) {
--border-color: transparent;
}
// Fill Clear Button
// --------------------------------------------------
:host(.button-clear) {
--background-activated: #e3e3e3;
--background-activated-opacity: 1;
--background-focused: transparent;
--background-hover: transparent;
}
// Button Hover
// --------------------------------------------------
:host(.button-outline),
:host(.button-clear) {
--background-hover: #121212;
--background-hover-opacity: 0.04;
}
// Button: Disabled
// --------------------------------------------------
:host(.button-disabled) {
--color: #c9c9c9;
--border-color: var(--color);
opacity: 1;
}
:host(.button-solid.button-disabled) {
--background: #f5f5f5;
}

View File

@@ -1,164 +0,0 @@
@import "../../themes/ionic.globals.ios";
// Ionic Button
// -------------------------------------------------------------------------------
/// @prop - Border radius of the button
$button-ionic-border-radius: px-to-rem(8) !default;
/// @prop - Padding top of the button
$button-ionic-padding-top: px-to-rem(12) !default;
/// @prop - Padding end of the button
$button-ionic-padding-end: px-to-rem(16) !default;
/// @prop - Padding bottom of the button
$button-ionic-padding-bottom: $button-ionic-padding-top !default;
/// @prop - Padding start of the button
$button-ionic-padding-start: $button-ionic-padding-end !default;
/// @prop - Minimum height of the button
$button-ionic-min-height: px-to-rem(40) !default;
/// @prop - Font size of the button text
/// The maximum font size is calculated by taking the default font size
/// and multiplying it by 3, since 310% of the default is the maximum
$button-ionic-font-size: dynamic-font-max(14px, 3) !default;
// Ionic Extra Small Button
// -------------------------------------------------------------------------------
/// @prop - Border radius of the extra small button
$button-ionic-xsmall-border-radius: px-to-rem(4) !default;
/// @prop - Padding top of the extra small button
$button-ionic-xsmall-padding-top: px-to-rem(4) !default;
/// @prop - Padding end of the extra small button
$button-ionic-xsmall-padding-end: px-to-rem(12) !default;
/// @prop - Padding bottom of the extra small button
$button-ionic-xsmall-padding-bottom: $button-ionic-xsmall-padding-top !default;
/// @prop - Padding start of the extra small button
$button-ionic-xsmall-padding-start: $button-ionic-xsmall-padding-end !default;
/// @prop - Minimum height of the extra small button
$button-ionic-xsmall-min-height: px-to-rem(24) !default;
/// @prop - Font size of the extra small button text
/// The maximum font size is calculated by taking the default font size
/// and multiplying it by 3, since 310% of the default is the maximum
$button-ionic-xsmall-font-size: dynamic-font-max(12px, 3) !default;
// Ionic Small Button
// -------------------------------------------------------------------------------
/// @prop - Border radius of the small button
$button-ionic-small-border-radius: px-to-rem(4) !default;
/// @prop - Padding top of the small button
$button-ionic-small-padding-top: px-to-rem(8) !default;
/// @prop - Padding end of the small button
$button-ionic-small-padding-end: px-to-rem(16) !default;
/// @prop - Padding bottom of the small button
$button-ionic-small-padding-bottom: $button-ionic-small-padding-top !default;
/// @prop - Padding start of the small button
$button-ionic-small-padding-start: $button-ionic-small-padding-end !default;
/// @prop - Minimum height of the small button
$button-ionic-small-min-height: px-to-rem(32) !default;
/// @prop - Font size of the small button text
/// The maximum font size is calculated by taking the default font size
/// and multiplying it by 3, since 310% of the default is the maximum
$button-ionic-small-font-size: dynamic-font-max(12px, 3) !default;
// Ionic Large Button
// -------------------------------------------------------------------------------
/// @prop - Padding top of the large button
$button-ionic-large-padding-top: px-to-rem(16) !default;
/// @prop - Padding end of the large button
$button-ionic-large-padding-end: px-to-rem(24) !default;
/// @prop - Padding bottom of the large button
$button-ionic-large-padding-bottom: $button-ionic-large-padding-top !default;
/// @prop - Padding start of the large button
$button-ionic-large-padding-start: $button-ionic-large-padding-end !default;
/// @prop - Minimum height of the large button
$button-ionic-large-min-height: px-to-rem(48) !default;
/// @prop - Font size of the large button text
/// The maximum font size is calculated by taking the default font size
/// and multiplying it by 3, since 310% of the default is the maximum
$button-ionic-large-font-size: dynamic-font-max(16px, 3) !default;
// Ionic Extra Large Button
// -------------------------------------------------------------------------------
/// @prop - Padding top of the extra large button
$button-ionic-xlarge-padding-top: px-to-rem(16) !default;
/// @prop - Padding end of the extra large button
$button-ionic-xlarge-padding-end: px-to-rem(32) !default;
/// @prop - Padding bottom of the extra large button
$button-ionic-xlarge-padding-bottom: $button-ionic-xlarge-padding-top !default;
/// @prop - Padding start of the extra large button
$button-ionic-xlarge-padding-start: $button-ionic-xlarge-padding-end !default;
/// @prop - Minimum height of the extra large button
$button-ionic-xlarge-min-height: px-to-rem(56) !default;
/// @prop - Font size of the extra large button text
/// The maximum font size is calculated by taking the default font size
/// and multiplying it by 3, since 310% of the default is the maximum
$button-ionic-xlarge-font-size: dynamic-font-max(20px, 3) !default;
// Ionic Rectangular Button
// -------------------------------------------------------------------------------
/// @prop - Border radius of the rectangular button
$button-ionic-rectangular-border: 0 !default;
// Ionic Round Button
// -------------------------------------------------------------------------------
/// @prop - Border radius of the round button
$button-ionic-round-border: px-to-rem(999) !default;
// Ionic Outline Button
// -------------------------------------------------------------------------------
/// @prop - Border width of the outline button
$button-ionic-outline-border-width: 1px !default;
/// @prop - Border style of the outline button
$button-ionic-outline-border-style: solid !default;
// Ionic Icon Only Button
// -------------------------------------------------------------------------------
/// @prop - Padding end of the icon only button
$button-has-icon-only-padding-end: px-to-rem(13) !default;
/// @prop - Padding end of the icon only extra small button
$button-has-icon-only-padding-end-xsmall: px-to-rem(6) !default;
/// @prop - Padding end of the icon only small button
$button-has-icon-only-padding-end-small: px-to-rem(10) !default;
/// @prop - Padding end of the icon only large button
$button-has-icon-only-padding-end-large: px-to-rem(16) !default;
/// @prop - Padding end of the icon only extra large button
$button-has-icon-only-padding-end-xlarge: px-to-rem(18) !default;

View File

@@ -6,13 +6,12 @@ import { inheritAriaAttributes, hasShadowDom } from '@utils/helpers';
import { printIonWarning } from '@utils/logging';
import { createColorClasses, hostContext, openURL } from '@utils/theme';
import { getIonTheme } from '../../global/ionic-global';
import { getIonMode } from '../../global/ionic-global';
import type { AnimationBuilder, Color } from '../../interface';
import type { RouterDirection } from '../router/utils/interface';
/**
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the visual appearance of the component.
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
*
* @slot - Content is placed between the named slots if provided without a slot.
* @slot icon-only - Should be used on an icon in a button that has no text.
@@ -26,7 +25,6 @@ import type { RouterDirection } from '../router/utils/interface';
styleUrls: {
ios: 'button.ios.scss',
md: 'button.md.scss',
ionic: 'button.ionic.scss',
},
shadow: true,
})
@@ -117,7 +115,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
/**
* Set to `"round"` for a button with more rounded corners.
*/
@Prop({ reflect: true }) shape?: 'round' | 'rectangular';
@Prop({ reflect: true }) shape?: 'round';
/**
* Set to `"small"` for a button with less height and padding, to `"default"`
@@ -126,7 +124,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
* is inside of an item, where the size is `"small"` by default. Set the size to
* `"default"` inside of an item to make it a standard size button.
*/
@Prop({ reflect: true }) size?: 'xsmall' | 'small' | 'default' | 'large' | 'xlarge';
@Prop({ reflect: true }) size?: 'small' | 'default' | 'large';
/**
* If `true`, activates a button with a heavier font weight.
@@ -216,24 +214,6 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
return 'bounded';
}
/**
* Disable the "xsmall" and "xlarge" sizes if the theme is "ios" or "md"
*/
private getSize(): string | undefined {
const theme = getIonTheme(this);
const { size } = this;
if (size === undefined && this.inItem) {
return 'small';
}
if ((theme === 'ios' || theme === 'md') && (size === 'xsmall' || size === 'xlarge')) {
return undefined;
}
return size;
}
/**
* Finds the form element based on the provided `form` selector
* or element reference provided.
@@ -333,12 +313,14 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
};
render() {
const mode = getIonMode(this);
const {
buttonType,
type,
disabled,
rel,
target,
size,
href,
color,
expand,
@@ -347,9 +329,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
strong,
inheritedAttributes,
} = this;
const theme = getIonTheme(this);
const finalSize = this.getSize();
const finalSize = size === undefined && this.inItem ? 'small' : size;
const TagType = href === undefined ? 'button' : ('a' as any);
const attrs =
TagType === 'button'
@@ -385,7 +365,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
onClick={this.handleClick}
aria-disabled={disabled ? 'true' : null}
class={createColorClasses(color, {
[theme]: true,
[mode]: true,
[buttonType]: true,
[`${buttonType}-${expand}`]: expand !== undefined,
[`${buttonType}-${finalSize}`]: finalSize !== undefined,
@@ -416,7 +396,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
<slot></slot>
<slot name="end"></slot>
</span>
{theme === 'md' && <ion-ripple-effect type={this.rippleType}></ion-ripple-effect>}
{mode === 'md' && <ion-ripple-effect type={this.rippleType}></ion-ripple-effect>}
</TagType>
</Host>
);

View File

@@ -1,17 +1,14 @@
import { expect } from '@playwright/test';
import { configs, test } from '@utils/test/playwright';
/**
* Fill="clear" does not render differently based on the direction.
*/
configs({ directions: ['ltr'], modes: ['ios', 'md', 'ionic-md'] }).forEach(({ title, config, screenshot }) => {
test.describe(title('button: fill: clear'), () => {
configs().forEach(({ title, config, screenshot }) => {
test.describe(title('button: clear'), () => {
test('should not have visual regressions', async ({ page }) => {
await page.goto(`/src/components/button/test/clear`, config);
await page.setIonViewport();
await expect(page).toHaveScreenshot(screenshot(`button-fill-clear`));
await expect(page).toHaveScreenshot(screenshot(`button-clear`));
});
});
});

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -0,0 +1,69 @@
import { expect } from '@playwright/test';
import { configs, test } from '@utils/test/playwright';
/**
* All content takes up the full width, so RTL has no effect.
*/
configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
test.describe(title('button: round'), () => {
test.describe('default', () => {
test('should not have visual regressions', async ({ page }) => {
await page.goto(`/src/components/button/test/round`, config);
await page.setIonViewport();
const container = page.locator('#default');
await expect(container).toHaveScreenshot(screenshot(`button-round`));
});
});
test.describe('outline', () => {
test('should not have visual regressions', async ({ page }) => {
await page.goto(`/src/components/button/test/round`, config);
await page.setIonViewport();
const container = page.locator('#outline');
await expect(container).toHaveScreenshot(screenshot(`button-outline-round`));
});
});
test.describe('clear', () => {
test('should not have visual regressions', async ({ page }) => {
await page.goto(`/src/components/button/test/round`, config);
await page.setIonViewport();
const container = page.locator('#clear');
await expect(container).toHaveScreenshot(screenshot(`button-clear-round`));
});
});
test.describe('color', () => {
test('should not have visual regressions', async ({ page }) => {
await page.goto(`/src/components/button/test/round`, config);
await page.setIonViewport();
const container = page.locator('#color');
await expect(container).toHaveScreenshot(screenshot(`button-color-round`));
});
});
test.describe('expand', () => {
test('should not have visual regressions', async ({ page }) => {
await page.goto(`/src/components/button/test/round`, config);
await page.setIonViewport();
const container = page.locator('#expand');
await expect(container).toHaveScreenshot(screenshot(`button-expand-round`));
});
});
});
});

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,111 +0,0 @@
import { expect } from '@playwright/test';
import { configs, test } from '@utils/test/playwright';
/**
* All content takes up the full width, so RTL has no effect.
*/
// TODO: FW-6077 - Add ionic theme on MD mode to this test.
configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
test.describe(title('button: shape'), () => {
test.describe('round', () => {
test.describe('default', () => {
test('should not have visual regressions', async ({ page }) => {
await page.goto(`/src/components/button/test/shape`, config);
await page.setIonViewport();
const container = page.locator('#default');
await expect(container).toHaveScreenshot(screenshot(`button-round`));
});
});
test.describe('outline', () => {
test('should not have visual regressions', async ({ page }) => {
await page.goto(`/src/components/button/test/shape`, config);
await page.setIonViewport();
const container = page.locator('#outline');
await expect(container).toHaveScreenshot(screenshot(`button-outline-round`));
});
});
test.describe('clear', () => {
test('should not have visual regressions', async ({ page }) => {
await page.goto(`/src/components/button/test/shape`, config);
await page.setIonViewport();
const container = page.locator('#clear');
await expect(container).toHaveScreenshot(screenshot(`button-clear-round`));
});
});
test.describe('color', () => {
test('should not have visual regressions', async ({ page }) => {
await page.goto(`/src/components/button/test/shape`, config);
await page.setIonViewport();
const container = page.locator('#color');
await expect(container).toHaveScreenshot(screenshot(`button-color-round`));
});
});
test.describe('expand', () => {
test('should not have visual regressions', async ({ page }) => {
await page.goto(`/src/components/button/test/shape`, config);
await page.setIonViewport();
const container = page.locator('#expand');
await expect(container).toHaveScreenshot(screenshot(`button-expand-round`));
});
});
});
});
});
/**
* Shape="rectangular" is only available in the Ionic theme.
*/
configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ title, screenshot, config }) => {
test.describe(title('button: shape'), () => {
test.describe('rectangular', () => {
test('should not have visual regressions', async ({ page }) => {
await page.setContent(
`
<style>
ion-button {
margin: 8px;
}
</style>
<div id="container">
<ion-button shape="rectangular" fill="solid">Rectangular Button, Solid</ion-button>
<ion-button class="ion-focused" shape="rectangular" fill="solid">Rectangular Button, Solid, Focused</ion-button>
<ion-button class="ion-activated" shape="rectangular" fill="solid">Rectangular Button, Solid, Activated</ion-button>
<ion-button shape="rectangular" fill="outline">Rectangular Button, Outline</ion-button>
<ion-button class="ion-focused" shape="rectangular" fill="outline">Rectangular Button, Outline, Focused</ion-button>
<ion-button class="ion-activated" shape="rectangular" fill="outline">Rectangular Button, Outline, Activated</ion-button>
<ion-button shape="rectangular" fill="clear">Rectangular Button</ion-button>
<ion-button class="ion-focused" shape="rectangular" fill="clear">Rectangular Button, Focused</ion-button>
<ion-button class="ion-activated" shape="rectangular" fill="clear">Rectangular Button, Activated</ion-button>
</div>
`,
config
);
const container = page.locator('#container');
await expect(container).toHaveScreenshot(screenshot(`button-shape-rectangular`));
});
});
});
});

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,7 +1,7 @@
import { expect } from '@playwright/test';
import { configs, test } from '@utils/test/playwright';
configs({ directions: ['ltr'], modes: ['ionic-md', 'md', 'ios'] }).forEach(({ title, screenshot, config }) => {
configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
test.describe(title('button: size'), () => {
test('should render small buttons', async ({ page }) => {
await page.setContent(
@@ -60,26 +60,3 @@ configs({ directions: ['ltr'], modes: ['ionic-md', 'md', 'ios'] }).forEach(({ ti
});
});
});
/**
* The following tests are specific to the Ionic theme and do not depend on the text direction.
*/
configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ title, screenshot, config }) => {
test.describe(title('button: size'), () => {
test('should render xsmall buttons', async ({ page }) => {
await page.setContent(`<ion-button size="xsmall" fill="solid">X-Small Button</ion-button>`, config);
const wrapper = page.locator('ion-button');
await expect(wrapper).toHaveScreenshot(screenshot(`button-size-x-small`));
});
test('should render xlarge buttons', async ({ page }) => {
await page.setContent(`<ion-button size="xlarge" fill="solid">X-Large Button</ion-button>`, config);
const wrapper = page.locator('ion-button');
await expect(wrapper).toHaveScreenshot(screenshot(`button-size-x-large`));
});
});
});

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