Compare commits

..

29 Commits

Author SHA1 Message Date
Christian Bromann
47b4a0c1a7 add more exports 2024-07-17 11:13:11 -07:00
Christian Bromann
7f31ece67e PR feedback 2024-07-17 11:13:11 -07:00
Christian Bromann
b8ca441cf7 fix(core): use bundler as moduleResolution 2024-07-17 11:13:11 -07:00
Sean Perkins
2bc3b1feae chore(vue): bump vue dev-deps to have generic type (#29718)
Issue number: Internal

---------

<!-- 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. -->

In v3.2.46 [vue was updated](https://github.com/vuejs/core/pull/3969) to
add support for a generic type argument to the `Plugin` type. In
https://github.com/ionic-team/ionic-framework/pull/29637 Ionic's Vue
plugin was updated to use the generic, but the`@ionic/vue` project is
currently installing v3.2.37.

This results in a local type checking error and build error:
```
(!) Plugin typescript: @rollup/plugin-typescript TS2315: Type 'Plugin_2' is not generic.
src/ionic-vue.ts: (24:24)

24 export const IonicVue: Plugin<[IonicConfig?]> = {
```

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

- Bumps and pins the dev dependency of `vue` to `3.2.46`. There are
other breaking changes that Vue has shipped in minor/patch cycles that
prevents from updating to the latest.
- Resolves the type checking error locally during build of
the`@ionic/vue` package

## 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. -->

Validation steps:
1. Checkout the branch
2. Build `core/`
3. In `packages/vue`, install latest pinned dependencies with `npm ci`
4. Sync the changes to the `vue` package with `npm run sync`
5. Open `/packages/vue/src/ionic-vue.ts`
6. Observe: No type errors on L24
7. Run `npm run build`
8. Observe: No build errors
2024-07-16 20:11:49 +00:00
renovate[bot]
2ddc793e86 chore(deps): update playwright (#29658)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence | Type |
Update |
|---|---|---|---|---|---|---|---|
| [@playwright/test](https://playwright.dev)
([source](https://togithub.com/microsoft/playwright)) | [`^1.44.1` ->
`^1.45.0`](https://renovatebot.com/diffs/npm/@playwright%2ftest/1.44.1/1.45.0)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@playwright%2ftest/1.45.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@playwright%2ftest/1.45.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@playwright%2ftest/1.44.1/1.45.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@playwright%2ftest/1.44.1/1.45.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
| devDependencies | minor |
| mcr.microsoft.com/playwright | `v1.44.1` -> `v1.45.0` |
[![age](https://developer.mend.io/api/mc/badges/age/docker/mcr.microsoft.com%2fplaywright/v1.45.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/docker/mcr.microsoft.com%2fplaywright/v1.45.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/docker/mcr.microsoft.com%2fplaywright/v1.44.1/v1.45.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/docker/mcr.microsoft.com%2fplaywright/v1.44.1/v1.45.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
| final | minor |

---

### Release Notes

<details>
<summary>microsoft/playwright (@&#8203;playwright/test)</summary>

###
[`v1.45.0`](https://togithub.com/microsoft/playwright/compare/v1.44.1...4f3f6eecae490af444dd9298c9eaeb0c596915b7)

[Compare
Source](https://togithub.com/microsoft/playwright/compare/v1.44.1...v1.45.0)

</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.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config help](https://togithub.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- 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:eyJjcmVhdGVkSW5WZXIiOiIzNy40MTMuMiIsInVwZGF0ZWRJblZlciI6IjM3LjQyMS45IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Maria Hutt <maria@ionic.io>
2024-07-16 18:49:24 +00:00
Mikel Hamer
1295cedae9 fix(alert): do not overwrite id set in htmlAttributes (#29708)
Issue number: resolves #29704

---------

<!-- 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?
Setting the id of an alert via htmlAttributes doesn't work due to it
being overwritten by the overlay id.

## What is the new behavior?
Setting the id of an alert via htmlAttributes works.

## 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

First time PR, long time fan. Please let me know if I missed any of the
contributing guidelines, happy to change anything!
2024-07-15 14:51:14 +00:00
jcesarmobile
d30afa5a44 chore(angular-server): update eslint to 8.x (#29671)
Updated `eslint` to latest 8.x and `@ionic/eslint-config` to latest
(0.4.0), which is required for eslint 8.x to work.

Removed `eslint-plugin-import` and `@typescript-eslint/eslint-plugin`
since they are part of `@ionic/eslint-config`
2024-07-03 16:44:32 +00:00
Brandy Carney
10615bfb30 merge release-8.2.5 (#29687)
v8.2.5
2024-07-03 10:47:21 -04:00
Brandy Carney
0196d45902 docs(changelog): correct v8.2.5 changelog 2024-07-03 10:33:14 -04:00
Brandy Carney
6a1b193ec4 chore(): update package lock files 2024-07-03 10:08:11 -04:00
ionitron
556a05807c chore(): update package lock files 2024-07-03 14:06:02 +00:00
ionitron
3f9ae8405b v8.2.5 2024-07-03 14:05:17 +00:00
Brandy Carney
d70ea400a4 chore(deps): update dependency @stencil/core to v4.19.2 (#29685)
Issue number: resolves #29681

---------

### Release Notes

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

###
[`v4.19.2`](https://togithub.com/ionic-team/stencil/blob/HEAD/CHANGELOG.md#-4192-2024-07-02)

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

### Bug Fixes

* **hydrate:** partially revert
[#5838](https://github.com/ionic-team/stencil/issues/5838)
([#5876](https://github.com/ionic-team/stencil/issues/5876))
([dfbc340](dfbc34007a))
* **hydrate:** support server side rendering of components with listener
([#5877](https://github.com/ionic-team/stencil/issues/5877))
([2c5b7f8](2c5b7f8ecb)),
fixes [#5869](https://github.com/ionic-team/stencil/issues/5869)
* **testing:** add testing sub module to export map
([#5873](https://github.com/ionic-team/stencil/issues/5873))
([bb2e04f](bb2e04f488)),
fixes [#5871](https://github.com/ionic-team/stencil/issues/5871) and
[#5868](https://github.com/ionic-team/stencil/issues/5868)

</details>
2024-07-02 21:02:33 +00:00
Sukaato
90893f46c9 feat(vue): add optional IonicConfig type parameter to IonicVue plugin (#29637)
Issue number: https://github.com/ionic-team/ionic-framework/issues/29659

---------

<!-- 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. -->
while using `.use(IonicVue, {})`, the config object has no autocomplete.

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
- Add type autocomplete on plugin option in VueJS package.


## 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. -->

Co-authored-by: Julien Vaumoron <julien.vaumoron@kanoma.fr>
2024-06-28 19:02:20 +00:00
Brandy Carney
4eb16298a3 merge release-8.2.4 (#29678)
v8.2.4
2024-06-28 11:46:45 -04:00
Brandy Carney
485a1b6892 docs(changelog): update changelogs for skipped version 2024-06-28 11:31:59 -04:00
Brandy Carney
ba1c1dd2be chore(): update package lock files 2024-06-28 11:23:08 -04:00
ionitron
9fec58680f chore(): update package lock files 2024-06-28 15:11:29 +00:00
ionitron
2ec47e3a93 v8.2.4 2024-06-28 15:10:48 +00:00
Brandy Carney
fda8397e1c merge release-8.2.3 (#29676)
v8.2.3
2024-06-28 11:03:39 -04:00
Brandy Carney
085c243942 v8.2.3 2024-06-28 10:50:41 -04:00
Brandy Carney
4c9083050b chore(angular-server): add sync github action and update @stencil/core to 4.19.1 in core (#29670)
Issue number: internal

---------

This does a couple things:

**1 - Adds a `sync` command to get the latest `core` build in
`angular-server`**

The release process for `angular-server` failed
[here](https://github.com/ionic-team/ionic-framework/actions/runs/9686982182/job/26730689874).
This failure was only made apparent because the Lerna command
[here](52ff0505e8/.github/workflows/actions/publish-npm/action.yml (L35))
runs prior to building each package.

This should have been caught by CI on the [update to @stencil/core to
v4.19.0](https://github.com/ionic-team/ionic-framework/pull/29666), but
the `angular-server` package is the only package that doesn't sync
`core` before it builds. This PR adds a `sync` command so that
`angular-server` will use the latest core build during the normal build
action.

**2 - Resolving types errors in `angular-server`**

After properly syncing `core` in `angular-server` using the command
added, running build fails with the following:

<img width="400px" alt="Screenshot 2024-06-27 at 1 16 15 PM"
src="https://github.com/ionic-team/ionic-framework/assets/6577830/68d74750-821b-4776-b563-124d8fa06a79">

This was a regression in Stencil. `@stencil/core` has been updated to
resolve these errors so the build passes.
2024-06-27 18:12:12 -04:00
Brandy Carney
52ff0505e8 chore(deps): update dependency @stencil/core to v4.19.0 (#29666)
### Release Notes

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

###
[`v4.19.0`](https://togithub.com/ionic-team/stencil/blob/HEAD/CHANGELOG.md#-4190-2024-06-26)

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

### Bug Fixes

* **compiler:** support rollup's external input option
([#3227](https://github.com/ionic-team/stencil/issues/3227))
([2c68849](2c6884970b)),
fixes [#3226](https://github.com/ionic-team/stencil/issues/3226)
* **emit:** don't emit test files
([#5789](https://github.com/ionic-team/stencil/issues/5789))
([50892f1](50892f153c)),
fixes [#5788](https://github.com/ionic-team/stencil/issues/5788)
* **hyrdate:** support vdom annotation in nested dsd structures
([#5856](https://github.com/ionic-team/stencil/issues/5856))
([61bb5e3](61bb5e3a08))
* label attribute not toggling input
([#3474](https://github.com/ionic-team/stencil/issues/3474))
([13db920](13db92075b)),
fixes [#3473](https://github.com/ionic-team/stencil/issues/3473)
* **mock-doc:** expose ShadowRoot and DocumentFragment globals
([#5827](https://github.com/ionic-team/stencil/issues/5827))
([98bbd7c](98bbd7c0d6)),
fixes [#3260](https://github.com/ionic-team/stencil/issues/3260)
* **runtime:** allow watchers to fire w/ no Stencil members
([#5855](https://github.com/ionic-team/stencil/issues/5855))
([850ad4f](850ad4f4dd)),
fixes [#5854](https://github.com/ionic-team/stencil/issues/5854)
* **runtime:** catch errors in async lifecycle methods
([#5826](https://github.com/ionic-team/stencil/issues/5826))
([87e5b33](87e5b33a3b)),
fixes [#5824](https://github.com/ionic-team/stencil/issues/5824)
* **runtime:** don't register listener before connected to DOM
([#5844](https://github.com/ionic-team/stencil/issues/5844))
([9d7021f](9d7021feab)),
fixes [#4067](https://github.com/ionic-team/stencil/issues/4067)
* **runtime:** properly assign style declarations
([#5838](https://github.com/ionic-team/stencil/issues/5838))
([5c10ebf](5c10ebfd09))
* **testing:** allow to re-use pages across it blocks
([#5830](https://github.com/ionic-team/stencil/issues/5830))
([561eab4](561eab4af6)),
fixes [#3720](https://github.com/ionic-team/stencil/issues/3720)
* **typescript:** remove unsupported label property
([#5840](https://github.com/ionic-team/stencil/issues/5840))
([d26ea2b](d26ea2b749)),
fixes [#3473](https://github.com/ionic-team/stencil/issues/3473)


### Features

* **cli:** support generation of sass and less files
([#5857](https://github.com/ionic-team/stencil/issues/5857))
([1883812](18838123f1)),
closes [#2155](https://github.com/ionic-team/stencil/issues/2155)
* **compiler:** generate export maps on build
([#5809](https://github.com/ionic-team/stencil/issues/5809))
([b6d2404](b6d24043bd))
* **complier:** support type import aliasing
([#5836](https://github.com/ionic-team/stencil/issues/5836))
([7ffb25d](7ffb25d259)),
closes [#2335](https://github.com/ionic-team/stencil/issues/2335)
* **runtime:** support declarative shadow DOM
([#5792](https://github.com/ionic-team/stencil/issues/5792))
([c837063](c837063628)),
closes [#4010](https://github.com/ionic-team/stencil/issues/4010)
* **testing:** add `toHaveLastReceivedEventDetail` event spy matcher
([#5829](https://github.com/ionic-team/stencil/issues/5829))
([63491de](63491de1e6)),
closes [#2488](https://github.com/ionic-team/stencil/issues/2488)
* **testing:** allow to disable network error logging via
'logFailingNetworkRequests' option
([#5839](https://github.com/ionic-team/stencil/issues/5839))
([dac3e33](dac3e33e14)),
closes [#2572](https://github.com/ionic-team/stencil/issues/2572)
* **testing:** expose captureBeyondViewport in pageCompareScreenshot
([#5828](https://github.com/ionic-team/stencil/issues/5828))
([cf6a450](cf6a4503b3)),
closes [#3188](https://github.com/ionic-team/stencil/issues/3188)

</details>
2024-06-26 21:09:28 +00:00
Maria Hutt
253465a8be test(refresher): update test page fullscreen title (#29614)
Issue number: N/A

---------

<!-- 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. -->

The test page has the wrong title text.

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

- Updated the text to reflect the purpose of the page.

## 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. -->

N/A
2024-06-26 20:30:58 +00:00
Maria Hutt
8e3fcbb658 chore(vue): unpin version (#29657)
Issue number: internal

---------

<!-- 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. -->

Vue input values cannot accept a string object without causing it's
behavior to fail. This is happening because a change that happened
through Vue.

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

- Vue released a fix, verified that fixes the issue, upgraded the
version

## 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. -->
2024-06-26 17:39:11 +00:00
Brandy Carney
caa88b34e1 style(many): fix comments with wrong component names (#29665) 2024-06-26 16:29:19 +00:00
Brandy Carney
ceb41f31f3 fix(angular): popover arrow navigation with disabled items (#29662)
Issue number: resolves #29640

---------

## What is the current behavior?
(Angular) If a list inside of a popover contains a disabled item and is
included in the following way:

```html
<ion-list>
  <ion-item [button]="true">Option 1</ion-item>
  <ion-item [button]="true" [disabled]="true">Option 2</ion-item>
  <ion-item [button]="true">Option 3</ion-item>
</ion-list>
```

when you try to navigate using the arrow down keys, it will stop at the
disabled item instead of continuing over it.

Note that changing the item to the following will work:

```html
<ion-item [button]="true" disabled="true">Option 2</ion-item>
```

## What is the new behavior?
Reflect the `disabled` property in the item so that when items are
queried in the popover, the arrow down key skips over the disabled item.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

## Other information

This can be tested in the Angular test app by following the
documentation here:
https://github.com/ionic-team/ionic-framework/blob/main/docs/angular/testing.md

Removing my fix in `core`, then running `npm run build` and re-syncing
the test app should reproduce the problem.
2024-06-26 15:35:44 +00:00
renovate[bot]
3d6e2c4d2f chore(deps): update capacitor to v6.1.0 (#29627)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

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

---

### Release Notes

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

###
[`v6.1.0`](https://togithub.com/ionic-team/capacitor/blob/HEAD/CHANGELOG.md#610-2024-06-11)

[Compare
Source](https://togithub.com/ionic-team/capacitor/compare/6.0.0...6.1.0)

##### Bug Fixes

- **android:** avoid crash if server url ends in /
([#&#8203;7426](https://togithub.com/ionic-team/capacitor/issues/7426))
([f8264cc](f8264ccae1))
- **cli:** Avoid duplicate entries in packageClassList
([#&#8203;7470](https://togithub.com/ionic-team/capacitor/issues/7470))
([cca0b80](cca0b80529))
- **cli:** Run sync before updating gradle
([#&#8203;7497](https://togithub.com/ionic-team/capacitor/issues/7497))
([f27786e](f27786ea13))
- **http:** don't override readyState for non POST requests
([#&#8203;7488](https://togithub.com/ionic-team/capacitor/issues/7488))
([30c13a8](30c13a865e))
- **ios:** check if urlSchemeTask is stopped before calling its methods
([#&#8203;7482](https://togithub.com/ionic-team/capacitor/issues/7482))
([b32b5b1](b32b5b17ed))

##### Features

- **cli:** run plugin hooks
([#&#8203;7499](https://togithub.com/ionic-team/capacitor/issues/7499))
([3b847ea](3b847eac42))
- **ios:** CAPPluginMethod selector-based initializer
([#&#8203;7412](https://togithub.com/ionic-team/capacitor/issues/7412))
([44c5b55](44c5b55e36))

</details>

<details>
<summary>ionic-team/capacitor-plugins
(@&#8203;capacitor/keyboard)</summary>

###
[`v6.0.1`](https://togithub.com/ionic-team/capacitor-plugins/releases/tag/%40capacitor/camera%406.0.1)

[Compare
Source](https://togithub.com/ionic-team/capacitor-plugins/compare/@capacitor/keyboard@6.0.0...@capacitor/keyboard@6.0.1)

##### Bug Fixes

- **ios:** iOS panorama photos selected through CameraPlugin are
corrupted
([#&#8203;2090](https://togithub.com/ionic-team/capacitor-plugins/issues/2090))
([998e495](998e4950d5))
- **ios:** Picking ProRAW pictures from Gallery
([#&#8203;2098](https://togithub.com/ionic-team/capacitor-plugins/issues/2098))
([20b9e26](20b9e26b1b))

</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 these
updates 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:eyJjcmVhdGVkSW5WZXIiOiIzNy4zOTMuMCIsInVwZGF0ZWRJblZlciI6IjM3LjQxMy4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-24 18:50:54 +00:00
renovate[bot]
ff214bd5f3 chore(deps): update playwright (#29609)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@axe-core/playwright](https://togithub.com/dequelabs/axe-core-npm) |
[`^4.8.5` ->
`^4.9.1`](https://renovatebot.com/diffs/npm/@axe-core%2fplaywright/4.9.1/4.9.1)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@axe-core%2fplaywright/4.9.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@axe-core%2fplaywright/4.9.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@axe-core%2fplaywright/4.9.1/4.9.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@axe-core%2fplaywright/4.9.1/4.9.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [@playwright/test](https://playwright.dev)
([source](https://togithub.com/microsoft/playwright)) | [`^1.39.0` ->
`^1.44.1`](https://renovatebot.com/diffs/npm/@playwright%2ftest/1.44.1/1.44.1)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@playwright%2ftest/1.44.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@playwright%2ftest/1.44.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@playwright%2ftest/1.44.1/1.44.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@playwright%2ftest/1.44.1/1.44.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### 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.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config help](https://togithub.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- 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:eyJjcmVhdGVkSW5WZXIiOiIzNy4zOTMuMCIsInVwZGF0ZWRJblZlciI6IjM3LjM5My4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-18 00:24:57 +00:00
1976 changed files with 9955 additions and 30926 deletions

View File

@@ -6,11 +6,19 @@ runs:
- uses: actions/setup-node@v4
with:
node-version: 18.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core
path: ./core
filename: CoreBuild.zip
- name: Install Angular Server Dependencies
run: npm ci
shell: bash
working-directory: ./packages/angular-server
- name: Sync
run: npm run sync
shell: bash
working-directory: ./packages/angular-server
- name: Build
run: npm run build.prod
shell: bash

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

@@ -4,31 +4,290 @@ This is a comprehensive list of the breaking changes introduced in the major ver
## Versions
- [Version 9.x](#version-9x)
- [Version 8.x](./BREAKING_ARCHIVE/v8.md)
- [Version 8.x](#version-8x)
- [Version 7.x](./BREAKING_ARCHIVE/v7.md)
- [Version 6.x](./BREAKING_ARCHIVE/v6.md)
- [Version 5.x](./BREAKING_ARCHIVE/v5.md)
- [Version 4.x](./BREAKING_ARCHIVE/v4.md)
- [Legacy](https://github.com/ionic-team/ionic-v3/blob/master/CHANGELOG.md)
## Version 9.x
## Version 8.x
- [Components](#version-9x-components)
- [Button](#version-9x-button)
- [Card](#version-9x-card)
- [Chip](#version-9x-chip)
- [Browser and Platform Support](#version-8x-browser-platform-support)
- [Dark Mode](#version-8x-dark-mode)
- [Global Styles](#version-8x-global-styles)
- [Haptics](#version-8x-haptics)
- [Components](#version-8x-components)
- [Button](#version-8x-button)
- [Checkbox](#version-8x-checkbox)
- [Content](#version-8x-content)
- [Datetime](#version-8x-datetime)
- [Input](#version-8x-input)
- [Item](#version-8x-item)
- [Modal](#version-8x-modal)
- [Nav](#version-8x-nav)
- [Picker](#version-8x-picker)
- [Progress bar](#version-8x-progress-bar)
- [Radio](#version-8x-radio)
- [Range](#version-8x-range)
- [Searchbar](#version-8x-searchbar)
- [Select](#version-8x-select)
- [Textarea](#version-8x-textarea)
- [Toggle](#version-8x-toggle)
- [Framework Specific](#version-8x-framework-specific)
- [Angular](#version-8x-angular)
<h2 id="version-9x-components">Components</h2>
<h2 id="version-8x-browser-platform-support">Browser and Platform Support</h2>
<h4 id="version-9x-button">Button</h4>
This section details the desktop browser, JavaScript framework, and mobile platform versions that are supported by Ionic 8.
- The `border-radius` of the `ios` and `md` button now defaults to `6px` and `999px` instead of `14px` and `4px`, respectively, in accordance with the iOS and Material Design 3 guidelines. To revert to the previous appearance, set the `shape` to `"soft"` for `md` and override the `--border-radius` CSS variable for `ios` to `14px`, or set it to a different value entirely.
**Minimum Browser Versions**
| Desktop Browser | Supported Versions |
| --------------- | ----------------- |
| Chrome | 89+ |
| Safari | 15+ |
| Firefox | 75+ |
| Edge | 89+ |
<h4 id="version-9x-card">Card</h4>
**Minimum JavaScript Framework Versions**
| Framework | Supported Version |
| --------- | --------------------- |
| Angular | 16+ |
| React | 17+ |
| Vue | 3.0.6+ |
- The `border-radius` of the `ios` and `md` card now defaults to `14px` and `12px` instead of `8px` and `4px`, respectively, in accordance with the iOS and Material Design 3 guidelines. To revert to the previous appearance, set the `shape` to `"soft"`, or override the `--border-radius` CSS variable to specify a different value.
**Minimum Mobile Platform Versions**
| Platform | Supported Version |
| -------- | ---------------------- |
| iOS | 15+ |
| Android | 5.1+ with Chromium 89+ |
<h4 id="version-9x-chip">Chip</h4>
Ionic Framework v8 removes backwards support for CSS Animations in favor of the [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API). All minimum browser versions listed above support the Web Animations API.
- The `border-radius` of the `ios` and `md` chip now defaults to `10px` and `8px`, respectively, instead of `16px` in accordance with the iOS and Material Design 3 guidelines. To revert to the previous appearance, set the `shape` to `"round"`, or override the `--border-radius` CSS variable to specify a different value.
<h2 id="version-8x-dark-mode">Dark Mode</h2>
In previous versions, it was recommended to define the dark palette in the following way:
```css
@media (prefers-color-scheme: dark) {
body {
/* global app variables */
}
.ios body {
/* global ios app variables */
}
.md body {
/* global md app variables */
}
}
```
In Ionic Framework version 8, the dark palette is being distributed via css files that can be imported. Below is an example of importing a dark palette file in Angular:
```css
/* @import '@ionic/angular/css/palettes/dark.always.css'; */
/* @import "@ionic/angular/css/palettes/dark.class.css"; */
@import "@ionic/angular/css/palettes/dark.system.css";
```
By importing the `dark.system.css` file, the dark palette variables will be defined like the following:
```css
@media (prefers-color-scheme: dark) {
:root {
/* global app variables */
}
:root.ios {
/* global ios app variables */
}
:root.md {
/* global md app variables */
}
}
```
Notice that the dark palette is now applied to the `:root` selector instead of the `body` selector. The [`:root`](https://developer.mozilla.org/en-US/docs/Web/CSS/:root) selector represents the `<html>` element and is identical to the selector `html`, except that its specificity is higher.
While migrating to include the new dark palette files is unlikely to cause breaking changes, these new selectors can lead to unexpected overrides if custom CSS variables are being set on the `body` element. We recommend updating any instances where global application variables are set to target the `:root` selector instead.
For more information on the new dark palette files, refer to the [Dark Mode documentation](https://ionicframework.com/docs/theming/dark-mode).
<h2 id="version-8x-global-styles">Global Styles</h2>
<h4 id="version-8x-text-color">Text Color</h4>
The `core.css` file has been updated to set the text color on the `body` element:
```diff
body {
+ color: var(--ion-text-color);
}
```
This allows components to inherit the color properly when used outside of Ionic Framework and is required for custom themes to work properly. However, it may have unintentional side effects in apps if the color was not expected to inherit.
<h4 id="version-8x-dynamic-font">Dynamic Font</h4>
The `core.css` file has been updated to enable dynamic font scaling by default.
The `--ion-default-dynamic-font` variable has been removed and replaced with `--ion-dynamic-font`.
Developers who had previously chosen dynamic font scaling by activating it in their global stylesheets can revert to the default setting by removing their custom CSS. In doing so, their application will seamlessly continue utilizing dynamic font scaling as it did before. It's essential to note that altering the font-size of the html element should be avoided, as it may disrupt the proper functioning of dynamic font scaling.
Developers who want to disable dynamic font scaling can set `--ion-dynamic-font: initial;` in their global stylesheets. However, this is not recommended because it may introduce accessibility challenges for users who depend on enlarged font sizes.
For more information on the dynamic font, refer to the [Dynamic Font Scaling documentation](https://ionicframework.com/docs/layout/dynamic-font-scaling).
<h2 id="version-8x-haptics">Haptics</h2>
- Support for the Cordova Haptics plugin has been removed. Components that integrate with haptics, such as `ion-picker` and `ion-toggle`, will continue to function but will no longer play haptics in Cordova environments. Developers should migrate to Capacitor to continue to have haptics in these components.
<h2 id="version-8x-components">Components</h2>
<h4 id="version-8x-button">Button</h4>
- Button text now wraps by default. If this behavior is not desired, add the `ion-text-nowrap` class from the [CSS Utilities](https://ionicframework.com/docs/layout/css-utilities).
<h4 id="version-8x-checkbox">Checkbox</h4>
The `legacy` property and support for the legacy syntax, which involved placing an `ion-checkbox` inside of an `ion-item` with an `ion-label`, have been removed. For more information on migrating from the legacy checkbox syntax, refer to the [Checkbox documentation](https://ionicframework.com/docs/api/checkbox#migrating-from-legacy-checkbox-syntax).
<h4 id="version-8x-content">Content</h4>
- Content no longer sets the `--background` custom property when the `.outer-content` class is set on the host.
<h4 id="version-8x-datetime">Datetime</h4>
- The CSS shadow part for `month-year-button` has been changed to target a `button` element instead of `ion-item`. Developers should verify their UI renders as expected for the month/year toggle button inside of `ion-datetime`.
- Developers using the CSS variables available on `ion-item` will need to migrate their CSS to use CSS properties. For example:
```diff
ion-datetime::part(month-year-button) {
- --background: red;
+ background: red;
}
```
<h4 id="version-8x-input">Input</h4>
- `size` has been removed from the `ion-input` component. Developers should use CSS to specify the visible width of the input.
- `accept` has been removed from the `ion-input` component. This was previously used in conjunction with the `type="file"`. However, the `file` value for `type` is not a valid value in Ionic Framework.
- The `legacy` property and support for the legacy syntax, which involved placing an `ion-input` inside of an `ion-item` with an `ion-label`, have been removed. For more information on migrating from the legacy input syntax, refer to the [Input documentation](https://ionicframework.com/docs/api/input#migrating-from-legacy-input-syntax).
<h4 id="version-8x-item">Item</h4>
- The `helper` slot has been removed. Developers should use the `helperText` property on `ion-input` and `ion-textarea`.
- The `error` slot has been removed. Developers should use the `errorText` property on `ion-input` and `ion-textarea`.
- Counter functionality has been removed including the `counter` and `counterFormatter` properties. Developers should use the properties of the same name on `ion-input` and `ion-textarea`.
- The `fill` property has been removed. Developers should use the property of the same name on `ion-input`, `ion-select`, and `ion-textarea`.
- The `shape` property has been removed. Developers should use the property of the same name on `ion-input`, `ion-select`, and `ion-textarea`.
- Item no longer automatically delegates focus to the first focusable element. While most developers should not need to make any changes to account for this update, usages of `ion-item` with interactive elements such as form controls (inputs, textareas, etc) should be evaluated to verify that interactions still work as expected.
<h5>CSS variables</h4>
The following deprecated CSS variables have been removed: `--highlight-height`, `--highlight-color-focused`, `--highlight-color-valid`, and `--highlight-color-invalid`. These variables were used on the bottom border highlight of an item when the form control inside of that item was focused. The form control syntax was [simplified in v7](https://ionic.io/blog/ionic-7-is-here#simplified-form-control-syntax) so that inputs, selects, and textareas would no longer be required to be used inside of an item.
If you have not yet migrated to the modern form control syntax, migration guides for each of the form controls that added a highlight to item can be found below:
- [Input migration documentation](https://ionicframework.com/docs/api/input#migrating-from-legacy-input-syntax)
- [Select migration documentation](https://ionicframework.com/docs/api/select#migrating-from-legacy-select-syntax)
- [Textarea migration documentation](https://ionicframework.com/docs/api/textarea#migrating-from-legacy-textarea-syntax)
Once all form controls are using the modern syntax, the same variables can be used to customize them from the form control itself:
| Name | Description |
| ----------------------------| ----------------------------------------|
| `--highlight-color-focused` | The color of the highlight when focused |
| `--highlight-color-invalid` | The color of the highlight when invalid |
| `--highlight-color-valid` | The color of the highlight when valid |
| `--highlight-height` | The height of the highlight indicator |
The following styles for item:
```css
ion-item {
--highlight-color-focused: purple;
--highlight-color-valid: blue;
--highlight-color-invalid: orange;
--highlight-height: 6px;
}
```
will instead be applied on the form controls:
```css
ion-input,
ion-textarea,
ion-select {
--highlight-color-focused: purple;
--highlight-color-valid: blue;
--highlight-color-invalid: orange;
--highlight-height: 6px;
}
```
> [!NOTE]
> The input and textarea components are scoped, which means they will automatically scope their CSS by appending each of the styles with an additional class at runtime. Overriding scoped selectors in CSS requires a [higher specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity) selector. Targeting the `ion-input` or `ion-textarea` for customization will not work; therefore we recommend adding a class and customizing it that way.
<h4 id="version-8x-modal">Modal</h4>
- Detection for Capacitor <= 2 with applying status bar styles has been removed. Developers should ensure they are using Capacitor 3 or later when using the card modal presentation.
<h4 id="version-8x-nav">Nav</h4>
- `getLength` returns `Promise<number>` instead of `<number>`. This method was not previously available in Nav's TypeScript interface, but developers could still access it by casting Nav as `any`. Developers should ensure they `await` their `getLength` call before accessing the returned value.
<h4 id="version-8x-picker">Picker</h4>
- `ion-picker` and `ion-picker-column` have been renamed to `ion-picker-legacy` and `ion-picker-legacy-column`, respectively. This change was made to accommodate the new inline picker component while allowing developers to continue to use the legacy picker during this migration period.
- Only the component names have been changed. Usages such as `ion-picker` or `IonPicker` should be changed to `ion-picker-legacy` and `IonPickerLegacy`, respectively.
- Non-component usages such as `pickerController` or `useIonPicker` remain unchanged. The new picker displays inline with your page content and does not have equivalents for these non-component usages.
<h4 id="version-8x-progress-bar">Progress bar</h4>
- The `--buffer-background` CSS variable has been removed. Use `--background` instead.
<h4 id="version-8x-toast">Toast</h4>
- `cssClass` has been removed from the `ToastButton` interface. This was previously used to apply a custom class to the toast buttons. Developers can use the "button" shadow part to style the buttons.
For more information on styling toast buttons, refer to the [Toast Theming documentation](https://ionicframework.com/docs/api/toast#theming).
<h4 id="version-8x-radio">Radio</h4>
- The `legacy` property and support for the legacy syntax, which involved placing an `ion-radio` inside of an `ion-item` with an `ion-label`, have been removed. For more information on migrating from the legacy radio syntax, refer to the [Radio documentation](https://ionicframework.com/docs/api/radio#migrating-from-legacy-radio-syntax).
<h4 id="version-8x-range">Range</h4>
- The `legacy` property and support for the legacy syntax, which involved placing an `ion-range` inside of an `ion-item` with an `ion-label`, have been removed. Ionic will also no longer attempt to automatically associate form controls with sibling `<label>` elements as these label elements are now used inside the form control. Developers should provide a label (either visible text or `aria-label`) directly to the form control. For more information on migrating from the legacy range syntax, refer to the [Range documentation](https://ionicframework.com/docs/api/range#migrating-from-legacy-range-syntax).
<h4 id="version-8x-searchbar">Searchbar</h4>
- The `autocapitalize` property now defaults to `'off'`.
<h4 id="version-8x-select">Select</h4>
- The `legacy` property and support for the legacy syntax, which involved placing an `ion-select` inside of an `ion-item` with an `ion-label`, have been removed. Ionic will also no longer attempt to automatically associate form controls with sibling `<label>` elements as these label elements are now used inside the form control. Developers should provide a label (either visible text or `aria-label`) directly to the form control. For more information on migrating from the legacy select syntax, refer to the [Select documentation](https://ionicframework.com/docs/api/select#migrating-from-legacy-select-syntax).
<h4 id="version-8x-textarea">Textarea</h4>
- The `legacy` property and support for the legacy syntax, which involved placing an `ion-textarea` inside of an `ion-item` with an `ion-label`, have been removed. For more information on migrating from the legacy textarea syntax, refer to the [Textarea documentation](https://ionicframework.com/docs/api/textarea#migrating-from-legacy-textarea-syntax).
<h4 id="version-8x-toggle">Toggle</h4>
- The `legacy` property and support for the legacy syntax, which involved placing an `ion-toggle` inside of an `ion-item` with an `ion-label`, have been removed. For more information on migrating from the legacy toggle syntax, refer to the [Toggle documentation](https://ionicframework.com/docs/api/toggle#migrating-from-legacy-toggle-syntax).
<h2 id="version-8x-framework-specific">Framework Specific</h2>
<h4 id="version-8x-angular">Angular</h4>
- The `IonBackButtonDelegate` class has been removed in favor of `IonBackButton`.
```diff
- import { IonBackButtonDelegate } from '@ionic/angular';
+ import { IonBackButton } from '@ionic/angular';
```

View File

@@ -1,282 +0,0 @@
# Breaking Changes
## Version 8.x
- [Browser and Platform Support](#version-8x-browser-platform-support)
- [Dark Mode](#version-8x-dark-mode)
- [Global Styles](#version-8x-global-styles)
- [Haptics](#version-8x-haptics)
- [Components](#version-8x-components)
- [Button](#version-8x-button)
- [Checkbox](#version-8x-checkbox)
- [Content](#version-8x-content)
- [Datetime](#version-8x-datetime)
- [Input](#version-8x-input)
- [Item](#version-8x-item)
- [Modal](#version-8x-modal)
- [Nav](#version-8x-nav)
- [Picker](#version-8x-picker)
- [Progress bar](#version-8x-progress-bar)
- [Radio](#version-8x-radio)
- [Range](#version-8x-range)
- [Searchbar](#version-8x-searchbar)
- [Select](#version-8x-select)
- [Textarea](#version-8x-textarea)
- [Toggle](#version-8x-toggle)
- [Framework Specific](#version-8x-framework-specific)
- [Angular](#version-8x-angular)
<h2 id="version-8x-browser-platform-support">Browser and Platform Support</h2>
This section details the desktop browser, JavaScript framework, and mobile platform versions that are supported by Ionic 8.
**Minimum Browser Versions**
| Desktop Browser | Supported Versions |
| --------------- | ----------------- |
| Chrome | 89+ |
| Safari | 15+ |
| Firefox | 75+ |
| Edge | 89+ |
**Minimum JavaScript Framework Versions**
| Framework | Supported Version |
| --------- | --------------------- |
| Angular | 16+ |
| React | 17+ |
| Vue | 3.0.6+ |
**Minimum Mobile Platform Versions**
| Platform | Supported Version |
| -------- | ---------------------- |
| iOS | 15+ |
| Android | 5.1+ with Chromium 89+ |
Ionic Framework v8 removes backwards support for CSS Animations in favor of the [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API). All minimum browser versions listed above support the Web Animations API.
<h2 id="version-8x-dark-mode">Dark Mode</h2>
In previous versions, it was recommended to define the dark palette in the following way:
```css
@media (prefers-color-scheme: dark) {
body {
/* global app variables */
}
.ios body {
/* global ios app variables */
}
.md body {
/* global md app variables */
}
}
```
In Ionic Framework version 8, the dark palette is being distributed via css files that can be imported. Below is an example of importing a dark palette file in Angular:
```css
/* @import '@ionic/angular/css/palettes/dark.always.css'; */
/* @import "@ionic/angular/css/palettes/dark.class.css"; */
@import "@ionic/angular/css/palettes/dark.system.css";
```
By importing the `dark.system.css` file, the dark palette variables will be defined like the following:
```css
@media (prefers-color-scheme: dark) {
:root {
/* global app variables */
}
:root.ios {
/* global ios app variables */
}
:root.md {
/* global md app variables */
}
}
```
Notice that the dark palette is now applied to the `:root` selector instead of the `body` selector. The [`:root`](https://developer.mozilla.org/en-US/docs/Web/CSS/:root) selector represents the `<html>` element and is identical to the selector `html`, except that its specificity is higher.
While migrating to include the new dark palette files is unlikely to cause breaking changes, these new selectors can lead to unexpected overrides if custom CSS variables are being set on the `body` element. We recommend updating any instances where global application variables are set to target the `:root` selector instead.
For more information on the new dark palette files, refer to the [Dark Mode documentation](https://ionicframework.com/docs/theming/dark-mode).
<h2 id="version-8x-global-styles">Global Styles</h2>
<h4 id="version-8x-text-color">Text Color</h4>
The `core.css` file has been updated to set the text color on the `body` element:
```diff
body {
+ color: var(--ion-text-color);
}
```
This allows components to inherit the color properly when used outside of Ionic Framework and is required for custom themes to work properly. However, it may have unintentional side effects in apps if the color was not expected to inherit.
<h4 id="version-8x-dynamic-font">Dynamic Font</h4>
The `core.css` file has been updated to enable dynamic font scaling by default.
The `--ion-default-dynamic-font` variable has been removed and replaced with `--ion-dynamic-font`.
Developers who had previously chosen dynamic font scaling by activating it in their global stylesheets can revert to the default setting by removing their custom CSS. In doing so, their application will seamlessly continue utilizing dynamic font scaling as it did before. It's essential to note that altering the font-size of the html element should be avoided, as it may disrupt the proper functioning of dynamic font scaling.
Developers who want to disable dynamic font scaling can set `--ion-dynamic-font: initial;` in their global stylesheets. However, this is not recommended because it may introduce accessibility challenges for users who depend on enlarged font sizes.
For more information on the dynamic font, refer to the [Dynamic Font Scaling documentation](https://ionicframework.com/docs/layout/dynamic-font-scaling).
<h2 id="version-8x-haptics">Haptics</h2>
- Support for the Cordova Haptics plugin has been removed. Components that integrate with haptics, such as `ion-picker` and `ion-toggle`, will continue to function but will no longer play haptics in Cordova environments. Developers should migrate to Capacitor to continue to have haptics in these components.
<h2 id="version-8x-components">Components</h2>
<h4 id="version-8x-button">Button</h4>
- Button text now wraps by default. If this behavior is not desired, add the `ion-text-nowrap` class from the [CSS Utilities](https://ionicframework.com/docs/layout/css-utilities).
<h4 id="version-8x-checkbox">Checkbox</h4>
The `legacy` property and support for the legacy syntax, which involved placing an `ion-checkbox` inside of an `ion-item` with an `ion-label`, have been removed. For more information on migrating from the legacy checkbox syntax, refer to the [Checkbox documentation](https://ionicframework.com/docs/api/checkbox#migrating-from-legacy-checkbox-syntax).
<h4 id="version-8x-content">Content</h4>
- Content no longer sets the `--background` custom property when the `.outer-content` class is set on the host.
<h4 id="version-8x-datetime">Datetime</h4>
- The CSS shadow part for `month-year-button` has been changed to target a `button` element instead of `ion-item`. Developers should verify their UI renders as expected for the month/year toggle button inside of `ion-datetime`.
- Developers using the CSS variables available on `ion-item` will need to migrate their CSS to use CSS properties. For example:
```diff
ion-datetime::part(month-year-button) {
- --background: red;
+ background: red;
}
```
<h4 id="version-8x-input">Input</h4>
- `size` has been removed from the `ion-input` component. Developers should use CSS to specify the visible width of the input.
- `accept` has been removed from the `ion-input` component. This was previously used in conjunction with the `type="file"`. However, the `file` value for `type` is not a valid value in Ionic Framework.
- The `legacy` property and support for the legacy syntax, which involved placing an `ion-input` inside of an `ion-item` with an `ion-label`, have been removed. For more information on migrating from the legacy input syntax, refer to the [Input documentation](https://ionicframework.com/docs/api/input#migrating-from-legacy-input-syntax).
<h4 id="version-8x-item">Item</h4>
- The `helper` slot has been removed. Developers should use the `helperText` property on `ion-input` and `ion-textarea`.
- The `error` slot has been removed. Developers should use the `errorText` property on `ion-input` and `ion-textarea`.
- Counter functionality has been removed including the `counter` and `counterFormatter` properties. Developers should use the properties of the same name on `ion-input` and `ion-textarea`.
- The `fill` property has been removed. Developers should use the property of the same name on `ion-input`, `ion-select`, and `ion-textarea`.
- The `shape` property has been removed. Developers should use the property of the same name on `ion-input`, `ion-select`, and `ion-textarea`.
- Item no longer automatically delegates focus to the first focusable element. While most developers should not need to make any changes to account for this update, usages of `ion-item` with interactive elements such as form controls (inputs, textareas, etc) should be evaluated to verify that interactions still work as expected.
<h5>CSS variables</h4>
The following deprecated CSS variables have been removed: `--highlight-height`, `--highlight-color-focused`, `--highlight-color-valid`, and `--highlight-color-invalid`. These variables were used on the bottom border highlight of an item when the form control inside of that item was focused. The form control syntax was [simplified in v7](https://ionic.io/blog/ionic-7-is-here#simplified-form-control-syntax) so that inputs, selects, and textareas would no longer be required to be used inside of an item.
If you have not yet migrated to the modern form control syntax, migration guides for each of the form controls that added a highlight to item can be found below:
- [Input migration documentation](https://ionicframework.com/docs/api/input#migrating-from-legacy-input-syntax)
- [Select migration documentation](https://ionicframework.com/docs/api/select#migrating-from-legacy-select-syntax)
- [Textarea migration documentation](https://ionicframework.com/docs/api/textarea#migrating-from-legacy-textarea-syntax)
Once all form controls are using the modern syntax, the same variables can be used to customize them from the form control itself:
| Name | Description |
| ----------------------------| ----------------------------------------|
| `--highlight-color-focused` | The color of the highlight when focused |
| `--highlight-color-invalid` | The color of the highlight when invalid |
| `--highlight-color-valid` | The color of the highlight when valid |
| `--highlight-height` | The height of the highlight indicator |
The following styles for item:
```css
ion-item {
--highlight-color-focused: purple;
--highlight-color-valid: blue;
--highlight-color-invalid: orange;
--highlight-height: 6px;
}
```
will instead be applied on the form controls:
```css
ion-input,
ion-textarea,
ion-select {
--highlight-color-focused: purple;
--highlight-color-valid: blue;
--highlight-color-invalid: orange;
--highlight-height: 6px;
}
```
> [!NOTE]
> The input and textarea components are scoped, which means they will automatically scope their CSS by appending each of the styles with an additional class at runtime. Overriding scoped selectors in CSS requires a [higher specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity) selector. Targeting the `ion-input` or `ion-textarea` for customization will not work; therefore we recommend adding a class and customizing it that way.
<h4 id="version-8x-modal">Modal</h4>
- Detection for Capacitor <= 2 with applying status bar styles has been removed. Developers should ensure they are using Capacitor 3 or later when using the card modal presentation.
<h4 id="version-8x-nav">Nav</h4>
- `getLength` returns `Promise<number>` instead of `<number>`. This method was not previously available in Nav's TypeScript interface, but developers could still access it by casting Nav as `any`. Developers should ensure they `await` their `getLength` call before accessing the returned value.
<h4 id="version-8x-picker">Picker</h4>
- `ion-picker` and `ion-picker-column` have been renamed to `ion-picker-legacy` and `ion-picker-legacy-column`, respectively. This change was made to accommodate the new inline picker component while allowing developers to continue to use the legacy picker during this migration period.
- Only the component names have been changed. Usages such as `ion-picker` or `IonPicker` should be changed to `ion-picker-legacy` and `IonPickerLegacy`, respectively.
- Non-component usages such as `pickerController` or `useIonPicker` remain unchanged. The new picker displays inline with your page content and does not have equivalents for these non-component usages.
<h4 id="version-8x-progress-bar">Progress bar</h4>
- The `--buffer-background` CSS variable has been removed. Use `--background` instead.
<h4 id="version-8x-toast">Toast</h4>
- `cssClass` has been removed from the `ToastButton` interface. This was previously used to apply a custom class to the toast buttons. Developers can use the "button" shadow part to style the buttons.
For more information on styling toast buttons, refer to the [Toast Theming documentation](https://ionicframework.com/docs/api/toast#theming).
<h4 id="version-8x-radio">Radio</h4>
- The `legacy` property and support for the legacy syntax, which involved placing an `ion-radio` inside of an `ion-item` with an `ion-label`, have been removed. For more information on migrating from the legacy radio syntax, refer to the [Radio documentation](https://ionicframework.com/docs/api/radio#migrating-from-legacy-radio-syntax).
<h4 id="version-8x-range">Range</h4>
- The `legacy` property and support for the legacy syntax, which involved placing an `ion-range` inside of an `ion-item` with an `ion-label`, have been removed. Ionic will also no longer attempt to automatically associate form controls with sibling `<label>` elements as these label elements are now used inside the form control. Developers should provide a label (either visible text or `aria-label`) directly to the form control. For more information on migrating from the legacy range syntax, refer to the [Range documentation](https://ionicframework.com/docs/api/range#migrating-from-legacy-range-syntax).
<h4 id="version-8x-searchbar">Searchbar</h4>
- The `autocapitalize` property now defaults to `'off'`.
<h4 id="version-8x-select">Select</h4>
- The `legacy` property and support for the legacy syntax, which involved placing an `ion-select` inside of an `ion-item` with an `ion-label`, have been removed. Ionic will also no longer attempt to automatically associate form controls with sibling `<label>` elements as these label elements are now used inside the form control. Developers should provide a label (either visible text or `aria-label`) directly to the form control. For more information on migrating from the legacy select syntax, refer to the [Select documentation](https://ionicframework.com/docs/api/select#migrating-from-legacy-select-syntax).
<h4 id="version-8x-textarea">Textarea</h4>
- The `legacy` property and support for the legacy syntax, which involved placing an `ion-textarea` inside of an `ion-item` with an `ion-label`, have been removed. For more information on migrating from the legacy textarea syntax, refer to the [Textarea documentation](https://ionicframework.com/docs/api/textarea#migrating-from-legacy-textarea-syntax).
<h4 id="version-8x-toggle">Toggle</h4>
- The `legacy` property and support for the legacy syntax, which involved placing an `ion-toggle` inside of an `ion-item` with an `ion-label`, have been removed. For more information on migrating from the legacy toggle syntax, refer to the [Toggle documentation](https://ionicframework.com/docs/api/toggle#migrating-from-legacy-toggle-syntax).
<h2 id="version-8x-framework-specific">Framework Specific</h2>
<h4 id="version-8x-angular">Angular</h4>
- The `IonBackButtonDelegate` class has been removed in favor of `IonBackButton`.
```diff
- import { IonBackButtonDelegate } from '@ionic/angular';
+ import { IonBackButton } from '@ionic/angular';
```

View File

@@ -3,6 +3,37 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [8.2.5](https://github.com/ionic-team/ionic-framework/compare/v8.2.4...v8.2.5) (2024-07-03)
### Bug Fixes
* **dependencies:** use latest @stencil/core to remove DOMException errors ([#29685](https://github.com/ionic-team/ionic-framework/issues/29685)) ([d70ea4](https://github.com/ionic-team/ionic/commit/d70ea400a4713bd091af1393e196e10844a190b6)), closes [#29681](https://github.com/ionic-team/ionic/issues/29681)
* **vue:** add optional IonicConfig type parameter to IonicVue plugin ([#29637](https://github.com/ionic-team/ionic-framework/issues/29637)) ([90893f4](https://github.com/ionic-team/ionic-framework/commit/90893f46c930dbccd4251fa2f56bdde30b669158)), closes [#29659](https://github.com/ionic-team/ionic-framework/issues/29659)
## [8.2.4](https://github.com/ionic-team/ionic-framework/compare/v8.2.2...v8.2.4) (2024-06-28)
### Bug Fixes
* **angular:** popover arrow navigation with disabled items ([#29662](https://github.com/ionic-team/ionic-framework/issues/29662)) ([ceb41f3](https://github.com/ionic-team/ionic-framework/commit/ceb41f31f382ff1bcf81de2b11680699d33d5077)), closes [#29640](https://github.com/ionic-team/ionic-framework/issues/29640)
## 8.2.3
This version should be skipped. Install 8.2.4 instead.
## [8.2.2](https://github.com/ionic-team/ionic-framework/compare/v8.2.1...v8.2.2) (2024-06-12)

View File

@@ -3,19 +3,16 @@
# See documentation at https://stylelint.io/
ignoreFiles:
- src/foundations/*.scss
- src/css/ionic/*.scss
- src/css/core.scss
- src/css/flex-utils.scss
- src/css/normalize.scss
- src/css/text-alignment.scss
- src/css/display.scss
- src/themes/mixins.scss
- src/themes/functions.color.scss
- src/themes/functions.string.scss
- src/themes/native.theme.default.scss
- src/themes/ionic.mixins.scss
- src/themes/ionic.functions.color.scss
- src/themes/ionic.functions.string.scss
- src/themes/ionic.theme.default.scss
- src/css/themes/*.scss
- scripts/tokens/*.css
indentation: 2
@@ -26,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
@@ -43,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
@@ -59,202 +57,203 @@ 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

View File

@@ -3,6 +3,33 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [8.2.5](https://github.com/ionic-team/ionic-framework/compare/v8.2.4...v8.2.5) (2024-07-03)
**Note:** Version bump only for package @ionic/core
## [8.2.4](https://github.com/ionic-team/ionic-framework/compare/v8.2.2...v8.2.4) (2024-06-28)
### Bug Fixes
* **angular:** popover arrow navigation with disabled items ([#29662](https://github.com/ionic-team/ionic-framework/issues/29662)) ([ceb41f3](https://github.com/ionic-team/ionic-framework/commit/ceb41f31f382ff1bcf81de2b11680699d33d5077)), closes [#29640](https://github.com/ionic-team/ionic-framework/issues/29640)
## 8.2.3
This version should be skipped. Install 8.2.4 instead.
## [8.2.2](https://github.com/ionic-team/ionic-framework/compare/v8.2.1...v8.2.2) (2024-06-12)

View File

@@ -1,5 +1,5 @@
# Get Playwright
FROM mcr.microsoft.com/playwright:v1.44.1
FROM mcr.microsoft.com/playwright:v1.45.0
# Set the working directory
WORKDIR /ionic

View File

File diff suppressed because it is too large Load Diff

1832
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.2.2",
"version": "8.2.5",
"description": "Base components for Ionic",
"keywords": [
"ionic",
@@ -23,6 +23,302 @@
"collection:main": "dist/collection/index.js",
"collection": "dist/collection/collection-manifest.json",
"types": "dist/types/interface.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.cjs.js",
"types": "./dist/types/interface.d.ts"
},
"./components": {
"import": "./components/index.js",
"types": "./components/index.d.ts"
},
"./loader": {
"import": "./loader/index.js",
"require": "./loader/index.cjs.js",
"types": "./loader/index.d.ts"
},
"./components/*": {
"import": "./components/*",
"types": "./components/*"
},
"./docs.json": {
"import": "./dist/docs.json",
"require": "./dist/docs.json"
},
"./ion-accordion-group": {
"import": "./components/ion-accordion-group.js",
"types": "./components/ion-accordion-group.d.ts"
},
"./ion-accordion": {
"import": "./components/ion-accordion.js",
"types": "./components/ion-accordion.d.ts"
},
"./ion-avatar": {
"import": "./components/ion-avatar.js",
"types": "./components/ion-avatar.d.ts"
},
"./ion-backdrop": {
"import": "./components/ion-backdrop.js",
"types": "./components/ion-backdrop.d.ts"
},
"./ion-badge": {
"import": "./components/ion-badge.js",
"types": "./components/ion-badge.d.ts"
},
"./ion-breadcrumbs": {
"import": "./components/ion-breadcrumbs.js",
"types": "./components/ion-breadcrumbs.d.ts"
},
"./ion-buttons": {
"import": "./components/ion-buttons.js",
"types": "./components/ion-buttons.d.ts"
},
"./ion-card-content": {
"import": "./components/ion-card-content.js",
"types": "./components/ion-card-content.d.ts"
},
"./ion-card-header": {
"import": "./components/ion-card-header.js",
"types": "./components/ion-card-header.d.ts"
},
"./ion-card-subtitle": {
"import": "./components/ion-card-subtitle.js",
"types": "./components/ion-card-subtitle.d.ts"
},
"./ion-card-title": {
"import": "./components/ion-card-title.js",
"types": "./components/ion-card-title.d.ts"
},
"./ion-checkbox": {
"import": "./components/ion-checkbox.js",
"types": "./components/ion-checkbox.d.ts"
},
"./ion-chip": {
"import": "./components/ion-chip.js",
"types": "./components/ion-chip.d.ts"
},
"./ion-col": {
"import": "./components/ion-col.js",
"types": "./components/ion-col.d.ts"
},
"./ion-content": {
"import": "./components/ion-content.js",
"types": "./components/ion-content.d.ts"
},
"./ion-datetime-button": {
"import": "./components/ion-datetime-button.js",
"types": "./components/ion-datetime-button.d.ts"
},
"./ion-datetime": {
"import": "./components/ion-datetime.js",
"types": "./components/ion-datetime.d.ts"
},
"./ion-fab-list": {
"import": "./components/ion-fab-list.js",
"types": "./components/ion-fab-list.d.ts"
},
"./ion-fab": {
"import": "./components/ion-fab.js",
"types": "./components/ion-fab.d.ts"
},
"./ion-footer": {
"import": "./components/ion-footer.js",
"types": "./components/ion-footer.d.ts"
},
"./ion-grid": {
"import": "./components/ion-grid.js",
"types": "./components/ion-grid.d.ts"
},
"./ion-header": {
"import": "./components/ion-header.js",
"types": "./components/ion-header.d.ts"
},
"./ion-img": {
"import": "./components/ion-img.js",
"types": "./components/ion-img.d.ts"
},
"./ion-infinite-scroll-content": {
"import": "./components/ion-infinite-scroll-content.js",
"types": "./components/ion-infinite-scroll-content.d.ts"
},
"./ion-infinite-scroll": {
"import": "./components/ion-infinite-scroll.js",
"types": "./components/ion-infinite-scroll.d.ts"
},
"./ion-input-password-toggle": {
"import": "./components/ion-input-password-toggle.js",
"types": "./components/ion-input-password-toggle.d.ts"
},
"./ion-input": {
"import": "./components/ion-input.js",
"types": "./components/ion-input.d.ts"
},
"./ion-item-divider": {
"import": "./components/ion-item-divider.js",
"types": "./components/ion-item-divider.d.ts"
},
"./ion-item-group": {
"import": "./components/ion-item-group.js",
"types": "./components/ion-item-group.d.ts"
},
"./ion-item-options": {
"import": "./components/ion-item-options.js",
"types": "./components/ion-item-options.d.ts"
},
"./ion-item-sliding": {
"import": "./components/ion-item-sliding.js",
"types": "./components/ion-item-sliding.d.ts"
},
"./ion-label": {
"import": "./components/ion-label.js",
"types": "./components/ion-label.d.ts"
},
"./ion-list-header": {
"import": "./components/ion-list-header.js",
"types": "./components/ion-list-header.d.ts"
},
"./ion-list": {
"import": "./components/ion-list.js",
"types": "./components/ion-list.d.ts"
},
"./ion-menu-button": {
"import": "./components/ion-menu-button.js",
"types": "./components/ion-menu-button.d.ts"
},
"./ion-menu-toggle": {
"import": "./components/ion-menu-toggle.js",
"types": "./components/ion-menu-toggle.d.ts"
},
"./ion-menu": {
"import": "./components/ion-menu.js",
"types": "./components/ion-menu.d.ts"
},
"./ion-nav-link": {
"import": "./components/ion-nav-link.js",
"types": "./components/ion-nav-link.d.ts"
},
"./ion-nav": {
"import": "./components/ion-nav.js",
"types": "./components/ion-nav.d.ts"
},
"./ion-note": {
"import": "./components/ion-note.js",
"types": "./components/ion-note.d.ts"
},
"./ion-picker-column-option": {
"import": "./components/ion-picker-column-option.js",
"types": "./components/ion-picker-column-option.d.ts"
},
"./ion-picker-column": {
"import": "./components/ion-picker-column.js",
"types": "./components/ion-picker-column.d.ts"
},
"./ion-picker": {
"import": "./components/ion-picker.js",
"types": "./components/ion-picker.d.ts"
},
"./ion-progress-bar": {
"import": "./components/ion-progress-bar.js",
"types": "./components/ion-progress-bar.d.ts"
},
"./ion-radio-group": {
"import": "./components/ion-radio-group.js",
"types": "./components/ion-radio-group.d.ts"
},
"./ion-radio": {
"import": "./components/ion-radio.js",
"types": "./components/ion-radio.d.ts"
},
"./ion-range": {
"import": "./components/ion-range.js",
"types": "./components/ion-range.d.ts"
},
"./ion-refresher-content": {
"import": "./components/ion-refresher-content.js",
"types": "./components/ion-refresher-content.d.ts"
},
"./ion-refresher": {
"import": "./components/ion-refresher.js",
"types": "./components/ion-refresher.d.ts"
},
"./ion-reorder-group": {
"import": "./components/ion-reorder-group.js",
"types": "./components/ion-reorder-group.d.ts"
},
"./ion-reorder": {
"import": "./components/ion-reorder.js",
"types": "./components/ion-reorder.d.ts"
},
"./ion-ripple-effect": {
"import": "./components/ion-ripple-effect.js",
"types": "./components/ion-ripple-effect.d.ts"
},
"./ion-row": {
"import": "./components/ion-row.js",
"types": "./components/ion-row.d.ts"
},
"./ion-searchbar": {
"import": "./components/ion-searchbar.js",
"types": "./components/ion-searchbar.d.ts"
},
"./ion-segment-button": {
"import": "./components/ion-segment-button.js",
"types": "./components/ion-segment-button.d.ts"
},
"./ion-segment": {
"import": "./components/ion-segment.js",
"types": "./components/ion-segment.d.ts"
},
"./ion-select-option": {
"import": "./components/ion-select-option.js",
"types": "./components/ion-select-option.d.ts"
},
"./ion-select": {
"import": "./components/ion-select.js",
"types": "./components/ion-select.d.ts"
},
"./ion-skeleton-text": {
"import": "./components/ion-skeleton-text.js",
"types": "./components/ion-skeleton-text.d.ts"
},
"./ion-spinner": {
"import": "./components/ion-spinner.js",
"types": "./components/ion-spinner.d.ts"
},
"./ion-split-pane": {
"import": "./components/ion-split-pane.js",
"types": "./components/ion-split-pane.d.ts"
},
"./ion-tab": {
"import": "./components/ion-tab.js",
"types": "./components/ion-tab.d.ts"
},
"./ion-text": {
"import": "./components/ion-text.js",
"types": "./components/ion-text.d.ts"
},
"./ion-textarea": {
"import": "./components/ion-textarea.js",
"types": "./components/ion-textarea.d.ts"
},
"./ion-thumbnail": {
"import": "./components/ion-thumbnail.js",
"types": "./components/ion-thumbnail.d.ts"
},
"./ion-title": {
"import": "./components/ion-title.js",
"types": "./components/ion-title.d.ts"
},
"./ion-toggle": {
"import": "./components/ion-toggle.js",
"types": "./components/ion-toggle.d.ts"
},
"./ion-toolbar": {
"import": "./components/ion-toolbar.js",
"types": "./components/ion-toolbar.d.ts"
}
},
"files": [
"components/",
"css/",
@@ -31,13 +327,12 @@
"loader/"
],
"dependencies": {
"@phosphor-icons/core": "^2.1.1",
"@stencil/core": "^4.17.2",
"@stencil/core": "^4.19.2",
"ionicons": "^7.2.2",
"tslib": "^2.1.0"
},
"devDependencies": {
"@axe-core/playwright": "^4.8.5",
"@axe-core/playwright": "^4.9.1",
"@capacitor/core": "^6.0.0",
"@capacitor/haptics": "^6.0.0",
"@capacitor/keyboard": "^6.0.0",
@@ -45,7 +340,7 @@
"@clack/prompts": "^0.7.0",
"@ionic/eslint-config": "^0.3.0",
"@ionic/prettier-config": "^2.0.0",
"@playwright/test": "^1.39.0",
"@playwright/test": "^1.45.0",
"@rollup/plugin-node-resolve": "^8.4.0",
"@rollup/plugin-virtual": "^2.0.3",
"@stencil/angular-output-target": "^0.8.4",
@@ -66,20 +361,18 @@
"fs-extra": "^9.0.1",
"jest": "^29.7.0",
"jest-cli": "^29.7.0",
"prettier": "^2.8.8",
"prettier": "^2.6.1",
"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/index.js && npm run lint.fix && npm run prettier.tokens",
"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",
@@ -91,8 +384,7 @@
"lint.ts": "npm run eslint",
"lint.ts.fix": "npm run eslint -- --fix",
"prerender.e2e": "node scripts/testing/prerender.js",
"prettier": "prettier \"./src/**/*.{html,ts,tsx,js,jsx,scss}\"",
"prettier.tokens": "prettier \"./src/foundations/*.{scss, html}\" --write --cache",
"prettier": "prettier \"./src/**/*.{html,ts,tsx,js,jsx}\"",
"start": "npm run build.css && stencil build --dev --watch --serve",
"test": "npm run test.spec && npm run test.e2e",
"test.spec": "stencil test --spec --max-workers=2",

View File

@@ -1,375 +0,0 @@
/* eslint-disable @typescript-eslint/no-var-requires */
// 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.
const fs = require('fs');
const path = require('path');
const StyleDictionary = require('style-dictionary');
const targetPath = './src/foundations/';
const {
variablesPrefix,
getRgbaValue,
hexToRgb,
generateShadowValue,
generateFontSizeValue,
generateFontFamilyValue,
generateTypographyValue,
generateRgbValue,
generateColorUtilityClasses,
generateFontUtilityClass,
generateSpaceUtilityClasses,
generateTypographyUtilityClass,
} = require('./utilities');
const { fileHeader } = StyleDictionary.formatHelpers;
// CSS vanilla :root format
StyleDictionary.registerFormat({
name: 'rootFormat',
formatter({ dictionary, file }) {
/*
* This will loop through all tokens and based on the type it will
* call a utility function that will return the expected format for the CSS Variable
*/
const prefixedVariables = dictionary.allProperties
.filter((prop) => prop['$type'] !== 'typography')
.map((prop) => {
if (prop.attributes.category.startsWith('Elevation')) {
const cssShadow = prop.value.map(generateShadowValue).join(', ');
return `--${variablesPrefix}-${prop.name}: ${cssShadow};`;
} else if (prop.attributes.category.match('font-family')) {
return generateFontFamilyValue(prop);
} else if (prop.attributes.category.match('font-size')) {
return generateFontSizeValue(prop);
} else {
const rgb = hexToRgb(prop.value);
prop.value = getRgbaValue(prop.value);
return ` --${variablesPrefix}-${prop.name}: ${prop.value};${
rgb ? `\n --${variablesPrefix}-${prop.name}-rgb: ${rgb.r}, ${rgb.g}, ${rgb.b};` : ``
}`;
}
});
return [
fileHeader({ file }),
'@use "../themes/functions.sizes" as font;\n',
':root {\n' + prefixedVariables.join('\n') + '\n}\n',
].join('\n');
},
});
// SCSS variables format
StyleDictionary.registerFormat({
name: 'scssVariablesFormat',
formatter({ dictionary, file }) {
const typographyProperties = dictionary.allProperties.filter((prop) => prop['$type'] === 'typography');
const otherProperties = dictionary.allProperties.filter((prop) => prop['$type'] !== 'typography');
// Make sure the reused scss variables are defined first, to avoid compilation errors
const sortedProperties = [...otherProperties, ...typographyProperties];
const prefixedVariables = sortedProperties.map((prop) => {
if (prop.attributes.category.startsWith('Elevation')) {
const cssShadow = prop.value.map(generateShadowValue).join(', ');
return `$${variablesPrefix}-${prop.name}: var(--${variablesPrefix}-${prop.name}, ${cssShadow});`;
} else if (prop.attributes.category.match('font-family')) {
return generateFontFamilyValue(prop, 'scss');
} else if (prop.attributes.category.match('font-size')) {
return generateFontSizeValue(prop, 'scss');
} else if (prop['$type'] === 'typography') {
return generateTypographyValue(prop, dictionary);
} else {
return generateRgbValue(prop);
}
});
return [
fileHeader({ file }),
'@use "../themes/functions.sizes" as font;\n',
prefixedVariables.join('\n') + '\n',
].join('\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 = '';
if (tokenType.startsWith('Elevation')) {
return `.${variablesPrefix}-${className} {\n box-shadow: $ionic-${prop.name};\n}`;
} else if (prop['$type'] === 'typography') {
return generateTypographyUtilityClass(prop, dictionary);
/*
* Not creating for the tokens below, as they make no sense to exist as utility-classes.
* Font-family should be defined on global scope, not component.
* Scale its an abstract token group, to be used by other tokens, like the space ones.
*/
} else if (prop.attributes.category.match('font-family') || tokenType === 'scale') {
return;
}
const tokenTypeLower = tokenType.toLowerCase();
switch (tokenTypeLower) {
case 'color':
case 'state':
case 'guidelines':
case 'disabled':
case 'hover':
case 'pressed':
utilityClass = generateColorUtilityClasses(prop, className);
break;
case 'border-size':
utilityClass = `.${variablesPrefix}-${className} {\n border-width: $ionic-${prop.name};\n}`;
break;
case 'font':
utilityClass = generateFontUtilityClass(prop, className);
break;
case 'space':
utilityClass = generateSpaceUtilityClasses(prop, className);
break;
default:
utilityClass = `.${variablesPrefix}-${className} {\n ${tokenType}: $ionic-${prop.name};\n}`;
}
return utilityClass;
});
return [
fileHeader({ file }),
'@import "./ionic.vars";\n@import "../themes/mixins";\n',
utilityClasses.join('\n'),
].join('\n');
},
});
// Register the custom format to generate HTML
// Load the HTML template
const template = fs.readFileSync(path.join(__dirname, 'preview.template.html'), 'utf8');
StyleDictionary.registerFormat({
name: 'html/tokens',
formatter: function ({ dictionary }) {
// Function to extract numerical value from token name
const extractValue = (tokenName) => {
const match = tokenName.match(/-([0-9]+)/);
return match ? parseInt(match[1], 10) : Number.MAX_SAFE_INTEGER;
};
let colorTokens = `
<table>
<thead>
<tr>
<th>Color</th>
<th>Hex</th>
<th>Token Name</th>
</tr>
</thead>
<tbody>
`;
let fontSizeTokens = '';
let boxShadowTokens = '';
let borderSizeTokens = '';
let borderRadiusTokens = '';
let borderStyleTokens = '';
let fontWeightTokens = '';
let letterSpacingTokens = '';
let spaceTokens = '';
// Collect border-radius and space tokens for separate sorting
let borderRadiusTokenList = [];
let spaceTokenList = [];
dictionary.allProperties.forEach((token) => {
if (token.attributes.category === 'color') {
colorTokens += `
<tr>
<td><div class="color-swatch" style="background-color: ${token.value};"></div></td>
<td>${token.value}</td>
<td>${token.name}</td>
</tr>
`;
} else if (token.attributes.category === 'font-size') {
fontSizeTokens += `
<div class="font-size-token" style="font-size: ${token.value};">
${token.name} (${token.value})
</div>
`;
} else if (token.attributes.category.startsWith('Elevation')) {
const cssShadow = token.value.map(generateShadowValue).join(', ');
boxShadowTokens += `
<div class="shadow-token" style="box-shadow: ${cssShadow};">
${token.name}
</div>
`;
} else if (token.attributes.category === 'border-size' || token.attributes.category === 'border-width') {
borderSizeTokens += `
<div class="border-token" style="border-width: ${token.value};">
${token.name} (${token.value})
</div>
`;
} else if (token.attributes.category === 'border-radius') {
borderRadiusTokenList.push(token); // Collect border-radius tokens
} else if (token.attributes.category === 'border-style') {
borderStyleTokens += `
<div class="border-token" style="border: 1px ${token.value} #000;">
${token.name} (${token.value})
</div>
`;
} else if (token.attributes.category === 'font-weight') {
fontWeightTokens += `
<div class="weight-token" style="font-weight: ${token.value};">
${token.name} (${token.value})
</div>
`;
} else if (token.attributes.category === 'letter-spacing') {
// Convert % to px
const letterSpacingValue = token.value.replace('%', '') + 'px';
letterSpacingTokens += `
<div class="letter-spacing-token" style="letter-spacing: ${letterSpacingValue};">
${token.name} (${letterSpacingValue})
</div>
`;
} else if (token.attributes.category === 'space') {
spaceTokenList.push(token); // Collect space tokens
}
});
// Sort border-radius and space tokens
borderRadiusTokenList.sort((a, b) => extractValue(a.name) - extractValue(b.name));
spaceTokenList.sort((a, b) => extractValue(a.name) - extractValue(b.name));
// Generate HTML for sorted border-radius tokens
borderRadiusTokenList.forEach((token) => {
borderRadiusTokens += `
<div class="border-token" style="border-radius: ${token.value};">
${token.name} (${token.value})
</div>
`;
});
// Generate HTML for sorted space tokens
spaceTokenList.forEach((token) => {
spaceTokens += `
<div class="spacing-wrapper">
<div class="space-token" style="margin: ${token.value};">
${token.name} (${token.value})
</div>
</div>
`;
});
colorTokens += '</tbody></table>';
return template
.replace('{{colorTokens}}', colorTokens)
.replace('{{fontSizeTokens}}', fontSizeTokens)
.replace('{{boxShadowTokens}}', boxShadowTokens)
.replace('{{borderSizeTokens}}', borderSizeTokens)
.replace('{{borderRadiusTokens}}', borderRadiusTokens)
.replace('{{borderStyleTokens}}', borderStyleTokens)
.replace('{{fontWeightTokens}}', fontWeightTokens)
.replace('{{letterSpacingTokens}}', letterSpacingTokens)
.replace('{{spaceTokens}}', spaceTokens);
},
});
// Custom transform to ensure unique token names
StyleDictionary.registerTransform({
name: 'name/cti/kebab-unique',
type: 'name',
transformer: function (prop, options) {
return [options.prefix].concat(prop.path).join('-').toLowerCase();
},
});
// Register the custom transform group for html file generation
StyleDictionary.registerTransformGroup({
name: 'custom',
transforms: ['attribute/cti', 'name/cti/kebab-unique', 'size/rem', 'color/css'],
});
// Make Style Dictionary comply with the $ format on properties from W3C Guidelines
const w3cTokenJsonParser = {
pattern: /\.json|\.tokens\.json|\.tokens$/,
parse({ 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/tokens/*.json', './src/foundations/tokens/theme/*.json'],
platforms: {
css: {
buildPath: targetPath,
transformGroup: 'css',
files: [
{
destination: 'ionic.root.scss',
format: 'rootFormat',
options: {
outputReferences: true,
fileHeader: `myFileHeader`,
},
},
],
},
scss: {
buildPath: targetPath,
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`,
},
},
],
},
html: {
transformGroup: 'custom',
buildPath: targetPath,
files: [
{
destination: 'tokens.preview.html',
format: 'html/tokens',
},
],
},
},
fileHeader: {
myFileHeader: () => {
return [`This is an auto-generated file, please do not change it directly.`, `Ionic Design System`];
},
},
}).buildAllPlatforms();

View File

@@ -1,63 +0,0 @@
table {
width: 100%;
border-collapse: collapse;
margin-bottom: 20px;
}
th,
td {
padding: 10px;
border: 1px solid #ccc;
text-align: left;
}
th {
background-color: #f4f4f4;
}
thead th {
position: sticky;
top: 0;
background-color: #f4f4f4;
z-index: 1;
}
.color-swatch {
width: 50px;
height: 50px;
}
.font-size-token,
.weight-token,
.letter-spacing-token {
margin: 10px 0;
}
.border-token,
.shadow-token {
margin: 10px;
padding: 10px;
}
.border-token {
border: 1px solid #000;
}
.spacing-wrapper {
background-color: lightblue;
}
.spacing-wrapper > div {
background-color: #fff;
}
.token-wrapper:has(.spacing-wrapper) {
display: flex;
flex-direction: column;
gap: 20px;
}
hr {
background-color: #ccc;
margin: 20px 0;
}

View File

@@ -1,52 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<title>Design Tokens</title>
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
<link rel="stylesheet" href="../../scripts/tokens/preview.styles.css" />
</head>
<body>
<ion-app>
<ion-header>
<ion-toolbar>
<ion-title>Design Tokens - Preview</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding-horizontal">
<h1>Color Tokens</h1>
<div class="token-wrapper">{{colorTokens}}</div>
<hr />
<h1>Font Size Tokens</h1>
<div class="token-wrapper">{{fontSizeTokens}}</div>
<hr />
<h1>Font Weight Tokens</h1>
<div class="token-wrapper">{{fontWeightTokens}}</div>
<hr />
<h1>Letter Spacing Tokens</h1>
<div class="token-wrapper">{{letterSpacingTokens}}</div>
<hr />
<h1>Box Shadow Tokens</h1>
<div class="token-wrapper">{{boxShadowTokens}}</div>
<hr />
<h1>Border Size Tokens</h1>
<div class="token-wrapper">{{borderSizeTokens}}</div>
<hr />
<h1>Border Radius Tokens</h1>
<div class="token-wrapper">{{borderRadiusTokens}}</div>
<hr />
<h1>Border Style Tokens</h1>
<div class="token-wrapper">{{borderStyleTokens}}</div>
<hr />
<h1>Space Tokens</h1>
<div class="token-wrapper">{{spaceTokens}}</div>
</ion-content>
</ion-app>
</body>
</html>

View File

@@ -1,191 +0,0 @@
const variablesPrefix = 'ionic'; // Variable that holds the prefix used on all css and scss variables generated
// Generates a valid rgba() color
function getRgbaValue(propValue) {
// Check if its rgba color
const isRgba = hexToRgba(propValue);
// If it is, then compose rgba() color, otherwise use the normal color
if (isRgba !== null) {
return (propValue = `rgba(${isRgba.r}, ${isRgba.g}, ${isRgba.b},${isRgba.a})`);
} else {
return propValue;
}
}
// Translates an hex color value to rgb
function hexToRgb(hex) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result
? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16),
}
: null;
}
// Translates an hex color value to rgba
function hexToRgba(hex) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result
? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16),
a: Math.round((parseInt(result[4], 16) * 100) / 255) / 100,
}
: null;
}
// Generates a valid box-shadow value from a shadow Design Token structure
function generateShadowValue(shadow) {
const color = getRgbaValue(shadow.color);
return `${shadow.offsetX} ${shadow.offsetY} ${shadow.blur} ${shadow.spread} ${color}`;
}
// Generates a valid font-size value from a font-size Design Token structure, while transforming the pixels to rem
function generateFontSizeValue(prop, variableType = 'css') {
return variableType === 'scss'
? `$${variablesPrefix}-${prop.name}: var(--${variablesPrefix}-${prop.name}, font.px-to-rem(${parseInt(
prop.value
)}));`
: `--${variablesPrefix}-${prop.name}: #{font.px-to-rem(${parseInt(prop.value)})};`;
}
// Generates a valid font-family value from a font-family Design Token structure
function generateFontFamilyValue(prop, variableType = 'css') {
// Remove the last word from the token, as it contains the name of the font, which we don't want to be included on the generated variables
const propName = prop.name.split('-').slice(0, -1).join('-');
return variableType === 'scss'
? `$${variablesPrefix}-${propName}: var(--${variablesPrefix}-${propName}, "${prop.value}", sans-serif);`
: `--${variablesPrefix}-${propName}: "${prop.value}", sans-serif;`;
}
// Generates a typography based scss map from a typography Design Token structure
function generateTypographyValue(prop, dictionary) {
const typography = prop.value;
const fontSizeMap = getTypeMap(dictionary, 'font-size');
const fontWeightMap = getTypeMap(dictionary, 'font-weight');
const lineHeightMap = getTypeMap(dictionary, 'line-height');
const letterSpacingMap = getTypeMap(dictionary, 'letter-spacing');
const fontStyle = prop.attributes.item?.toLowerCase() === 'italic' ? 'italic' : 'normal';
// This exact format is needed so that it compiles the tokens with the expected lint rules
return `
$${variablesPrefix}-${prop.name}: (
font-size: $ionic-font-size-${fontSizeMap[typography.fontSize]},
font-style: ${fontStyle},
font-weight: $ionic-font-weight-${fontWeightMap[typography.fontWeight]},
letter-spacing: $ionic-letter-spacing-${letterSpacingMap[typography.letterSpacing] || 0},
line-height: $ionic-line-height-${lineHeightMap[typography.lineHeight]},
text-transform: ${typography.textTransform},
text-decoration: ${typography.textDecoration}
);
`;
}
// To abstract the need to loop across all tokens from a given type
function getTypeMap(dictionary, type) {
return Object.fromEntries(
Object.entries(dictionary.properties[type]).map(([key, token]) => [token.value, token.attributes.type])
);
}
// Generates a final value, based if the Design Token is of type color or not
function generateValue(prop) {
const rgb = hexToRgb(prop.value);
let rgbDeclaration = '';
if (rgb) {
// If the token is color, also add a rgb variable using the same color
rgbDeclaration = `\n$${variablesPrefix}-${prop.name}-rgb: var(--${variablesPrefix}-${prop.name}-rgb, ${rgb.r}, ${rgb.g}, ${rgb.b});`;
}
prop.value = getRgbaValue(prop.value);
return `$${variablesPrefix}-${prop.name}: var(--${variablesPrefix}-${prop.name}, ${prop.value});${rgbDeclaration}`;
}
// Generates a typography based css utility-class from a typography Design Token structure
function generateTypographyUtilityClass(prop, dictionary) {
const typography = prop.value;
const fontSizeMap = getTypeMap(dictionary, 'font-size');
const fontWeightMap = getTypeMap(dictionary, 'font-weight');
const lineHeightMap = getTypeMap(dictionary, 'line-height');
const letterSpacingMap = getTypeMap(dictionary, 'letter-spacing');
const fontStyle = prop.attributes.item?.toLowerCase() === 'italic' ? 'italic' : 'normal';
// This exact format is needed so that it compiles the tokens with the expected lint rules
return `
.${variablesPrefix}-${prop.name} {
font-size: $ionic-font-size-${fontSizeMap[typography.fontSize]};
font-style: ${fontStyle};
font-weight: $ionic-font-weight-${fontWeightMap[typography.fontWeight]};
letter-spacing: $ionic-letter-spacing-${letterSpacingMap[typography.letterSpacing] || 0};
line-height: $ionic-line-height-${lineHeightMap[typography.lineHeight]};
text-transform: ${typography.textTransform};
text-decoration: ${typography.textDecoration};
};
`;
}
// Generates a color based css utility-class from a color Design Token structure
function generateColorUtilityClasses(prop, className) {
return `.${variablesPrefix}-${className} {\n color: $ionic-${prop.name};\n}
.${variablesPrefix}-background-${className} {\n background-color: $ionic-${prop.name};\n}`;
}
// Generates a font based css utility-class from a font Design Token structure
function generateFontUtilityClass(prop, className) {
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;
}
return `.${variablesPrefix}-${className} {\n ${fontAttribute}: $ionic-${prop.name};\n}`;
}
// Generates a margin or padding based css utility-class from a space Design Token structure
function generateSpaceUtilityClasses(prop, className) {
// This exact format is needed so that it compiles the tokens with the expected lint rules
const marginPaddingTemplate = (type) => `
.${variablesPrefix}-${type}-${className} {
--${type}-start: #{$ionic-${prop.name}};
--${type}-end: #{$ionic-${prop.name}};
--${type}-top: #{$ionic-${prop.name}};
--${type}-bottom: #{$ionic-${prop.name}};
@include ${type}($ionic-${prop.name});
};`;
return `${marginPaddingTemplate('margin')}\n${marginPaddingTemplate('padding')}`;
}
// Export all methods to be used on the tokens.js script
module.exports = {
variablesPrefix,
getRgbaValue,
hexToRgb,
hexToRgba,
generateShadowValue,
generateFontSizeValue,
generateFontFamilyValue,
generateTypographyValue,
generateRgbValue: generateValue,
generateColorUtilityClasses,
generateFontUtilityClass,
generateSpaceUtilityClasses,
generateTypographyUtilityClass,
};

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

File diff suppressed because it is too large Load Diff

View File

@@ -11,12 +11,7 @@
:host(.accordion-group-expand-inset) ::slotted(ion-accordion.accordion-expanding),
:host(.accordion-group-expand-inset) ::slotted(ion-accordion.accordion-expanded) {
@include margin($accordion-md-expanded-margin, 0, $accordion-md-expanded-margin, 0);
@include border-radius(
$accordion-md-border-radius,
$accordion-md-border-radius,
$accordion-md-border-radius,
$accordion-md-border-radius
);
@include border-radius($accordion-md-border-radius, $accordion-md-border-radius, $accordion-md-border-radius, $accordion-md-border-radius);
}
:host(.accordion-group-expand-inset) ::slotted(ion-accordion.accordion-previous) {

View File

@@ -1,4 +1,4 @@
@import "../../themes/native/native.globals";
@import "../../themes/ionic.globals";
@import "../accordion/accordion.vars";
// Accordion Group

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,
})
@@ -280,12 +278,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

@@ -1,14 +1,13 @@
@import "../../themes/native/native.globals.md";
@import "../../themes/ionic.globals.md";
// Accordion
// --------------------------------------------------
/// @prop - Border radius applied to the accordion
$accordion-md-border-radius: 6px;
$accordion-md-border-radius: 6px;
/// @prop - Box shadow of the accordion
$accordion-md-box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14),
0px 1px 5px 0px rgba(0, 0, 0, 0.12);
$accordion-md-box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
/// @prop - Margin of the expanded accordion
$accordion-md-expanded-margin: 16px;
$accordion-md-expanded-margin: 16px;

View File

@@ -1,11 +1,10 @@
import caretDownRegular from '@phosphor-icons/core/assets/regular/caret-down.svg';
import type { ComponentInterface } from '@stencil/core';
import { Component, Element, Host, Prop, State, Watch, h } from '@stencil/core';
import { addEventListener, getElementRoot, raf, removeEventListener, transitionEndAsync } from '@utils/helpers';
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,
@@ -15,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.
@@ -33,7 +31,6 @@ const enum AccordionState {
styleUrls: {
ios: 'accordion.ios.scss',
md: 'accordion.md.scss',
ionic: 'accordion.md.scss',
},
shadow: {
delegatesFocus: true,
@@ -80,7 +77,7 @@ export class Accordion implements ComponentInterface {
* rotated when the accordion is expanded
* or collapsed.
*/
@Prop() toggleIcon?: string;
@Prop() toggleIcon = chevronDown;
/**
* The slot inside of `ion-item` to
@@ -188,34 +185,13 @@ export class Accordion implements ComponentInterface {
button.setAttribute('aria-expanded', `${expanded}`);
};
get accordionToggleIcon() {
// Return the icon if it is explicitly set
if (this.toggleIcon != null) {
return this.toggleIcon;
}
// Determine the theme and map to default icons
const theme = getIonTheme(this);
const defaultIcons = {
ios: chevronDown,
ionic: caretDownRegular,
md: chevronDown,
};
// Get the default icon based on the theme, falling back to 'md' icon if necessary
const defaultIcon = defaultIcons[theme] || defaultIcons.md;
// Return the configured accordion toggle icon or the default icon
return config.get('accordionToggleIcon', defaultIcon);
}
private slotToggleIcon = () => {
const ionItem = this.getSlottedHeaderIonItem();
if (!ionItem) {
return;
}
const { accordionToggleIcon, toggleIconSlot } = this;
const { toggleIconSlot, toggleIcon } = this;
/**
* Check if there already is a toggle icon.
@@ -230,7 +206,7 @@ export class Accordion implements ComponentInterface {
iconEl.slot = toggleIconSlot;
iconEl.lazy = false;
iconEl.classList.add('ion-accordion-toggle-icon');
iconEl.icon = accordionToggleIcon;
iconEl.icon = toggleIcon;
iconEl.setAttribute('aria-hidden', 'true');
ionItem.appendChild(iconEl);
@@ -426,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';
@@ -436,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,19 +1,19 @@
@import "../../themes/native/native.globals";
@import "../../themes/ionic.globals";
// Accordion
// --------------------------------------------------
/// @prop - Background color of the accordion
$accordion-background-color: var(--ion-background-color, #ffffff);
$accordion-background-color: var(--ion-background-color, #ffffff);
/// @prop - Duration of the accordion transition
$accordion-transition-duration: 300ms;
$accordion-transition-duration: 300ms;
/// @prop - Timing function of the accordion transition
$accordion-transition-easing: cubic-bezier(0.25, 0.8, 0.5, 1);
$accordion-transition-easing: cubic-bezier(0.25, 0.8, 0.5, 1);
/// @prop - Opacity of the disabled accordion
$accordion-disabled-opacity: 0.4;
$accordion-disabled-opacity: 0.4;
/// @prop - Margin of the inset accordion
$accordion-inset-margin: 16px;
$accordion-inset-margin: 16px;

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

@@ -9,11 +9,11 @@
--backdrop-opacity: var(--ion-backdrop-opacity, 0.4);
--button-background: #{$action-sheet-ios-button-background};
--button-background-activated: #{$action-sheet-ios-button-background-activated};
--button-background-activated-opacity: 0.08;
--button-background-activated-opacity: .08;
--button-background-hover: currentColor;
--button-background-hover-opacity: 0.04;
--button-background-hover-opacity: .04;
--button-background-focused: currentColor;
--button-background-focused-opacity: 0.12;
--button-background-focused-opacity: .12;
--button-background-selected: #{$action-sheet-ios-button-background-selected};
--button-background-selected-opacity: 1;
--button-color: #{$action-sheet-ios-button-text-color};
@@ -51,14 +51,10 @@
// ---------------------------------------------------
.action-sheet-container {
@include padding(
$action-sheet-ios-padding-top,
$action-sheet-ios-padding-end,
$action-sheet-ios-padding-bottom,
$action-sheet-ios-padding-start
);
@include padding($action-sheet-ios-padding-top, $action-sheet-ios-padding-end, $action-sheet-ios-padding-bottom, $action-sheet-ios-padding-start);
}
// iOS Action Sheet Group
// ---------------------------------------------------
@@ -75,6 +71,7 @@
@include margin(null, null, $action-sheet-ios-group-margin-bottom, null);
}
// iOS Translucent Action Sheet
// ---------------------------------------------------
@@ -87,17 +84,9 @@
:host(.action-sheet-translucent) .action-sheet-title,
:host(.action-sheet-translucent) .action-sheet-button {
background-color: transparent;
background-image: linear-gradient(
0deg,
$action-sheet-ios-translucent-background-color,
$action-sheet-ios-translucent-background-color 100%
),
linear-gradient(
0deg,
$action-sheet-ios-translucent-border-color,
$action-sheet-ios-translucent-border-color 50%,
$action-sheet-ios-translucent-background-color 50%
);
background-image:
linear-gradient(0deg, $action-sheet-ios-translucent-background-color, $action-sheet-ios-translucent-background-color 100%),
linear-gradient(0deg, $action-sheet-ios-translucent-border-color, $action-sheet-ios-translucent-border-color 50%, $action-sheet-ios-translucent-background-color 50%);
background-repeat: no-repeat;
/* stylelint-disable-next-line all */
@@ -126,16 +115,12 @@
background: $action-sheet-ios-button-background;
}
// iOS Action Sheet Title
// ---------------------------------------------------
.action-sheet-title {
@include padding(
$action-sheet-ios-title-padding-top,
$action-sheet-ios-title-padding-end,
$action-sheet-ios-title-padding-bottom,
$action-sheet-ios-title-padding-start
);
@include padding($action-sheet-ios-title-padding-top, $action-sheet-ios-title-padding-end, $action-sheet-ios-title-padding-bottom, $action-sheet-ios-title-padding-start);
color: var(--color, $action-sheet-ios-title-color);
@@ -150,18 +135,14 @@
}
.action-sheet-sub-title {
@include padding(
$action-sheet-ios-sub-title-padding-top,
$action-sheet-ios-sub-title-padding-end,
$action-sheet-ios-sub-title-padding-bottom,
$action-sheet-ios-sub-title-padding-start
);
@include padding($action-sheet-ios-sub-title-padding-top, $action-sheet-ios-sub-title-padding-end, $action-sheet-ios-sub-title-padding-bottom, $action-sheet-ios-sub-title-padding-start);
font-size: $action-sheet-ios-sub-title-font-size;
font-weight: $action-sheet-ios-title-font-weight;
}
// iOS Action Sheet Buttons
// ---------------------------------------------------

View File

@@ -1,163 +1,148 @@
@import "../../themes/native/native.globals.ios";
@import "../../themes/ionic.globals.ios";
// iOS Action Sheet
// --------------------------------------------------
/// @prop - Text align of the action sheet
$action-sheet-ios-text-align: center;
$action-sheet-ios-text-align: center;
/// @prop - Padding top of the action sheet
$action-sheet-ios-padding-top: 0;
$action-sheet-ios-padding-top: 0;
/// @prop - Padding end of the action sheet
$action-sheet-ios-padding-end: 8px;
$action-sheet-ios-padding-end: 8px;
/// @prop - Padding bottom of the action sheet
$action-sheet-ios-padding-bottom: $action-sheet-ios-padding-top;
$action-sheet-ios-padding-bottom: $action-sheet-ios-padding-top;
/// @prop - Padding start of the action sheet
$action-sheet-ios-padding-start: $action-sheet-ios-padding-end;
$action-sheet-ios-padding-start: $action-sheet-ios-padding-end;
/// @prop - Top margin of the action sheet button group
$action-sheet-ios-group-margin-top: 10px;
$action-sheet-ios-group-margin-top: 10px;
/// @prop - Bottom margin of the action sheet button group
$action-sheet-ios-group-margin-bottom: 10px;
$action-sheet-ios-group-margin-bottom: 10px;
/// @prop - Background color of the action sheet
$action-sheet-ios-background-color: $overlay-ios-background-color;
$action-sheet-ios-background-color: $overlay-ios-background-color;
/// @prop - Border radius of the action sheet
$action-sheet-ios-border-radius: 13px;
$action-sheet-ios-border-radius: 13px;
// Action Sheet Title
// --------------------------------------------------
/// @prop - Padding top of the action sheet title
$action-sheet-ios-title-padding-top: 14px;
$action-sheet-ios-title-padding-top: 14px;
/// @prop - Padding end of the action sheet title
$action-sheet-ios-title-padding-end: 10px;
$action-sheet-ios-title-padding-end: 10px;
/// @prop - Padding bottom of the action sheet title
$action-sheet-ios-title-padding-bottom: 13px;
$action-sheet-ios-title-padding-bottom: 13px;
/// @prop - Padding start of the action sheet title
$action-sheet-ios-title-padding-start: $action-sheet-ios-title-padding-end;
$action-sheet-ios-title-padding-start: $action-sheet-ios-title-padding-end;
/// @prop - Color of the action sheet title
$action-sheet-ios-title-color: $text-color-step-600;
$action-sheet-ios-title-color: $text-color-step-600;
/// @prop - Font size of the action sheet title
$action-sheet-ios-title-font-size: dynamic-font-min(1, 13px);
$action-sheet-ios-title-font-size: dynamic-font-min(1, 13px);
/// @prop - Font weight of the action sheet title
$action-sheet-ios-title-font-weight: 400;
$action-sheet-ios-title-font-weight: 400;
/// @prop - Font weight of the action sheet title when it has a sub title
$action-sheet-ios-title-with-sub-title-font-weight: 600;
$action-sheet-ios-title-with-sub-title-font-weight: 600;
// Action Sheet Subtitle
// --------------------------------------------------
/// @prop - Font size of the action sheet sub title
$action-sheet-ios-sub-title-font-size: dynamic-font-min(1, 13px);
$action-sheet-ios-sub-title-font-size: dynamic-font-min(1, 13px);
/// @prop - Padding top of the action sheet sub title
$action-sheet-ios-sub-title-padding-top: 6px;
$action-sheet-ios-sub-title-padding-top: 6px;
/// @prop - Padding end of the action sheet sub title
$action-sheet-ios-sub-title-padding-end: 0;
$action-sheet-ios-sub-title-padding-end: 0;
/// @prop - Padding bottom of the action sheet sub title
$action-sheet-ios-sub-title-padding-bottom: 0;
$action-sheet-ios-sub-title-padding-bottom: 0;
/// @prop - Padding start of the action sheet sub title
$action-sheet-ios-sub-title-padding-start: $action-sheet-ios-sub-title-padding-end;
$action-sheet-ios-sub-title-padding-start: $action-sheet-ios-sub-title-padding-end;
// Action Sheet Button
// --------------------------------------------------
/// @prop - Minimum height of the action sheet button
$action-sheet-ios-button-height: 56px;
$action-sheet-ios-button-height: 56px;
/// @prop - Padding of the action sheet button
$action-sheet-ios-button-padding: 14px;
$action-sheet-ios-button-padding: 14px;
/// @prop - Text color of the action sheet button
$action-sheet-ios-button-text-color: ion-color(primary, base);
$action-sheet-ios-button-text-color: ion-color(primary, base);
/// @prop - Font size of the action sheet button icon
$action-sheet-ios-button-icon-font-size: dynamic-font-min(1, 28px);
$action-sheet-ios-button-icon-font-size: dynamic-font-min(1, 28px);
/// @prop - Padding right of the action sheet button icon
$action-sheet-ios-button-icon-padding-right: 0.3em;
$action-sheet-ios-button-icon-padding-right: .3em;
/// @prop - Font size of the action sheet button
$action-sheet-ios-button-font-size: dynamic-font-min(1, 20px);
$action-sheet-ios-button-font-size: dynamic-font-min(1, 20px);
/// @prop - Border color alpha of the action sheet button
$action-sheet-ios-button-border-color-alpha: 0.08;
$action-sheet-ios-button-border-color-alpha: .08;
/// @prop - Border color of the action sheet button
$action-sheet-ios-button-border-color: rgba($text-color-rgb, $action-sheet-ios-button-border-color-alpha);
$action-sheet-ios-button-border-color: rgba($text-color-rgb, $action-sheet-ios-button-border-color-alpha);
/// @prop - Background color of the action sheet button
$action-sheet-ios-button-background: linear-gradient(
0deg,
$action-sheet-ios-button-border-color,
$action-sheet-ios-button-border-color 50%,
transparent 50%
)
bottom / 100% 1px no-repeat transparent;
$action-sheet-ios-button-background: linear-gradient(0deg, $action-sheet-ios-button-border-color, $action-sheet-ios-button-border-color 50%, transparent 50%) bottom / 100% 1px no-repeat transparent;
/// @prop - Background color of the activated action sheet button
$action-sheet-ios-button-background-activated: $text-color;
$action-sheet-ios-button-background-activated: $text-color;
/// @prop - Background color of the selected action sheet button
$action-sheet-ios-button-background-selected: var(
--ion-color-step-150,
var(--ion-background-color-step-150, $background-color)
);
$action-sheet-ios-button-background-selected: var(--ion-color-step-150, var(--ion-background-color-step-150, $background-color));
/// @prop - Destructive text color of the action sheet button
$action-sheet-ios-button-destructive-text-color: ion-color(danger, base);
$action-sheet-ios-button-destructive-text-color: ion-color(danger, base);
/// @prop - Font weight of the action sheet cancel button
$action-sheet-ios-button-cancel-font-weight: 600;
$action-sheet-ios-button-cancel-font-weight: 600;
// Action Sheet Translucent
// --------------------------------------------------
/// @prop - Background color alpha of the action sheet when translucent
$action-sheet-ios-translucent-background-color-alpha: 0.8;
$action-sheet-ios-translucent-background-color-alpha: .8;
/// @prop - Background color of the action sheet when translucent
$action-sheet-ios-translucent-background-color: rgba(
$background-color-rgb,
$action-sheet-ios-translucent-background-color-alpha
);
$action-sheet-ios-translucent-background-color: rgba($background-color-rgb, $action-sheet-ios-translucent-background-color-alpha);
/// @prop - Border color alpha of the action sheet when translucent
$action-sheet-ios-translucent-border-color-alpha: 0.4;
$action-sheet-ios-translucent-border-color-alpha: .4;
/// @prop - Border color of the action sheet when translucent
$action-sheet-ios-translucent-border-color: rgba(
$background-color-rgb,
$action-sheet-ios-translucent-border-color-alpha
);
$action-sheet-ios-translucent-border-color: rgba($background-color-rgb, $action-sheet-ios-translucent-border-color-alpha);
/// @prop - Background color alpha of the activated action sheet when translucent
$action-sheet-ios-translucent-background-color-activated-alpha: 0.7;
$action-sheet-ios-translucent-background-color-activated-alpha: .7;
/// @prop - Background color of the activated action sheet when translucent
$action-sheet-ios-translucent-background-color-activated: rgba(
$background-color-rgb,
$action-sheet-ios-translucent-background-color-activated-alpha
);
$action-sheet-ios-translucent-background-color-activated: rgba($background-color-rgb, $action-sheet-ios-translucent-background-color-activated-alpha);
/// @prop - Filter of the translucent action-sheet group
$action-sheet-ios-group-translucent-filter: saturate(280%) blur(20px);
$action-sheet-ios-group-translucent-filter: saturate(280%) blur(20px);
/// @prop - Filter of the translucent action-sheet button
$action-sheet-ios-button-translucent-filter: saturate(120%);
$action-sheet-ios-button-translucent-filter: saturate(120%);

View File

@@ -13,14 +13,15 @@
--button-background-activated: transparent;
--button-background-activated-opacity: 0;
--button-background-hover: currentColor;
--button-background-hover-opacity: 0.04;
--button-background-hover-opacity: .04;
--button-background-focused: currentColor;
--button-background-focused-opacity: 0.12;
--button-background-focused-opacity: .12;
--button-color: #{$action-sheet-md-button-text-color};
--button-color-disabled: var(--button-color);
--color: #{$action-sheet-md-title-color};
}
// Material Design Action Sheet Wrapper
// -----------------------------------------
@@ -29,12 +30,7 @@
}
.action-sheet-title {
@include padding(
$action-sheet-md-title-padding-top,
$action-sheet-md-title-padding-end,
$action-sheet-md-title-padding-bottom,
$action-sheet-md-title-padding-start
);
@include padding($action-sheet-md-title-padding-top, $action-sheet-md-title-padding-end, $action-sheet-md-title-padding-bottom, $action-sheet-md-title-padding-start);
min-height: $action-sheet-md-title-height;
@@ -46,16 +42,12 @@
}
.action-sheet-sub-title {
@include padding(
$action-sheet-md-sub-title-padding-top,
$action-sheet-md-sub-title-padding-end,
$action-sheet-md-sub-title-padding-bottom,
$action-sheet-md-sub-title-padding-start
);
@include padding($action-sheet-md-sub-title-padding-top, $action-sheet-md-sub-title-padding-end, $action-sheet-md-sub-title-padding-bottom, $action-sheet-md-sub-title-padding-start);
font-size: $action-sheet-md-sub-title-font-size;
}
// Material Design Action Sheet Group
// -----------------------------------------
@@ -67,16 +59,12 @@
@include padding(null, null, $action-sheet-md-padding-bottom, null);
}
// Material Design Action Sheet Buttons
// -----------------------------------------
.action-sheet-button {
@include padding(
$action-sheet-md-button-padding-top,
$action-sheet-md-button-padding-end,
$action-sheet-md-button-padding-bottom,
$action-sheet-md-button-padding-start
);
@include padding($action-sheet-md-button-padding-top, $action-sheet-md-button-padding-end, $action-sheet-md-button-padding-bottom, $action-sheet-md-button-padding-start);
position: relative;
@@ -91,12 +79,7 @@
}
.action-sheet-icon {
@include margin(
$action-sheet-md-icon-margin-top,
$action-sheet-md-icon-margin-end,
$action-sheet-md-icon-margin-bottom,
$action-sheet-md-icon-margin-start
);
@include margin($action-sheet-md-icon-margin-top, $action-sheet-md-icon-margin-end, $action-sheet-md-icon-margin-bottom, $action-sheet-md-icon-margin-start);
color: var(--color);

View File

@@ -1,100 +1,103 @@
@import "../../themes/native/native.globals.md";
@import "../../themes/ionic.globals.md";
// Material Design Action Sheet
// --------------------------------------------------
/// @prop - Text align of the action sheet
$action-sheet-md-text-align: start;
$action-sheet-md-text-align: start;
/// @prop - Background color of the action sheet
$action-sheet-md-background-color: $overlay-md-background-color;
$action-sheet-md-background-color: $overlay-md-background-color;
/// @prop - Padding top of the action sheet
$action-sheet-md-padding-top: 0;
$action-sheet-md-padding-top: 0;
/// @prop - Padding bottom of the action sheet
$action-sheet-md-padding-bottom: var(--ion-safe-area-bottom);
$action-sheet-md-padding-bottom: var(--ion-safe-area-bottom);
// Action Sheet Title
// --------------------------------------------------
/// @prop - Height of the action sheet title
$action-sheet-md-title-height: 60px;
$action-sheet-md-title-height: 60px;
/// @prop - Color of the action sheet title
$action-sheet-md-title-color: rgba($text-color-rgb, 0.54);
$action-sheet-md-title-color: rgba($text-color-rgb, 0.54);
/// @prop - Font size of the action sheet title
$action-sheet-md-title-font-size: dynamic-font(16px);
$action-sheet-md-title-font-size: dynamic-font(16px);
/// @prop - Padding top of the action sheet title
$action-sheet-md-title-padding-top: 20px;
$action-sheet-md-title-padding-top: 20px;
/// @prop - Padding end of the action sheet title
$action-sheet-md-title-padding-end: 16px;
$action-sheet-md-title-padding-end: 16px;
/// @prop - Padding bottom of the action sheet title
$action-sheet-md-title-padding-bottom: 17px;
$action-sheet-md-title-padding-bottom: 17px;
/// @prop - Padding start of the action sheet title
$action-sheet-md-title-padding-start: $action-sheet-md-title-padding-end;
$action-sheet-md-title-padding-start: $action-sheet-md-title-padding-end;
// Action Sheet Subtitle
// --------------------------------------------------
/// @prop - Font size of the action sheet sub title
$action-sheet-md-sub-title-font-size: dynamic-font(14px);
$action-sheet-md-sub-title-font-size: dynamic-font(14px);
/// @prop - Padding top of the action sheet sub title
$action-sheet-md-sub-title-padding-top: 16px;
$action-sheet-md-sub-title-padding-top: 16px;
/// @prop - Padding end of the action sheet sub title
$action-sheet-md-sub-title-padding-end: 0;
$action-sheet-md-sub-title-padding-end: 0;
/// @prop - Padding bottom of the action sheet sub title
$action-sheet-md-sub-title-padding-bottom: 0;
$action-sheet-md-sub-title-padding-bottom: 0;
/// @prop - Padding start of the action sheet sub title
$action-sheet-md-sub-title-padding-start: $action-sheet-md-sub-title-padding-end;
$action-sheet-md-sub-title-padding-start: $action-sheet-md-sub-title-padding-end;
// Action Sheet Button
// --------------------------------------------------
/// @prop - Minimum height of the action sheet button
$action-sheet-md-button-height: 52px;
$action-sheet-md-button-height: 52px;
/// @prop - Text color of the action sheet button
$action-sheet-md-button-text-color: $text-color-step-150;
$action-sheet-md-button-text-color: $text-color-step-150;
/// @prop - Font size of the action sheet button
$action-sheet-md-button-font-size: dynamic-font(16px);
$action-sheet-md-button-font-size: dynamic-font(16px);
/// @prop - Padding top of the action sheet button
$action-sheet-md-button-padding-top: 12px;
$action-sheet-md-button-padding-top: 12px;
/// @prop - Padding end of the action sheet button
$action-sheet-md-button-padding-end: 16px;
$action-sheet-md-button-padding-end: 16px;
/// @prop - Padding bottom of the action sheet button
$action-sheet-md-button-padding-bottom: $action-sheet-md-button-padding-top;
$action-sheet-md-button-padding-bottom: $action-sheet-md-button-padding-top;
/// @prop - Padding start of the action sheet button
$action-sheet-md-button-padding-start: $action-sheet-md-button-padding-end;
$action-sheet-md-button-padding-start: $action-sheet-md-button-padding-end;
// Action Sheet Icon
// --------------------------------------------------
/// @prop - Font size of the icon in the action sheet button
$action-sheet-md-icon-font-size: dynamic-font(24px);
$action-sheet-md-icon-font-size: dynamic-font(24px);
/// @prop - Margin top of the icon in the action sheet button
$action-sheet-md-icon-margin-top: 0;
$action-sheet-md-icon-margin-top: 0;
/// @prop - Margin end of the icon in the action sheet button
$action-sheet-md-icon-margin-end: 32px;
$action-sheet-md-icon-margin-end: 32px;
/// @prop - Margin bottom of the icon in the action sheet button
$action-sheet-md-icon-margin-bottom: 0;
$action-sheet-md-icon-margin-bottom: 0;
/// @prop - Margin start of the icon in the action sheet button
$action-sheet-md-icon-margin-start: 0;
$action-sheet-md-icon-margin-start: 0;

View File

@@ -173,6 +173,7 @@
overflow: hidden;
}
// Action Sheet: States
// --------------------------------------------------
@@ -180,6 +181,7 @@
@include button-state();
}
// Action Sheet: Selected
// --------------------------------------------------
@@ -193,6 +195,7 @@
}
}
// Action Sheet: Activated
// --------------------------------------------------
@@ -206,6 +209,7 @@
}
}
// Action Sheet: Focused
// --------------------------------------------------

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,10 +1,10 @@
@import "../../themes/native/native.globals";
@import "../../themes/ionic.globals";
// Action Sheet
// --------------------------------------------------
/// @prop - Width of the action sheet
$action-sheet-width: 100%;
$action-sheet-width: 100%;
/// @prop - Maximum width of the action sheet
$action-sheet-max-width: 500px;
$action-sheet-max-width: 500px;

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

@@ -23,6 +23,7 @@
pointer-events: none;
}
// iOS Translucent Alert
// -----------------------------------------
@@ -37,12 +38,7 @@
// --------------------------------------------------
.alert-head {
@include padding(
$alert-ios-head-padding-top,
$alert-ios-head-padding-end,
$alert-ios-head-padding-bottom,
$alert-ios-head-padding-start
);
@include padding($alert-ios-head-padding-top, $alert-ios-head-padding-end, $alert-ios-head-padding-bottom, $alert-ios-head-padding-start);
text-align: $alert-ios-head-text-align;
}
@@ -62,17 +58,13 @@
font-size: $alert-ios-sub-title-font-size;
}
// iOS Alert Message
// --------------------------------------------------
.alert-message,
.alert-input-group {
@include padding(
$alert-ios-message-padding-top,
$alert-ios-message-padding-end,
$alert-ios-message-padding-bottom,
$alert-ios-message-padding-start
);
@include padding($alert-ios-message-padding-top, $alert-ios-message-padding-end, $alert-ios-message-padding-bottom, $alert-ios-message-padding-start);
color: $alert-ios-message-text-color;
@@ -86,26 +78,17 @@
}
.alert-message:empty {
@include padding(
$alert-ios-message-empty-padding-top,
$alert-ios-message-empty-padding-end,
$alert-ios-message-empty-padding-bottom,
$alert-ios-message-empty-padding-start
);
@include padding($alert-ios-message-empty-padding-top, $alert-ios-message-empty-padding-end, $alert-ios-message-empty-padding-bottom, $alert-ios-message-empty-padding-start);
}
// iOS Alert Input
// --------------------------------------------------
.alert-input {
@include border-radius($alert-ios-input-border-radius);
@include margin($alert-ios-input-margin-top, null, null, null);
@include padding(
$alert-ios-input-padding-top,
$alert-ios-input-padding-end,
$alert-ios-input-padding-bottom,
$alert-ios-input-padding-start
);
@include padding($alert-ios-input-padding-top, $alert-ios-input-padding-end, $alert-ios-input-padding-bottom, $alert-ios-input-padding-start);
border: $alert-ios-input-border;
@@ -137,6 +120,7 @@
}
}
// iOS Alert Radio/Checkbox Group
// --------------------------------------------------
@@ -155,16 +139,12 @@
min-height: $alert-ios-tappable-height;
}
// iOS Alert Radio Label
// --------------------------------------------------
.alert-radio-label {
@include padding(
$alert-ios-radio-label-padding-top,
$alert-ios-radio-label-padding-end,
$alert-ios-radio-label-padding-bottom,
$alert-ios-radio-label-padding-start
);
@include padding($alert-ios-radio-label-padding-top, $alert-ios-radio-label-padding-end, $alert-ios-radio-label-padding-bottom, $alert-ios-radio-label-padding-start);
flex: 1;
order: 0;
@@ -172,13 +152,15 @@
color: $alert-ios-radio-label-text-color;
}
// iOS Alert Radio Label: Checked
// --------------------------------------------------
[aria-checked="true"] .alert-radio-label {
[aria-checked=true] .alert-radio-label {
color: $alert-ios-radio-label-text-color-checked;
}
// iOS Alert Radio Checkmark: Unchecked
// -----------------------------------------
@@ -190,10 +172,11 @@
min-width: $alert-ios-radio-min-width;
}
// iOS Alert Radio Checked
// -----------------------------------------
[aria-checked="true"] .alert-radio-inner {
[aria-checked=true] .alert-radio-inner {
@include position($alert-ios-radio-icon-top, null, null, $alert-ios-radio-icon-start);
position: absolute;
@@ -210,16 +193,12 @@
border-color: $alert-ios-radio-icon-border-color;
}
// iOS Alert Checkbox Label
// --------------------------------------------------
.alert-checkbox-label {
@include padding(
$alert-ios-checkbox-label-padding-top,
$alert-ios-checkbox-label-padding-end,
$alert-ios-checkbox-label-padding-bottom,
$alert-ios-checkbox-label-padding-start
);
@include padding($alert-ios-checkbox-label-padding-top, $alert-ios-checkbox-label-padding-end, $alert-ios-checkbox-label-padding-bottom, $alert-ios-checkbox-label-padding-start);
flex: 1;
@@ -231,12 +210,7 @@
.alert-checkbox-icon {
@include border-radius($alert-ios-checkbox-border-radius);
@include margin(
$alert-ios-checkbox-margin-top,
$alert-ios-checkbox-margin-end,
$alert-ios-checkbox-margin-bottom,
$alert-ios-checkbox-margin-start
);
@include margin($alert-ios-checkbox-margin-top, $alert-ios-checkbox-margin-end, $alert-ios-checkbox-margin-bottom, $alert-ios-checkbox-margin-start);
position: relative;
@@ -252,19 +226,21 @@
contain: strict;
}
// iOS Alert Checkbox Outer Circle: Checked
// -----------------------------------------
[aria-checked="true"] .alert-checkbox-icon {
[aria-checked=true] .alert-checkbox-icon {
border-color: $alert-ios-checkbox-border-color-on;
background-color: $alert-ios-checkbox-background-color-on;
}
// iOS Alert Checkbox Inner Checkmark: Checked
// -----------------------------------------
[aria-checked="true"] .alert-checkbox-inner {
[aria-checked=true] .alert-checkbox-inner {
@include position($alert-ios-checkbox-icon-top, null, null, $alert-ios-checkbox-icon-start);
position: absolute;
@@ -281,6 +257,7 @@
border-color: $alert-ios-checkbox-icon-border-color;
}
// iOS Alert Button
// --------------------------------------------------

View File

@@ -1,141 +1,141 @@
@use "sass:math";
@import "../../themes/native/native.globals.ios";
@import "../../themes/ionic.globals.ios";
@import "../item/item.ios.vars";
// iOS Alert
// --------------------------------------------------
/// @prop - Font size of the alert
$alert-ios-font-size: dynamic-font-min(1, 14px);
$alert-ios-font-size: dynamic-font-min(1, 14px);
/// @prop - Max width of the alert
$alert-ios-max-width: dynamic-font-clamp(1, 270px, 1.2);
$alert-ios-max-width: dynamic-font-clamp(1, 270px, 1.2);
/// @prop - Border radius of the alert
$alert-ios-border-radius: 13px;
$alert-ios-border-radius: 13px;
/// @prop - Background color of the alert
$alert-ios-background-color: $overlay-ios-background-color;
$alert-ios-background-color: $overlay-ios-background-color;
/// @prop - Background color alpha of the alert when translucent
$alert-ios-translucent-background-color-alpha: 0.9;
$alert-ios-translucent-background-color-alpha: .9;
/// @prop - Background color of the alert when translucent
$alert-ios-translucent-background-color: rgba($background-color-rgb, $alert-ios-translucent-background-color-alpha);
$alert-ios-translucent-background-color: rgba($background-color-rgb, $alert-ios-translucent-background-color-alpha);
/// @prop - Box shadow of the alert
$alert-ios-box-shadow: none;
$alert-ios-box-shadow: none;
/// @prop - Padding top of the alert head
$alert-ios-head-padding-top: 12px;
$alert-ios-head-padding-top: 12px;
/// @prop - Padding end of the alert head
$alert-ios-head-padding-end: 16px;
$alert-ios-head-padding-end: 16px;
/// @prop - Padding bottom of the alert head
$alert-ios-head-padding-bottom: 7px;
$alert-ios-head-padding-bottom: 7px;
/// @prop - Padding start of the alert head
$alert-ios-head-padding-start: $alert-ios-head-padding-end;
$alert-ios-head-padding-start: $alert-ios-head-padding-end;
/// @prop - Text align of the alert head
$alert-ios-head-text-align: center;
$alert-ios-head-text-align: center;
/// @prop - Color of the alert title
$alert-ios-title-color: $text-color;
$alert-ios-title-color: $text-color;
/// @prop - Margin top of the alert title
$alert-ios-title-margin-top: 8px;
$alert-ios-title-margin-top: 8px;
/// @prop - Font size of the alert title
$alert-ios-title-font-size: dynamic-font-min(1, 17px);
$alert-ios-title-font-size: dynamic-font-min(1, 17px);
/// @prop - Font weight of the alert title
$alert-ios-title-font-weight: 600;
$alert-ios-title-font-weight: 600;
/// @prop - Font size of the alert sub title
$alert-ios-sub-title-font-size: dynamic-font-min(1, 14px);
$alert-ios-sub-title-font-size: dynamic-font-min(1, 14px);
/// @prop - Text color of the alert sub title
$alert-ios-sub-title-text-color: $text-color-step-400;
$alert-ios-sub-title-text-color: $text-color-step-400;
/// @prop - Padding top of the alert message
$alert-ios-message-padding-top: 0;
$alert-ios-message-padding-top: 0;
/// @prop - Padding end of the alert message
$alert-ios-message-padding-end: 16px;
$alert-ios-message-padding-end: 16px;
/// @prop - Padding bottom of the alert message
$alert-ios-message-padding-bottom: 21px;
$alert-ios-message-padding-bottom: 21px;
/// @prop - Padding start of the alert message
$alert-ios-message-padding-start: $alert-ios-message-padding-end;
$alert-ios-message-padding-start: $alert-ios-message-padding-end;
/// @prop - Font size of the alert message
$alert-ios-message-font-size: dynamic-font-min(1, 13px);
$alert-ios-message-font-size: dynamic-font-min(1, 13px);
/// @prop - Text align of the alert message
$alert-ios-message-text-align: center;
$alert-ios-message-text-align: center;
/// @prop - Text color of the alert message
$alert-ios-message-text-color: $text-color;
$alert-ios-message-text-color: $text-color;
/// @prop - Padding top of the alert empty message
$alert-ios-message-empty-padding-top: 0;
$alert-ios-message-empty-padding-top: 0;
/// @prop - Padding end of the alert empty message
$alert-ios-message-empty-padding-end: 0;
$alert-ios-message-empty-padding-end: 0;
/// @prop - Padding bottom of the alert empty message
$alert-ios-message-empty-padding-bottom: 12px;
$alert-ios-message-empty-padding-bottom: 12px;
/// @prop - Padding start of the alert empty message
$alert-ios-message-empty-padding-start: 0;
$alert-ios-message-empty-padding-start: 0;
/// @prop - Maximum height of the alert content
$alert-ios-content-max-height: 240px;
$alert-ios-content-max-height: 240px;
/// @prop - Margin top of the alert input
$alert-ios-input-margin-top: 10px;
$alert-ios-input-margin-top: 10px;
/// @prop - Padding top on the alert input
$alert-ios-input-padding-top: 7px;
$alert-ios-input-padding-top: 7px;
/// @prop - Padding end on the alert input
$alert-ios-input-padding-end: $alert-ios-input-padding-top;
$alert-ios-input-padding-end: $alert-ios-input-padding-top;
/// @prop - Padding bottom on the alert input
$alert-ios-input-padding-bottom: $alert-ios-input-padding-top;
$alert-ios-input-padding-bottom: $alert-ios-input-padding-top;
/// @prop - Padding start on the alert input
$alert-ios-input-padding-start: $alert-ios-input-padding-end;
$alert-ios-input-padding-start: $alert-ios-input-padding-end;
/// @prop - Placeholder Color for input
$alert-ios-input-placeholder-color: $placeholder-text-color;
$alert-ios-input-placeholder-color: $placeholder-text-color;
/// @prop - Border color of the alert input
$alert-ios-input-border-color: $background-color-step-250;
$alert-ios-input-border-color: $background-color-step-250;
/// @prop - Border of the alert input
$alert-ios-input-border: $hairlines-width solid $alert-ios-input-border-color;
$alert-ios-input-border: $hairlines-width solid $alert-ios-input-border-color;
/// @prop - Border radius of the alert input
$alert-ios-input-border-radius: 7px;
$alert-ios-input-border-radius: 7px;
/// @prop - Background color of the alert input
$alert-ios-input-background-color: $background-color;
$alert-ios-input-background-color: $background-color;
/// @prop - Flex wrap of the alert button group
$alert-ios-button-group-flex-wrap: wrap;
$alert-ios-button-group-flex-wrap: wrap;
/// @prop - Flex of the alert button
$alert-ios-button-flex: 1 1 auto;
$alert-ios-button-flex: 1 1 auto;
/// @prop - Margin of the alert button
$alert-ios-button-margin: 0;
$alert-ios-button-margin: 0;
/// @prop - Min width of the alert button
$alert-ios-button-min-width: 50%;
$alert-ios-button-min-width: 50%;
/// @prop - Height of the alert button
/**
@@ -147,172 +147,172 @@ $alert-ios-button-min-width: 50%;
* a hairline (<1px) width, this will cause subpixel rendering
* differences across browsers.
*/
$alert-ios-button-height: dynamic-font-min(1, 44px);
$alert-ios-button-height: dynamic-font-min(1, 44px);
/// @prop - Padding of the alert button
$alert-ios-button-padding: 8px;
/// @prop - Font size of the alert button
$alert-ios-button-font-size: dynamic-font-min(1, 17px);
$alert-ios-button-font-size: dynamic-font-min(1, 17px);
/// @prop - Color of the text in the alert button
$alert-ios-button-text-color: ion-color(primary, base);
$alert-ios-button-text-color: ion-color(primary, base);
/// @prop - Destructive text color of the alert button
$alert-ios-button-destructive-text-color: ion-color(danger, base);
$alert-ios-button-destructive-text-color: ion-color(danger, base);
/// @prop - Background color of the alert button
$alert-ios-button-background-color: transparent;
$alert-ios-button-background-color: transparent;
/// @prop - Background color alpha of the alert activated button
$alert-ios-button-background-color-alpha-activated: 0.1;
$alert-ios-button-background-color-alpha-activated: .1;
/// @prop - Background color of the alert activated button
$alert-ios-button-background-color-activated: rgba($text-color-rgb, $alert-ios-button-background-color-alpha-activated);
$alert-ios-button-background-color-activated: rgba($text-color-rgb, $alert-ios-button-background-color-alpha-activated);
/// @prop - Border width of the alert button
$alert-ios-button-border-width: $hairlines-width;
$alert-ios-button-border-width: $hairlines-width;
/// @prop - Border style of the alert button
$alert-ios-button-border-style: solid;
$alert-ios-button-border-style: solid;
/// @prop - Border color alpha of the alert button
$alert-ios-button-border-color-alpha: 0.2;
$alert-ios-button-border-color-alpha: .2;
/// @prop - Border color of the alert button
$alert-ios-button-border-color: rgba($text-color-rgb, $alert-ios-button-border-color-alpha);
$alert-ios-button-border-color: rgba($text-color-rgb, $alert-ios-button-border-color-alpha);
/// @prop - Border radius of the alert button
$alert-ios-button-border-radius: 0;
$alert-ios-button-border-radius: 0;
/// @prop - Font weight of the main text on the alert button
$alert-ios-button-main-font-weight: bold;
$alert-ios-button-main-font-weight: bold;
/// @prop - Border top of the alert list
$alert-ios-list-border-top: $alert-ios-button-border-width $alert-ios-button-border-style $alert-ios-button-border-color;
$alert-ios-list-border-top: $alert-ios-button-border-width $alert-ios-button-border-style $alert-ios-button-border-color;
/// @prop - Padding top on the label for the radio alert
$alert-ios-radio-label-padding-top: 13px;
$alert-ios-radio-label-padding-top: 13px;
/// @prop - Padding end on the label for the radio alert
$alert-ios-radio-label-padding-end: $alert-ios-radio-label-padding-top;
$alert-ios-radio-label-padding-end: $alert-ios-radio-label-padding-top;
/// @prop - Padding bottom on the label for the radio alert
$alert-ios-radio-label-padding-bottom: $alert-ios-radio-label-padding-top;
$alert-ios-radio-label-padding-bottom: $alert-ios-radio-label-padding-top;
/// @prop - Padding start on the label for the radio alert
$alert-ios-radio-label-padding-start: $alert-ios-radio-label-padding-end;
$alert-ios-radio-label-padding-start: $alert-ios-radio-label-padding-end;
/// @prop - Text color of the label for the radio alert
$alert-ios-radio-label-text-color: $text-color;
$alert-ios-radio-label-text-color: $text-color;
/// @prop - Text color of the label for the checked radio alert
$alert-ios-radio-label-text-color-checked: $alert-ios-button-text-color;
$alert-ios-radio-label-text-color-checked: $alert-ios-button-text-color;
/// @prop - Min width of the radio alert
$alert-ios-radio-min-width: 30px;
$alert-ios-radio-min-width: 30px;
/// @prop - Top of the icon in the radio alert
$alert-ios-radio-icon-top: -7px;
$alert-ios-radio-icon-top: -7px;
/// @prop - Start of the icon in the radio alert
$alert-ios-radio-icon-start: 7px;
$alert-ios-radio-icon-start: 7px;
/// @prop - Width of the icon in the radio alert
$alert-ios-radio-icon-width: 6px;
$alert-ios-radio-icon-width: 6px;
/// @prop - Height of the icon in the radio alert
$alert-ios-radio-icon-height: 12px;
$alert-ios-radio-icon-height: 12px;
/// @prop - Border width of the icon in the radio alert
$alert-ios-radio-icon-border-width: 2px;
$alert-ios-radio-icon-border-width: 2px;
/// @prop - Border style of the icon in the radio alert
$alert-ios-radio-icon-border-style: solid;
$alert-ios-radio-icon-border-style: solid;
/// @prop - Border color of the icon in the radio alert
$alert-ios-radio-icon-border-color: $alert-ios-button-text-color;
$alert-ios-radio-icon-border-color: $alert-ios-button-text-color;
/// @prop - Transform of the icon in the radio alert
$alert-ios-radio-icon-transform: rotate(45deg);
$alert-ios-radio-icon-transform: rotate(45deg);
/// @prop - Padding top of the label for the checkbox in the alert
$alert-ios-checkbox-label-padding-top: 13px;
$alert-ios-checkbox-label-padding-top: 13px;
/// @prop - Padding end of the label for the checkbox in the alert
$alert-ios-checkbox-label-padding-end: $alert-ios-checkbox-label-padding-top;
$alert-ios-checkbox-label-padding-end: $alert-ios-checkbox-label-padding-top;
/// @prop - Padding bottom of the label for the checkbox in the alert
$alert-ios-checkbox-label-padding-bottom: $alert-ios-checkbox-label-padding-top;
$alert-ios-checkbox-label-padding-bottom: $alert-ios-checkbox-label-padding-top;
/// @prop - Padding start of the label for the checkbox in the alert
$alert-ios-checkbox-label-padding-start: $alert-ios-checkbox-label-padding-end;
$alert-ios-checkbox-label-padding-start: $alert-ios-checkbox-label-padding-end;
/// @prop - Text color of the label for the checkbox in the alert
$alert-ios-checkbox-label-text-color: $text-color;
$alert-ios-checkbox-label-text-color: $text-color;
/// @prop - Margin top of the checkbox in the alert
$alert-ios-checkbox-margin-top: 10px;
$alert-ios-checkbox-margin-top: 10px;
/// @prop - Margin end of the checkbox in the alert
$alert-ios-checkbox-margin-end: 6px;
$alert-ios-checkbox-margin-end: 6px;
/// @prop - Margin bottom of the checkbox in the alert
$alert-ios-checkbox-margin-bottom: 10px;
$alert-ios-checkbox-margin-bottom: 10px;
/// @prop - Margin start of the checkbox in the alert
$alert-ios-checkbox-margin-start: 16px;
$alert-ios-checkbox-margin-start: 16px;
/// @prop - Size of the checkbox in the alert
$alert-ios-checkbox-size: dynamic-font-max(22px, 2.538);
$alert-ios-checkbox-size: dynamic-font-max(22px, 2.538);
/// @prop - Border width of the checkbox in the alert
$alert-ios-checkbox-border-width: dynamic-font(2px);
$alert-ios-checkbox-border-width: dynamic-font(2px);
/// @prop - Border style of the checkbox in the alert
$alert-ios-checkbox-border-style: solid;
$alert-ios-checkbox-border-style: solid;
/// @prop - Border radius of the checkbox in the alert
$alert-ios-checkbox-border-radius: 50%;
$alert-ios-checkbox-border-radius: 50%;
/// @prop - Border color of the checkbox in the alert when off
$alert-ios-checkbox-border-color-off: $item-ios-border-color;
$alert-ios-checkbox-border-color-off: $item-ios-border-color;
/// @prop - Border color of the checkbox in the alert when on
$alert-ios-checkbox-border-color-on: ion-color(primary, base);
$alert-ios-checkbox-border-color-on: ion-color(primary, base);
/// @prop - Background color of the checkbox in the alert when off
$alert-ios-checkbox-background-color-off: $item-ios-background;
$alert-ios-checkbox-background-color-off: $item-ios-background;
/// @prop - Background color of the checkbox in the alert when on
$alert-ios-checkbox-background-color-on: ion-color(primary, base);
$alert-ios-checkbox-background-color-on: ion-color(primary, base);
/// @prop - Top of the icon in the checkbox alert
$alert-ios-checkbox-icon-top: calc($alert-ios-checkbox-size / 8);
$alert-ios-checkbox-icon-top: calc($alert-ios-checkbox-size / 8);
/// @prop - Start of the icon in the checkbox alert
$alert-ios-checkbox-icon-start: calc($alert-ios-checkbox-size / 3);
$alert-ios-checkbox-icon-start: calc($alert-ios-checkbox-size / 3);
/// @prop - Width of the icon in the checkbox alert
$alert-ios-checkbox-icon-width: calc($alert-ios-checkbox-size / 6 + 1px);
$alert-ios-checkbox-icon-width: calc($alert-ios-checkbox-size / 6 + 1px);
/// @prop - Height of the icon in the checkbox alert
$alert-ios-checkbox-icon-height: calc($alert-ios-checkbox-size * 0.5);
$alert-ios-checkbox-icon-height: calc($alert-ios-checkbox-size * 0.5);
/// @prop - Border width of the icon in the checkbox alert
$alert-ios-checkbox-icon-border-width: $alert-ios-checkbox-border-width;
$alert-ios-checkbox-icon-border-width: $alert-ios-checkbox-border-width;
/// @prop - Border style of the icon in the checkbox alert
$alert-ios-checkbox-icon-border-style: $alert-ios-checkbox-border-style;
$alert-ios-checkbox-icon-border-style: $alert-ios-checkbox-border-style;
/// @prop - Border color of the icon in the checkbox alert
$alert-ios-checkbox-icon-border-color: $background-color;
$alert-ios-checkbox-icon-border-color: $background-color;
/// @prop - Transform of the icon in the checkbox alert
$alert-ios-checkbox-icon-transform: rotate(45deg);
$alert-ios-checkbox-icon-transform: rotate(45deg);
/// @prop - Filter of the translucent alert
$alert-ios-translucent-filter: saturate(180%) blur(20px);
$alert-ios-translucent-filter: saturate(180%) blur(20px);
/// @prop - Height of the tappable inputs in the checkbox alert
$alert-ios-tappable-height: $item-ios-min-height;
$alert-ios-tappable-height: $item-ios-min-height;

View File

@@ -22,12 +22,7 @@
// --------------------------------------------------
.alert-head {
@include padding(
$alert-md-head-padding-top,
$alert-md-head-padding-end,
$alert-md-head-padding-bottom,
$alert-md-head-padding-start
);
@include padding($alert-md-head-padding-top, $alert-md-head-padding-end, $alert-md-head-padding-bottom, $alert-md-head-padding-start);
text-align: $alert-md-head-text-align;
}
@@ -45,17 +40,13 @@
font-size: $alert-md-sub-title-font-size;
}
// Material Design Alert Message
// --------------------------------------------------
.alert-message,
.alert-input-group {
@include padding(
$alert-md-message-padding-top,
$alert-md-message-padding-end,
$alert-md-message-padding-bottom,
$alert-md-message-padding-start
);
@include padding($alert-md-message-padding-top, $alert-md-message-padding-end, $alert-md-message-padding-bottom, $alert-md-message-padding-start);
color: $alert-md-message-text-color;
}
@@ -76,28 +67,19 @@
}
.alert-message:empty {
@include padding(
$alert-md-message-empty-padding-top,
$alert-md-message-empty-padding-end,
$alert-md-message-empty-padding-bottom,
$alert-md-message-empty-padding-start
);
@include padding($alert-md-message-empty-padding-top, $alert-md-message-empty-padding-end, $alert-md-message-empty-padding-bottom, $alert-md-message-empty-padding-start);
}
.alert-head + .alert-message {
padding-top: 0;
}
// Material Design Alert Input
// --------------------------------------------------
.alert-input {
@include margin(
$alert-md-input-margin-top,
$alert-md-input-margin-end,
$alert-md-input-margin-bottom,
$alert-md-input-margin-start
);
@include margin($alert-md-input-margin-top, $alert-md-input-margin-end, $alert-md-input-margin-bottom, $alert-md-input-margin-start);
border-bottom: $alert-md-input-border-width $alert-md-input-border-style $alert-md-input-border-color;
@@ -118,10 +100,10 @@
.alert-input:focus {
@include margin(null, null, $alert-md-input-margin-bottom - 1, null);
border-bottom: $alert-md-input-border-width-focused $alert-md-input-border-style-focused
$alert-md-input-border-color-focused;
border-bottom: $alert-md-input-border-width-focused $alert-md-input-border-style-focused $alert-md-input-border-color-focused;
}
// Material Design Alert Radio/Checkbox Group
// --------------------------------------------------
@@ -153,16 +135,12 @@
min-height: $alert-md-tappable-height;
}
// Material Design Alert Radio
// --------------------------------------------------
.alert-radio-label {
@include padding(
$alert-md-radio-label-padding-top,
$alert-md-radio-label-padding-end,
$alert-md-radio-label-padding-bottom,
$alert-md-radio-label-padding-start
);
@include padding($alert-md-radio-label-padding-top, $alert-md-radio-label-padding-end, $alert-md-radio-label-padding-bottom, $alert-md-radio-label-padding-start);
flex: 1;
@@ -208,31 +186,28 @@
background-color: $alert-md-radio-border-color-on;
}
// Material Design Alert Radio Checked
// ---------------------------------------------------
[aria-checked="true"] .alert-radio-label {
[aria-checked=true] .alert-radio-label {
color: $alert-md-radio-label-text-color-checked;
}
[aria-checked="true"] .alert-radio-icon {
[aria-checked=true] .alert-radio-icon {
border-color: $alert-md-radio-border-color-on;
}
[aria-checked="true"] .alert-radio-inner {
[aria-checked=true] .alert-radio-inner {
transform: $alert-md-radio-icon-transform-on;
}
// Material Design Alert Checkbox Label
// --------------------------------------------------
.alert-checkbox-label {
@include padding(
$alert-md-checkbox-label-padding-top,
$alert-md-checkbox-label-padding-end,
$alert-md-checkbox-label-padding-bottom,
$alert-md-checkbox-label-padding-start
);
@include padding($alert-md-checkbox-label-padding-top, $alert-md-checkbox-label-padding-end, $alert-md-checkbox-label-padding-bottom, $alert-md-checkbox-label-padding-start);
flex: 1;
@@ -245,6 +220,7 @@
font-size: $alert-md-checkbox-label-font-size;
}
// Material Design Alert Checkbox Outline: Unchecked
// --------------------------------------------------
@@ -267,13 +243,13 @@
// Material Design Alert Checkbox Checkmark: Checked
// --------------------------------------------------
[aria-checked="true"] .alert-checkbox-icon {
[aria-checked=true] .alert-checkbox-icon {
border-color: $alert-md-checkbox-border-color-on;
background-color: $alert-md-checkbox-border-color-on;
}
[aria-checked="true"] .alert-checkbox-inner {
[aria-checked=true] .alert-checkbox-inner {
@include position($alert-md-checkbox-icon-top, null, null, $alert-md-checkbox-icon-start);
position: absolute;
@@ -290,6 +266,7 @@
border-color: $alert-md-checkbox-icon-border-color;
}
// Material Design Alert Button
// --------------------------------------------------
@@ -304,18 +281,8 @@
.alert-button {
@include border-radius($alert-md-button-border-radius);
@include margin(
$alert-md-button-margin-top,
$alert-md-button-margin-end,
$alert-md-button-margin-bottom,
$alert-md-button-margin-start
);
@include padding(
$alert-md-button-padding-top,
$alert-md-button-padding-end,
$alert-md-button-padding-bottom,
$alert-md-button-padding-start
);
@include margin($alert-md-button-margin-top, $alert-md-button-margin-end, $alert-md-button-margin-bottom, $alert-md-button-margin-start);
@include padding($alert-md-button-padding-top, $alert-md-button-padding-end, $alert-md-button-padding-bottom, $alert-md-button-padding-start);
// necessary for ripple to work properly
position: relative;

View File

@@ -1,14 +1,14 @@
@import "../../themes/native/native.globals.md";
@import "../../themes/ionic.globals.md";
@import "../item/item.md.vars";
// Material Design Alert
// --------------------------------------------------
/// @prop - Font size of the alert
$alert-md-font-size: dynamic-font(14px);
$alert-md-font-size: dynamic-font(14px);
/// @prop - Max width of the alert
$alert-md-max-width: 280px;
$alert-md-max-width: 280px;
/// @prop - Max width of the alert on a tablet
/**
@@ -19,314 +19,313 @@ $alert-md-max-width: 280px;
* 3. The height can increase up to 560px.
* Source: https://m2.material.io/components/dialogs#behavior
*/
$alert-md-max-width-tablet: min(calc(100vw - 96px), 560px);
$alert-md-max-width-tablet: min(calc(100vw - 96px), 560px);
/// @prop - Max width of the alert on a tablet
$alert-md-max-height-tablet: min(calc(100vh - 96px), 560px);
$alert-md-max-height-tablet: min(calc(100vh - 96px), 560px);
/// @prop - Border radius of the alert
$alert-md-border-radius: 4px;
$alert-md-border-radius: 4px;
/// @prop - Background color of the alert
$alert-md-background-color: $overlay-md-background-color;
$alert-md-background-color: $overlay-md-background-color;
/// @prop - Box shadow color of the alert
$alert-md-box-shadow: 0 11px 15px -7px rgba(0, 0, 0, 0.2), 0 24px 38px 3px rgba(0, 0, 0, 0.14),
0 9px 46px 8px rgba(0, 0, 0, 0.12);
$alert-md-box-shadow: 0 11px 15px -7px rgba(0, 0, 0, .2), 0 24px 38px 3px rgba(0, 0, 0, .14), 0 9px 46px 8px rgba(0, 0, 0, .12);
/// @prop - Padding top of the alert head
$alert-md-head-padding-top: 20px;
$alert-md-head-padding-top: 20px;
/// @prop - Padding end of the alert head
$alert-md-head-padding-end: 23px;
$alert-md-head-padding-end: 23px;
/// @prop - Padding bottom of the alert head
$alert-md-head-padding-bottom: 15px;
$alert-md-head-padding-bottom: 15px;
/// @prop - Padding start of the alert head
$alert-md-head-padding-start: $alert-md-head-padding-end;
$alert-md-head-padding-start: $alert-md-head-padding-end;
/// @prop - Text align of the alert head
$alert-md-head-text-align: start;
$alert-md-head-text-align: start;
/// @prop - Color of the alert title
$alert-md-title-color: $text-color;
$alert-md-title-color: $text-color;
/// @prop - Font size of the alert title
$alert-md-title-font-size: dynamic-font(20px);
$alert-md-title-font-size: dynamic-font(20px);
/// @prop - Font weight of the alert title
$alert-md-title-font-weight: 500;
$alert-md-title-font-weight: 500;
/// @prop - Font size of the alert sub title
$alert-md-sub-title-font-size: dynamic-font(16px);
$alert-md-sub-title-font-size: dynamic-font(16px);
/// @prop - Text color of the alert sub title
$alert-md-sub-title-text-color: $text-color;
$alert-md-sub-title-text-color: $text-color;
/// @prop - Padding top of the alert message
$alert-md-message-padding-top: 20px;
$alert-md-message-padding-top: 20px;
/// @prop - Padding end of the alert message
$alert-md-message-padding-end: 24px;
$alert-md-message-padding-end: 24px;
/// @prop - Padding bottom of the alert message
$alert-md-message-padding-bottom: $alert-md-message-padding-top;
$alert-md-message-padding-bottom: $alert-md-message-padding-top;
/// @prop - Padding start of the alert message
$alert-md-message-padding-start: $alert-md-message-padding-end;
$alert-md-message-padding-start: $alert-md-message-padding-end;
/// @prop - Font size of the alert message
$alert-md-message-font-size: dynamic-font(16px);
$alert-md-message-font-size: dynamic-font(16px);
/// @prop - Text color of the alert message
$alert-md-message-text-color: $text-color-step-450;
$alert-md-message-text-color: $text-color-step-450;
/// @prop - Padding top of the alert empty message
$alert-md-message-empty-padding-top: 0;
$alert-md-message-empty-padding-top: 0;
/// @prop - Padding end of the alert empty message
$alert-md-message-empty-padding-end: $alert-md-message-empty-padding-top;
$alert-md-message-empty-padding-end: $alert-md-message-empty-padding-top;
/// @prop - Padding bottom of the alert empty message
$alert-md-message-empty-padding-bottom: $alert-md-message-empty-padding-top;
$alert-md-message-empty-padding-bottom: $alert-md-message-empty-padding-top;
/// @prop - Padding start of the alert empty message
$alert-md-message-empty-padding-start: $alert-md-message-empty-padding-end;
$alert-md-message-empty-padding-start: $alert-md-message-empty-padding-end;
/// @prop - Maximum height of the alert content
$alert-md-content-max-height: 266px;
$alert-md-content-max-height: 266px;
/// @prop - Border width of the alert input
$alert-md-input-border-width: 1px;
$alert-md-input-border-width: 1px;
/// @prop - Border style of the alert input
$alert-md-input-border-style: solid;
$alert-md-input-border-style: solid;
/// @prop - Border color of the alert input
$alert-md-input-border-color: $background-color-step-150;
$alert-md-input-border-color: $background-color-step-150;
/// @prop - Text color of the alert input
$alert-md-input-text-color: $text-color;
$alert-md-input-text-color: $text-color;
/// @prop - Border width of the alert input when focused
$alert-md-input-border-width-focused: 2px;
$alert-md-input-border-width-focused: 2px;
/// @prop - Border style of the alert input when focused
$alert-md-input-border-style-focused: $alert-md-input-border-style;
$alert-md-input-border-style-focused: $alert-md-input-border-style;
/// @prop - Border color of the alert input when focused
$alert-md-input-border-color-focused: ion-color(primary, base);
$alert-md-input-border-color-focused: ion-color(primary, base);
/// @prop - Margin top of the alert input
$alert-md-input-margin-top: 5px;
$alert-md-input-margin-top: 5px;
/// @prop - Margin end of the alert input
$alert-md-input-margin-end: 0;
$alert-md-input-margin-end: 0;
/// @prop - Margin bottom of the alert input
$alert-md-input-margin-bottom: 5px;
$alert-md-input-margin-bottom: 5px;
/// @prop - Margin start of the alert input
$alert-md-input-margin-start: 0;
$alert-md-input-margin-start: 0;
/// @prop - Placeholder Color for input
$alert-md-input-placeholder-color: $placeholder-text-color;
$alert-md-input-placeholder-color: $placeholder-text-color;
/// @prop - Flex wrap of the alert button group
$alert-md-button-group-flex-wrap: wrap-reverse;
$alert-md-button-group-flex-wrap: wrap-reverse;
/// @prop - Justify content of the alert button group
$alert-md-button-group-justify-content: flex-end;
$alert-md-button-group-justify-content: flex-end;
/// @prop - Padding top of the alert button
$alert-md-button-padding-top: 10px;
$alert-md-button-padding-top: 10px;
/// @prop - Padding end of the alert button
$alert-md-button-padding-end: $alert-md-button-padding-top;
$alert-md-button-padding-end: $alert-md-button-padding-top;
/// @prop - Padding bottom of the alert button
$alert-md-button-padding-bottom: $alert-md-button-padding-top;
$alert-md-button-padding-bottom: $alert-md-button-padding-top;
/// @prop - Padding start of the alert button
$alert-md-button-padding-start: $alert-md-button-padding-end;
$alert-md-button-padding-start: $alert-md-button-padding-end;
/// @prop - Margin top of the alert button
$alert-md-button-margin-top: 0;
$alert-md-button-margin-top: 0;
/// @prop - Margin end of the alert button
$alert-md-button-margin-end: 8px;
$alert-md-button-margin-end: 8px;
/// @prop - Margin bottom of the alert button
$alert-md-button-margin-bottom: 0;
$alert-md-button-margin-bottom: 0;
/// @prop - Margin start of the alert button
$alert-md-button-margin-start: 0;
$alert-md-button-margin-start: 0;
/// @prop - Font weight of the alert button
$alert-md-button-font-weight: 500;
$alert-md-button-font-weight: 500;
/// @prop - Text color of the alert button
$alert-md-button-text-color: ion-color(primary, base);
$alert-md-button-text-color: ion-color(primary, base);
/// @prop - Background color of the alert button
$alert-md-button-background-color: transparent;
$alert-md-button-background-color: transparent;
/// @prop - Border radius of the alert button
$alert-md-button-border-radius: 2px;
$alert-md-button-border-radius: 2px;
/// @prop - Text transform of the alert button
$alert-md-button-text-transform: uppercase;
$alert-md-button-text-transform: uppercase;
/// @prop - Text align of the alert button
$alert-md-button-text-align: end;
$alert-md-button-text-align: end;
/// @prop - Border top of the alert list
$alert-md-list-border-top: 1px solid $alert-md-input-border-color;
$alert-md-list-border-top: 1px solid $alert-md-input-border-color;
/// @prop - Border bottom of the alert list
$alert-md-list-border-bottom: $alert-md-list-border-top;
$alert-md-list-border-bottom: $alert-md-list-border-top;
/// @prop - Top of the alert radio
$alert-md-radio-top: 0;
$alert-md-radio-top: 0;
/// @prop - Left of the alert radio
$alert-md-radio-left: 26px;
$alert-md-radio-left: 26px;
/// @prop - Width of the alert radio
$alert-md-radio-width: 20px;
$alert-md-radio-width: 20px;
/// @prop - Height of the alert radio
$alert-md-radio-height: $alert-md-radio-width;
$alert-md-radio-height: $alert-md-radio-width;
/// @prop - Border width of the alert radio
$alert-md-radio-border-width: 2px;
$alert-md-radio-border-width: 2px;
/// @prop - Border style of the alert radio
$alert-md-radio-border-style: solid;
$alert-md-radio-border-style: solid;
/// @prop - Border radius of the alert radio
$alert-md-radio-border-radius: 50%;
$alert-md-radio-border-radius: 50%;
/// @prop - Border color of the alert radio when off
$alert-md-radio-border-color-off: $background-color-step-550;
$alert-md-radio-border-color-off: $background-color-step-550;
/// @prop - Border color of the alert radio when on
$alert-md-radio-border-color-on: $alert-md-button-text-color;
$alert-md-radio-border-color-on: $alert-md-button-text-color;
/// @prop - Width of the icon in the alert radio
$alert-md-radio-icon-width: $alert-md-radio-width * 0.5;
$alert-md-radio-icon-width: $alert-md-radio-width * 0.5;
/// @prop - Height of the icon in the alert radio
$alert-md-radio-icon-height: $alert-md-radio-icon-width;
$alert-md-radio-icon-height: $alert-md-radio-icon-width;
/// @prop - Top of the icon in the alert radio
$alert-md-radio-icon-top: ($alert-md-radio-width - $alert-md-radio-icon-width - $alert-md-radio-border-width * 2) * 0.5;
$alert-md-radio-icon-top: ($alert-md-radio-width - $alert-md-radio-icon-width - $alert-md-radio-border-width * 2) * 0.5;
/// @prop - Start of the icon in the radio alert
$alert-md-radio-icon-start: $alert-md-radio-icon-top;
$alert-md-radio-icon-start: $alert-md-radio-icon-top;
/// @prop - Border radius of the icon in the alert radio
$alert-md-radio-icon-border-radius: $alert-md-radio-border-radius;
$alert-md-radio-icon-border-radius: $alert-md-radio-border-radius;
/// @prop - Transform of the icon in the alert radio when off
$alert-md-radio-icon-transform-off: scale3d(0, 0, 0);
$alert-md-radio-icon-transform-off: scale3d(0, 0, 0);
/// @prop - Transform of the icon in the alert radio when on
$alert-md-radio-icon-transform-on: scale3d(1, 1, 1);
$alert-md-radio-icon-transform-on: scale3d(1, 1, 1);
/// @prop - Transition of the icon in the alert radio
$alert-md-radio-icon-transition: transform 280ms cubic-bezier(0.4, 0, 0.2, 1);
$alert-md-radio-icon-transition: transform 280ms cubic-bezier(.4, 0, .2, 1);
/// @prop - Padding top on the label for the radio alert
$alert-md-radio-label-padding-top: 13px;
$alert-md-radio-label-padding-top: 13px;
/// @prop - Padding end on the label for the radio alert
$alert-md-radio-label-padding-end: 26px;
$alert-md-radio-label-padding-end: 26px;
/// @prop - Padding bottom on the label for the radio alert
$alert-md-radio-label-padding-bottom: $alert-md-radio-label-padding-top;
$alert-md-radio-label-padding-bottom: $alert-md-radio-label-padding-top;
/// @prop - Padding start on the label for the radio alert
$alert-md-radio-label-padding-start: $alert-md-radio-label-padding-end + 26px;
$alert-md-radio-label-padding-start: $alert-md-radio-label-padding-end + 26px;
/// @prop - Font size of the label for the radio alert
$alert-md-radio-label-font-size: dynamic-font(16px);
$alert-md-radio-label-font-size: dynamic-font(16px);
/// @prop - Text color of the label for the radio alert
$alert-md-radio-label-text-color: $text-color-step-150;
$alert-md-radio-label-text-color: $text-color-step-150;
/// @prop - Text color of the label for the checked radio alert
$alert-md-radio-label-text-color-checked: $alert-md-radio-label-text-color;
$alert-md-radio-label-text-color-checked: $alert-md-radio-label-text-color;
/// @prop - Top of the checkbox in the alert
$alert-md-checkbox-top: 0;
$alert-md-checkbox-top: 0;
/// @prop - Left of the checkbox in the alert
$alert-md-checkbox-left: 26px;
$alert-md-checkbox-left: 26px;
/// @prop - Width of the checkbox in the alert
$alert-md-checkbox-width: 16px;
$alert-md-checkbox-width: 16px;
/// @prop - Height of the checkbox in the alert
$alert-md-checkbox-height: 16px;
$alert-md-checkbox-height: 16px;
/// @prop - Border width of the checkbox in the alert
$alert-md-checkbox-border-width: 2px;
$alert-md-checkbox-border-width: 2px;
/// @prop - Border style of the checkbox in the alert
$alert-md-checkbox-border-style: solid;
$alert-md-checkbox-border-style: solid;
/// @prop - Border radius of the checkbox in the alert
$alert-md-checkbox-border-radius: 2px;
$alert-md-checkbox-border-radius: 2px;
/// @prop - Border color of the checkbox in the alert when off
$alert-md-checkbox-border-color-off: $background-color-step-550;
$alert-md-checkbox-border-color-off: $background-color-step-550;
/// @prop - Border color of the checkbox in the alert when on
$alert-md-checkbox-border-color-on: $alert-md-button-text-color;
$alert-md-checkbox-border-color-on: $alert-md-button-text-color;
/// @prop - Top of the icon in the checkbox alert
$alert-md-checkbox-icon-top: 0;
$alert-md-checkbox-icon-top: 0;
/// @prop - Start of the icon in the checkbox alert
$alert-md-checkbox-icon-start: 3px;
$alert-md-checkbox-icon-start: 3px;
/// @prop - Width of the icon in the checkbox alert
$alert-md-checkbox-icon-width: 6px;
$alert-md-checkbox-icon-width: 6px;
/// @prop - Height of the icon in the checkbox alert
$alert-md-checkbox-icon-height: 10px;
$alert-md-checkbox-icon-height: 10px;
/// @prop - Border width of the icon in the checkbox alert
$alert-md-checkbox-icon-border-width: 2px;
$alert-md-checkbox-icon-border-width: 2px;
/// @prop - Border style of the icon in the checkbox alert
$alert-md-checkbox-icon-border-style: solid;
$alert-md-checkbox-icon-border-style: solid;
/// @prop - Border color of the icon in the checkbox alert
$alert-md-checkbox-icon-border-color: ion-color(primary, contrast);
$alert-md-checkbox-icon-border-color: ion-color(primary, contrast);
/// @prop - Transform of the icon in the checkbox alert
$alert-md-checkbox-icon-transform: rotate(45deg);
$alert-md-checkbox-icon-transform: rotate(45deg);
/// @prop - Padding top of the label for the checkbox in the alert
$alert-md-checkbox-label-padding-top: 13px;
$alert-md-checkbox-label-padding-top: 13px;
/// @prop - Padding end of the label for the checkbox in the alert
$alert-md-checkbox-label-padding-end: $alert-md-checkbox-left;
$alert-md-checkbox-label-padding-end: $alert-md-checkbox-left;
/// @prop - Padding bottom of the label for the checkbox in the alert
$alert-md-checkbox-label-padding-bottom: $alert-md-checkbox-label-padding-top;
$alert-md-checkbox-label-padding-bottom: $alert-md-checkbox-label-padding-top;
/// @prop - Padding start of the label for the checkbox in the alert
$alert-md-checkbox-label-padding-start: $alert-md-checkbox-label-padding-end + 27px;
$alert-md-checkbox-label-padding-start: $alert-md-checkbox-label-padding-end + 27px;
/// @prop - Text color of the label for the checkbox in the alert
$alert-md-checkbox-label-text-color: $text-color-step-150;
$alert-md-checkbox-label-text-color: $text-color-step-150;
/// @prop - Font size of the label for the checkbox in the alert
$alert-md-checkbox-label-font-size: dynamic-font(16px);
$alert-md-checkbox-label-font-size: dynamic-font(16px);
/// @prop - Height of the tappable inputs in the checkbox alert
$alert-md-tappable-height: $item-md-min-height;
$alert-md-tappable-height: $item-md-min-height;

View File

@@ -198,13 +198,14 @@
min-height: inherit;
}
// Alert Button: Disabled
// --------------------------------------------------
.alert-input-disabled,
.alert-checkbox-button-disabled .alert-button-inner,
.alert-radio-button-disabled .alert-button-inner {
cursor: default;
opacity: 0.5;
opacity: .5;
pointer-events: none;
}

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;
@@ -343,7 +341,9 @@ export class Alert implements ComponentInterface, OverlayInterface {
}
componentWillLoad() {
setOverlayId(this.el);
if (!this.htmlAttributes?.id) {
setOverlayId(this.el);
}
this.inputsChanged();
this.buttonsChanged();
}
@@ -535,7 +535,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 +567,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 +684,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 +701,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 +723,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 +748,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
}}
class={{
...getClassMap(this.cssClass),
[theme]: true,
[mode]: true,
'overlay-hidden': true,
'alert-translucent': this.translucent,
}}

View File

@@ -1,19 +1,19 @@
@import "../../themes/native/native.globals";
@import "../../themes/ionic.globals";
// Alert
// --------------------------------------------------
/// @prop - Minimum width of the alert
$alert-min-width: 250px;
$alert-min-width: 250px;
/// @prop - Maximum height of the alert
$alert-max-height: 90%;
$alert-max-height: 90%;
/// @prop - Line height of the alert button
$alert-button-line-height: dynamic-font(20px);
$alert-button-line-height: dynamic-font(20px);
/// @prop - Font size of the alert button
$alert-button-font-size: dynamic-font(14px);
$alert-button-font-size: dynamic-font(14px);
/// @prop - Minimum height of a textarea in the alert
$alert-input-min-height: 37px;
$alert-input-min-height: 37px;

View File

@@ -2,6 +2,7 @@ import { newSpecPage } from '@stencil/core/testing';
import { config } from '../../../global/config';
import { Alert } from '../alert';
import { h } from '@stencil/core';
describe('alert: custom html', () => {
it('should not allow for custom html by default', async () => {
@@ -38,4 +39,15 @@ describe('alert: custom html', () => {
expect(content.textContent).toContain('Custom Text');
expect(content.querySelector('button.custom-html')).toBe(null);
});
it('should not overwrite the id set in htmlAttributes', async () => {
const id = 'custom-id';
const page = await newSpecPage({
components: [Alert],
template: () => <ion-alert htmlAttributes={{ id }} overlayIndex={-1}></ion-alert>,
});
const alert = page.body.querySelector('ion-alert')!;
expect(alert.id).toBe(id);
});
});

View File

@@ -1,3 +1,4 @@
html.plt-mobile ion-app {
user-select: none;
}

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -1,137 +0,0 @@
@use "../../themes/ionic/ionic.globals.scss" as globals;
@import "./avatar";
// Ionic Avatar
// --------------------------------------------------
:host {
--padding-top: #{globals.$ionic-space-0};
--padding-bottom: #{globals.$ionic-space-0};
display: flex;
align-items: center;
justify-content: center;
background: globals.$ionic-color-neutral-100;
color: globals.$ionic-color-neutral-800;
font-weight: globals.$ionic-font-weight-medium;
line-height: globals.$ionic-line-height-700;
}
:host(:not(.avatar-image)) {
@include padding(var(--padding-top), var(--padding-end), var(--padding-bottom), var(--padding-start));
border: globals.$ionic-border-size-025 globals.$ionic-border-style-solid globals.$ionic-color-neutral-800;
}
// Avatar Sizes
// --------------------------------------------------
:host(.avatar-xsmall) {
--padding-end: #{globals.$ionic-space-050};
--padding-start: #{globals.$ionic-space-050};
width: globals.$ionic-scale-600;
height: globals.$ionic-scale-600;
font-size: globals.$ionic-font-size-300;
line-height: globals.$ionic-line-height-400;
}
:host(.avatar-small) {
--padding-end: #{globals.$ionic-space-150};
--padding-start: #{globals.$ionic-space-150};
width: globals.$ionic-scale-800;
height: globals.$ionic-scale-800;
font-size: globals.$ionic-font-size-400;
line-height: globals.$ionic-line-height-600;
}
:host(.avatar-medium) {
--padding-end: #{globals.$ionic-space-200};
--padding-start: #{globals.$ionic-space-200};
width: globals.$ionic-scale-1000;
height: globals.$ionic-scale-1000;
font-size: globals.$ionic-font-size-450;
}
:host(.avatar-large) {
--padding-end: #{globals.$ionic-space-250};
--padding-start: #{globals.$ionic-space-250};
width: globals.$ionic-scale-1200;
height: globals.$ionic-scale-1200;
font-size: globals.$ionic-font-size-500;
}
:host(.avatar-xlarge) {
--padding-end: #{globals.$ionic-space-300};
--padding-start: #{globals.$ionic-space-300};
width: globals.$ionic-scale-1400;
height: globals.$ionic-scale-1400;
font-size: globals.$ionic-font-size-550;
}
// Avatar Shapes
// --------------------------------------------------
:host(.avatar-xsmall.avatar-soft),
:host(.avatar-small.avatar-soft) {
--border-radius: #{globals.$ionic-border-radius-100};
}
:host(.avatar-soft) {
--border-radius: #{globals.$ionic-border-radius-200};
}
:host(.avatar-round) {
--border-radius: #{globals.$ionic-border-radius-full};
}
:host(.avatar-rectangular) {
--border-radius: #{globals.$ionic-border-radius-0};
}
// Avatar Icon
// --------------------------------------------------
:host(.avatar-icon) {
@include padding(0);
}
:host(.avatar-xsmall) ::slotted(ion-icon) {
width: globals.$ionic-scale-400;
height: globals.$ionic-scale-400;
}
:host(.avatar-small) ::slotted(ion-icon) {
width: globals.$ionic-scale-500;
height: globals.$ionic-scale-500;
}
:host(.avatar-medium) ::slotted(ion-icon) {
width: globals.$ionic-scale-600;
height: globals.$ionic-scale-600;
}
:host(.avatar-large) ::slotted(ion-icon) {
width: globals.$ionic-scale-800;
height: globals.$ionic-scale-800;
}
:host(.avatar-xlarge) ::slotted(ion-icon) {
width: globals.$ionic-scale-1000;
height: globals.$ionic-scale-1000;
}

View File

@@ -1,6 +1,7 @@
@import "./avatar";
@import "./avatar.ios.vars";
// iOS Avatar
// --------------------------------------------------

View File

@@ -1,13 +1,14 @@
@import "../../themes/native/native.globals.ios";
@import "../../themes/ionic.globals.ios";
// iOS Avatar
// --------------------------------------------------
/// @prop - Width of the avatar
$avatar-ios-width: 48px;
$avatar-ios-width: 48px;
/// @prop - Height of the avatar
$avatar-ios-height: $avatar-ios-width;
$avatar-ios-height: $avatar-ios-width;
/// @prop - Border radius of the avatar
$avatar-ios-border-radius: 50%;
$avatar-ios-border-radius: 50%;

View File

@@ -1,6 +1,7 @@
@import "./avatar";
@import "./avatar.md.vars";
// Material Design Avatar
// --------------------------------------------------

View File

@@ -1,13 +1,14 @@
@import "../../themes/native/native.globals.md";
@import "../../themes/ionic.globals.md";
// Material Design Avatar
// --------------------------------------------------
/// @prop - Width of the avatar
$avatar-md-width: 64px;
$avatar-md-width: 64px;
/// @prop - Height of the avatar
$avatar-md-height: $avatar-md-width;
$avatar-md-height: $avatar-md-width;
/// @prop - Border radius of the avatar
$avatar-md-border-radius: 50%;
$avatar-md-border-radius: 50%;

View File

@@ -1,4 +1,5 @@
@import "../../themes/native/native.globals";
@import "../../themes/ionic.globals";
// Avatar
// --------------------------------------------------

View File

@@ -1,97 +1,20 @@
import type { ComponentInterface } from '@stencil/core';
import { Component, Element, Host, Prop, h } 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.ionic.scss',
},
shadow: true,
})
export class Avatar implements ComponentInterface {
@Element() el!: HTMLElement;
/**
* Set to `"xsmall"` for the smallest size, `"small"` for a compact size, `"medium"`
* for the default height and width, `"large"` for a larger size, or `"xlarge"` for
* the largest dimensions.
*
* Defaults to `"medium"` for the `ionic` theme, undefined for all other themes.
*/
@Prop() size?: `xsmall` | 'small' | 'medium' | 'large' | 'xlarge';
/**
* Set to `"soft"` for an avatar with slightly rounded corners,
* `"round"` for an avatar with fully rounded corners, or `"rectangular"`
* for an avatar without rounded corners.
*
* Defaults to `"round"` for the `ionic` theme, undefined for all other themes.
*/
@Prop() shape?: 'soft' | 'round' | 'rectangular';
get hasImage() {
return !!this.el.querySelector('ion-img') || !!this.el.querySelector('img');
}
get hasIcon() {
return !!this.el.querySelector('ion-icon');
}
private getSize(): string | undefined {
const theme = getIonTheme(this);
const { size } = this;
// TODO(ROU-10752): Remove theme check when sizes are defined for all themes.
if (theme !== 'ionic') {
return undefined;
}
if (size === undefined) {
return 'medium';
}
return size;
}
private getShape(): string | undefined {
const theme = getIonTheme(this);
const { shape } = this;
// TODO(ROU-10755): Remove theme check when shapes are defined for all themes.
if (theme !== 'ionic') {
return undefined;
}
if (shape === undefined) {
return 'round';
}
return shape;
}
render() {
const theme = getIonTheme(this);
const size = this.getSize();
const shape = this.getShape();
return (
<Host
class={{
[theme]: true,
[`avatar-${size}`]: size !== undefined,
[`avatar-${shape}`]: shape !== undefined,
[`avatar-image`]: this.hasImage,
[`avatar-icon`]: this.hasIcon,
}}
>
<Host class={getIonMode(this)}>
<slot></slot>
</Host>
);

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -1,185 +0,0 @@
import { expect } from '@playwright/test';
import { configs, test } from '@utils/test/playwright';
/**
* This behavior does not vary across directions.
*/
configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ config, screenshot, title }) => {
test.describe(title('avatar: shape'), () => {
test.describe('round', () => {
test('should not have visual regressions when containing text', async ({ page }) => {
await page.setContent(
`
<ion-avatar shape="round">AB</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-shape-round-text`));
});
test('should not have visual regressions when containing an icon', async ({ page }) => {
await page.setContent(
`
<ion-avatar shape="round">
<ion-icon name="person-outline"></ion-icon>
</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-shape-round-icon`));
});
test('should not have visual regressions when containing an image', async ({ page }) => {
await page.setContent(
`
<ion-avatar shape="round">
<img src="/src/components/avatar/test/avatar.svg"/>
</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-shape-round-image`));
});
});
test.describe('rectangular', () => {
test('should not have visual regressions when containing text', async ({ page }) => {
await page.setContent(
`
<ion-avatar shape="rectangular">AB</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-shape-rectangular-text`));
});
test('should not have visual regressions when containing an icon', async ({ page }) => {
await page.setContent(
`
<ion-avatar shape="rectangular">
<ion-icon name="person-outline"></ion-icon>
</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-shape-rectangular-icon`));
});
test('should not have visual regressions when containing an image', async ({ page }) => {
await page.setContent(
`
<ion-avatar shape="rectangular">
<img src="/src/components/avatar/test/avatar.svg"/>
</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-shape-rectangular-image`));
});
});
test.describe('soft', () => {
test('should not have visual regressions when containing text', async ({ page }) => {
await page.setContent(
`
<style>
#container {
display: flex;
gap: 10px;
}
</style>
<div id="container">
<ion-avatar shape="soft" size="xsmall">AB</ion-avatar>
<ion-avatar shape="soft" size="small">AB</ion-avatar>
<ion-avatar shape="soft">AB</ion-avatar>
</div>
`,
config
);
const container = page.locator('#container');
await expect(container).toHaveScreenshot(screenshot(`avatar-shape-soft-text`));
});
test('should not have visual regressions when containing an icon', async ({ page }) => {
await page.setContent(
`
<style>
#container {
display: flex;
gap: 10px;
}
</style>
<div id="container">
<ion-avatar shape="soft" size="xsmall">
<ion-icon name="person-outline"></ion-icon>
</ion-avatar>
<ion-avatar shape="soft" size="small">
<ion-icon name="person-outline"></ion-icon>
</ion-avatar>
<ion-avatar shape="soft">
<ion-icon name="person-outline"></ion-icon>
</ion-avatar>
</div>
`,
config
);
const container = page.locator('#container');
await expect(container).toHaveScreenshot(screenshot(`avatar-shape-soft-icon`));
});
test('should not have visual regressions when containing an image', async ({ page }) => {
await page.setContent(
`
<style>
#container {
display: flex;
gap: 10px;
}
</style>
<div id="container">
<ion-avatar shape="soft" size="xsmall">
<img src="/src/components/avatar/test/avatar.svg"/>
</ion-avatar>
<ion-avatar shape="soft" size="small">
<img src="/src/components/avatar/test/avatar.svg"/>
</ion-avatar>
<ion-avatar shape="soft">
<img src="/src/components/avatar/test/avatar.svg"/>
</ion-avatar>
</div>
`,
config
);
const container = page.locator('#container');
await expect(container).toHaveScreenshot(screenshot(`avatar-shape-soft-image`));
});
});
});
});

View File

@@ -1,73 +0,0 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Avatar - Shape</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
<style>
.container {
display: flex;
gap: 10px;
}
</style>
</head>
<body>
<ion-app>
<ion-header>
<ion-toolbar>
<ion-title>Avatar - Shape</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding" id="content" no-bounce>
<h2>Default</h2>
<div class="container">
<ion-avatar>AB</ion-avatar>
<ion-avatar>
<ion-icon name="person-outline"></ion-icon>
</ion-avatar>
<ion-avatar>
<img src="/src/components/avatar/test/avatar.svg" />
</ion-avatar>
</div>
<h2>Soft</h2>
<div class="container">
<ion-avatar shape="soft" size="xsmall">AB</ion-avatar>
<ion-avatar shape="soft" size="small">AB</ion-avatar>
<ion-avatar shape="soft" size="medium">AB</ion-avatar>
<ion-avatar shape="soft" size="large">AB</ion-avatar>
<ion-avatar shape="soft" size="xlarge">AB</ion-avatar>
</div>
<h2>Round</h2>
<div class="container">
<ion-avatar shape="round" size="xsmall">AB</ion-avatar>
<ion-avatar shape="round" size="small">AB</ion-avatar>
<ion-avatar shape="round" size="medium">AB</ion-avatar>
<ion-avatar shape="round" size="large">AB</ion-avatar>
<ion-avatar shape="round" size="xlarge">AB</ion-avatar>
</div>
<h2>Rectangular</h2>
<div class="container">
<ion-avatar shape="rectangular" size="xsmall">AB</ion-avatar>
<ion-avatar shape="rectangular" size="small">AB</ion-avatar>
<ion-avatar shape="rectangular" size="medium">AB</ion-avatar>
<ion-avatar shape="rectangular" size="large">AB</ion-avatar>
<ion-avatar shape="rectangular" size="xlarge">AB</ion-avatar>
</div>
</ion-content>
</ion-app>
</body>
</html>

View File

@@ -1,234 +0,0 @@
import { expect } from '@playwright/test';
import { configs, test } from '@utils/test/playwright';
/**
* This behavior does not vary across directions.
*/
configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ config, screenshot, title }) => {
test.describe(title('avatar: size'), () => {
test.describe('xsmall', () => {
test('should not have visual regressions when containing text', async ({ page }) => {
await page.setContent(
`
<ion-avatar size="xsmall">AB</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-size-xsmall-text`));
});
test('should not have visual regressions when containing an icon', async ({ page }) => {
await page.setContent(
`
<ion-avatar size="xsmall">
<ion-icon name="person-outline"></ion-icon>
</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-size-xsmall-icon`));
});
test('should not have visual regressions when containing an image', async ({ page }) => {
await page.setContent(
`
<ion-avatar size="xsmall">
<img src="/src/components/avatar/test/avatar.svg"/>
</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-size-xsmall-image`));
});
});
test.describe('small', () => {
test('should not have visual regressions when containing text', async ({ page }) => {
await page.setContent(
`
<ion-avatar size="small">AB</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-size-small-text`));
});
test('should not have visual regressions when containing an icon', async ({ page }) => {
await page.setContent(
`
<ion-avatar size="small">
<ion-icon name="person-outline"></ion-icon>
</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-size-small-icon`));
});
test('should not have visual regressions when containing an image', async ({ page }) => {
await page.setContent(
`
<ion-avatar size="small">
<img src="/src/components/avatar/test/avatar.svg"/>
</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-size-small-image`));
});
});
test.describe('medium', () => {
test('should not have visual regressions when containing text', async ({ page }) => {
await page.setContent(
`
<ion-avatar size="medium">AB</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-size-medium-text`));
});
test('should not have visual regressions when containing an icon', async ({ page }) => {
await page.setContent(
`
<ion-avatar size="medium">
<ion-icon name="person-outline"></ion-icon>
</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-size-medium-icon`));
});
test('should not have visual regressions when containing an image', async ({ page }) => {
await page.setContent(
`
<ion-avatar size="medium">
<img src="/src/components/avatar/test/avatar.svg"/>
</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-size-medium-image`));
});
});
test.describe('large', () => {
test('should not have visual regressions when containing text', async ({ page }) => {
await page.setContent(
`
<ion-avatar size="large">AB</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-size-large-text`));
});
test('should not have visual regressions when containing an icon', async ({ page }) => {
await page.setContent(
`
<ion-avatar size="large">
<ion-icon name="person-outline"></ion-icon>
</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-size-large-icon`));
});
test('should not have visual regressions when containing an image', async ({ page }) => {
await page.setContent(
`
<ion-avatar size="large">
<img src="/src/components/avatar/test/avatar.svg"/>
</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-size-large-image`));
});
});
test.describe('xlarge', () => {
test('should not have visual regressions when containing text', async ({ page }) => {
await page.setContent(
`
<ion-avatar size="xlarge">AB</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-size-xlarge-text`));
});
test('should not have visual regressions when containing an icon', async ({ page }) => {
await page.setContent(
`
<ion-avatar size="xlarge">
<ion-icon name="person-outline"></ion-icon>
</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-size-xlarge-icon`));
});
test('should not have visual regressions when containing an image', async ({ page }) => {
await page.setContent(
`
<ion-avatar size="xlarge">
<img src="/src/components/avatar/test/avatar.svg"/>
</ion-avatar>
`,
config
);
const avatar = page.locator('ion-avatar');
await expect(avatar).toHaveScreenshot(screenshot(`avatar-size-xlarge-image`));
});
});
});
});

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