Compare commits

..

26 Commits

Author SHA1 Message Date
Sean Perkins
395b14317f chore: use dev-build 2023-11-15 12:56:32 -05:00
Liam DeBeasi
9fad566175 merge release-7.5.5
Release 7.5.5
2023-11-15 10:56:17 -05:00
Liam DeBeasi
6dcf9cadb3 chore: add note for Ionic Vue developers 2023-11-15 10:31:23 -05:00
ionitron
9bb45b3772 chore(): update package lock files 2023-11-15 15:27:39 +00:00
ionitron
78ce39f8c6 v7.5.5 2023-11-15 15:27:28 +00:00
Liam DeBeasi
093c671e3e test(angular): remove routing waits in tests (#28532)
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. -->

Our Angular E2E tests are brittle because they rely on arbitrary
`cy.wait` calls to account for asynchronous routing. This leads to flaky
tests on CI and seemingly random test failures when we make adjustments
to the Ionic Anguar routing integration (see:
https://github.com/ionic-team/ionic-framework/pull/28188)

Additionally, our test execution for the navigation tests is quite slow
because transitions are enabled. As a result, we need to wait hundreds
of ms per test just for the transitions to finish.

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

- Updated the `testStack` command to use a new `getStack` [Cypress
query](https://docs.cypress.io/api/cypress-api/custom-queries). These
queries come with automatic retrying built-in. By leveraging this query
in the `testStack` command, we can avoid the arbitrary waits.
- Added `ionic:_testing=true` query strings to the navigation tests.
This causes Ionic to disable any transitions so the tests execute
faster.
- Removed most of the arbitrary `cy.wait` calls. I kept the swipe to go
back `cy.wait` -- I wasn't quite sure how to reduce flakiness on that
one.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
2023-11-14 23:04:09 +00:00
dependabot[bot]
ed80b7f118 chore(deps): Bump @stencil/core from 4.7.1 to 4.7.2 in /core (#28522)
Bumps [@stencil/core](https://github.com/ionic-team/stencil) from 4.7.1
to 4.7.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/ionic-team/stencil/releases"><code>@​stencil/core</code>'s
releases</a>.</em></p>
<blockquote>
<h2>🐄 v4.7.2 (2023-11-13)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>compiler:</strong> normalize paths on windows (<a
href="https://redirect.github.com/ionic-team/stencil/issues/4997">#4997</a>)
(<a
href="bb0b1d46f6">bb0b1d4</a>),
closes <a
href="https://redirect.github.com/ionic-team/stencil/issues/4980">#4980</a>
<a
href="https://redirect.github.com/ionic-team/stencil/issues/4961">#4961</a></li>
<li><strong>runtime:</strong> add display style to slot-fb elements (<a
href="https://redirect.github.com/ionic-team/stencil/issues/5028">#5028</a>)
(<a
href="72c1f1a352">72c1f1a</a>)</li>
<li><strong>test:</strong> don't fail build when jest typings can't be
resolved (<a
href="https://redirect.github.com/ionic-team/stencil/issues/5031">#5031</a>)
(<a
href="5df16e69d2">5df16e6</a>),
closes <a
href="https://redirect.github.com/ionic-team/stencil/issues/5030">#5030</a></li>
<li><strong>vite:</strong> resolve PURE comment warnings (<a
href="https://redirect.github.com/ionic-team/stencil/issues/5018">#5018</a>)
(<a
href="0a1fbe144e">0a1fbe1</a>),
closes <a
href="https://redirect.github.com/ionic-team/stencil/issues/5008">#5008</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/ionic-team/stencil/blob/main/CHANGELOG.md"><code>@​stencil/core</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>🐄 <a
href="https://github.com/ionic-team/stencil/compare/v4.7.1...v4.7.2">4.7.2</a>
(2023-11-13)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>compiler:</strong> normalize paths on windows (<a
href="https://redirect.github.com/ionic-team/stencil/issues/4997">#4997</a>)
(<a
href="bb0b1d46f6">bb0b1d4</a>),
closes <a
href="https://redirect.github.com/ionic-team/stencil/issues/4980">#4980</a>
<a
href="https://redirect.github.com/ionic-team/stencil/issues/4961">#4961</a></li>
<li><strong>runtime:</strong> add display style to slot-fb elements (<a
href="https://redirect.github.com/ionic-team/stencil/issues/5028">#5028</a>)
(<a
href="72c1f1a352">72c1f1a</a>)</li>
<li><strong>test:</strong> don't fail build when jest typings can't be
resolved (<a
href="https://redirect.github.com/ionic-team/stencil/issues/5031">#5031</a>)
(<a
href="5df16e69d2">5df16e6</a>),
closes <a
href="https://redirect.github.com/ionic-team/stencil/issues/5030">#5030</a></li>
<li><strong>vite:</strong> resolve PURE comment warnings (<a
href="https://redirect.github.com/ionic-team/stencil/issues/5018">#5018</a>)
(<a
href="0a1fbe144e">0a1fbe1</a>),
closes <a
href="https://redirect.github.com/ionic-team/stencil/issues/5008">#5008</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="d321cb5839"><code>d321cb5</code></a>
v4.7.2 (<a
href="https://redirect.github.com/ionic-team/stencil/issues/5062">#5062</a>)</li>
<li><a
href="4ea0ce0b1f"><code>4ea0ce0</code></a>
chore(deps): update dependency <code>@​types/eslint</code> to v8.44.7
(<a
href="https://redirect.github.com/ionic-team/stencil/issues/5056">#5056</a>)</li>
<li><a
href="5c917c9411"><code>5c917c9</code></a>
chore(ci): unpin node minor version (<a
href="https://redirect.github.com/ionic-team/stencil/issues/5055">#5055</a>)</li>
<li><a
href="cb4120c381"><code>cb4120c</code></a>
chore(deps): update typescript-eslint to v6.10.0 (<a
href="https://redirect.github.com/ionic-team/stencil/issues/5060">#5060</a>)</li>
<li><a
href="0b5c71ae54"><code>0b5c71a</code></a>
chore(deps): update dependency cspell to v8 (<a
href="https://redirect.github.com/ionic-team/stencil/issues/5061">#5061</a>)</li>
<li><a
href="0a7100e568"><code>0a7100e</code></a>
chore(deps): update dependency <code>@​types/node</code> to v20.9.0 (<a
href="https://redirect.github.com/ionic-team/stencil/issues/5058">#5058</a>)</li>
<li><a
href="b795a54178"><code>b795a54</code></a>
refactor(jest): narrow getJestPreset typings (<a
href="https://redirect.github.com/ionic-team/stencil/issues/5053">#5053</a>)</li>
<li><a
href="72c1f1a352"><code>72c1f1a</code></a>
fix(runtime): add display style to slot-fb elements (<a
href="https://redirect.github.com/ionic-team/stencil/issues/5028">#5028</a>)</li>
<li><a
href="bb0b1d46f6"><code>bb0b1d4</code></a>
fix(compiler): normalize paths on windows (<a
href="https://redirect.github.com/ionic-team/stencil/issues/4997">#4997</a>)</li>
<li><a
href="bd826ffc6f"><code>bd826ff</code></a>
refactor(worker): document worker code, improve types (<a
href="https://redirect.github.com/ionic-team/stencil/issues/5034">#5034</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/ionic-team/stencil/compare/v4.7.1...v4.7.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@stencil/core&package-manager=npm_and_yarn&previous-version=4.7.1&new-version=4.7.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-14 21:09:35 +00:00
dependabot[bot]
83f9ac0fac chore(deps-dev): Bump @stencil/vue-output-target from 0.8.6 to 0.8.7 in /core (#28508)
Bumps
[@stencil/vue-output-target](https://github.com/ionic-team/stencil-ds-output-targets)
from 0.8.6 to 0.8.7.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/ionic-team/stencil-ds-output-targets/commits">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@stencil/vue-output-target&package-manager=npm_and_yarn&previous-version=0.8.6&new-version=0.8.7)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Liam DeBeasi <liamdebeasi@users.noreply.github.com>
2023-11-13 20:00:24 +00:00
Mohamed Ben Makhlouf
a000dd2c0b fix(accordion-group): correct accordion is open on load (#28510)
Issue number: resolves #28506 

---------

<!-- 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. -->
ion-accordion-group would not set the value when using it as a Angular
standalone component and data binding:

``` html
<ion-accordion-group #accordionGroup [value]="fromValue">
  <ion-accordion value="turtles">
    <ion-item slot="header" color="light">
      <ion-label>First Accordion</ion-label>
    </ion-item>
    <div class="ion-padding" slot="content">First Content</div>
  </ion-accordion>
  <ion-accordion value="second">
    <ion-item slot="header" color="light">
      <ion-label>Second Accordion</ion-label>
    </ion-item>
    <div class="ion-padding" slot="content">Second Content</div>
  </ion-accordion>
</ion-accordion-group>

```

The problem here is Angular is setting the value of the accordion group
after the component has been initialized (but not loaded) and before the
component watchers are setup, so
[valueChanged](d69ad43482/core/src/components/accordion-group/accordion-group.tsx (L78))
does not fire automatically.

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

- Run valueChanged() in componentDidLoad().
-
-

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## 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: Mohamed Ben Makhlouf <benmakhlouf@softcatalyst.com>
Co-authored-by: Liam DeBeasi <liamdebeasi@users.noreply.github.com>
2023-11-13 19:43:21 +00:00
Shawn Taylor
04d32b6d68 chore: adds angular test app for v17 (#28513)
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. -->
There is no Angular v17 test app.

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
There is an Angular v17 test app.

New overrides:
- angular.json: `browserTarget` was changed to `buildTarget` and to
replace `@nguniversal` with `@angular/ssr` and
`@angular-devkit/build-angular`
- server.ts: Replace uses of `@nguniversal` with `@angular/ssr`

New change to base:
- polyfills.ts: Import
[changed](https://github.com/angular/angular/blob/main/CHANGELOG.md#zonejs)
from `import 'zone.js/dist/zone';` (this change is supported for all
versions of Angular that we support, so should be changed in the base
file)

All other files were duplicated from their v16 counterparts.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
2023-11-13 19:30:36 +00:00
Liam DeBeasi
342511959a chore(datetime): remove unused code (#28502)
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. -->

While evaluating step colors for high contrast themes I discovered that
this code is not actually applied anywhere.

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

- Remove unused code

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
2023-11-13 16:16:13 +00:00
Brandy Carney
900267eb36 fix(action-sheet): adjust height for safe area with scrollable options (#28504)
Issue number: fixes #27777

---------

## What is the current behavior?
When safe area (top/bottom) is applied to an action sheet with
scrollable options and a cancel button, the cancel button is pushed off
the screen and cannot be reached.

## What is the new behavior?
Properly adjust the height of the action sheet container to account for
the top and bottom safe area.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

## Other information

The below screenshots use the following CSS when safe area is added so
it is expected that the action sheet will adjust the top and bottom:

```css
:root {
  --ion-safe-area-top: 60px;
  --ion-safe-area-bottom: 40px;
}
```

### iOS

|                    | Before (`main`) | After (`FW-4715`) |
| -------------------| ----------------| ------------------|
| **No** Safe Area |
![ios-main-no-safe-area](https://github.com/ionic-team/ionic-framework/assets/6577830/2bbb8c09-6e35-4f88-983c-019cef1b9f44)
|
![ios-branch-no-safe-area](https://github.com/ionic-team/ionic-framework/assets/6577830/55d899d3-945e-4d1e-983f-5d9b0a3ad6cc)
|
| **Safe Area** |
![ios-main-safe-area](https://github.com/ionic-team/ionic-framework/assets/6577830/7b7ea64c-4432-4160-aadb-8be333549bc6)
|
![ios-branch-safe-area](https://github.com/ionic-team/ionic-framework/assets/6577830/02143b3a-ca40-4294-b77c-3bb7867da0b9)
|

### Material Design

|                    | Before (`main`) | After (`FW-4715`) |
| -------------------| ----------------| ------------------|
| **No** Safe Area |
![md-main-no-safe-area](https://github.com/ionic-team/ionic-framework/assets/6577830/a448bd22-6d79-4f2c-a0ec-654c6679732f)
|
![md-branch-no-safe-area](https://github.com/ionic-team/ionic-framework/assets/6577830/ef8244c4-b8e8-434b-bd06-1d6981396574)
|
| **Safe Area** |
![md-main-safe-area](https://github.com/ionic-team/ionic-framework/assets/6577830/80e00ce6-eb34-4d87-9546-a49da373fb6b)
|
![md-branch-safe-area](https://github.com/ionic-team/ionic-framework/assets/6577830/d8b86141-a65c-4026-b895-8d167ebc6258)
|

---------

Co-authored-by: ionitron <hi@ionicframework.com>
2023-11-13 15:50:58 +00:00
Maria Hutt
73b8bfde3f fix(radio-group): emit value change on componentDidLoad (#28488)
Issue number: resolves #28356 

---------

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

`ion-radio-group` would not set the radio value when using it as a
Angular standalone component and data binding:

```html
<ion-radio-group [value]="fromValue">
  <ion-radio value="dogs">Dogs</ion-radio><br />
  <ion-radio value="cats">Cats</ion-radio><br />
  <ion-radio value="turtles">Turtles</ion-radio><br />
  <ion-radio value="fish">Fish</ion-radio><br />
</ion-radio-group>
```

This is happening because the value is set before the [value
watcher](c5dd622bbe/core/src/components/radio-group/radio-group.tsx (L34))
has been configured. The event, `ionValueChange`, does not get
[dispatched](c5dd622bbe/core/src/components/radio-group/radio-group.tsx (L37)).

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

Run `valueChanged()` in `componentDidLoad()`.
- `valueChanged()` function is tied to the [value
watcher](c5dd622bbe/core/src/components/radio-group/radio-group.tsx (L34))
so it will
[dispatch](c5dd622bbe/core/src/components/radio-group/radio-group.tsx (L37))
the `ionValueChange`.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

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

In our testing, we observed that the issue described below only occurs
when assigning a value to the radio group within the primary content,
such as rendering within the app component template.

When the template is isolated to a route, the value is assigned
correctly. To address this issue, we need to ensure that the watcher is
called after the component has finished loading, allowing the emit to be
dispatched correctly.

Dev build: 7.5.4-dev.11699404450.136700d7
2023-11-10 22:12:08 +00:00
Sean Perkins
f0a5d2704c refactor(angular): gesture controller uses correct core instance (#28477)
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. -->

The `GestureController` provider does not use the correct underlying
instance of the utilities from either the lazy or custom elements build,
depending on if the developer is using `@ionic/angular` or
`@ionic/angular/standalone`. It will always use the lazy instance.

This applied to the `createGesture` function.

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

- `GestureController` uses the instance of the utilities based on it's
implementation type, e.g. `@ionic/angular/standalone` uses the custom
elements build with the utilities from `@ionic/core/components`.
- `@ionic/angular` and `@ionic/angular/standalone` now export their own
specific implementation of `GestureController`

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->

## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
2023-11-10 02:02:29 +00:00
Sean Perkins
fbc9f53d35 refactor(angular): animation controller uses correct core instance (#28473)
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. -->

The `AnimationController` does not use the correct underlying instance
of the utilities from either the lazy or custom elements build,
depending on if the developer is using `@ionic/angular` or
`@ionic/angular/standalone`. It will always use the lazy instance.

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

- `AnimationController` uses the instance of the utilities based on it's
implementation type, e.g. `@ionic/angular/standalone` uses the custom
elements build with the utilities from `@ionic/core/components`.
- `@ionic/angular` and `@ionic/angular/standalone` now export their own
specific implementation of `AnimationController`

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->

Ionic was re-exporting the `AnimationController` from both
`@ionic/angular` and `@ionic/angular/standalone` entry points.
Developers will not need to update their implementations or change
import paths to take advantage of this change.

## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
2023-11-10 00:43:38 +00:00
Ryan Waskiewicz
d69ad43482 chore(dev-deps): upgrade to jest v29 (#28412)
Issue number: #

---------

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

Ionic Framework uses Jest 27. Previously, this was due to a limitation
of Stencil. As of Stencil v4.7.0, this limitation no longer exists & the
Framework can upgrade to the latest version of Jest.

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

There was a top level dependency on `@jest/core` that I could not find
to be used anywhere. This dependency is included in `jest` by default,
and has been removed as a top level/`package.json` dependency.

Otherwise, all jest packages have been upgraded to jest v29. This is two
major version bumps and a switch to the jest-circus runtime (instead of
jest-jasmine2).

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information
There is some inherent risk of _something_ breaking when someone like me
who doesn't work on this project day-to-day bumps packages. I did this
as a part of testing Jest 29 when implementing its support in Stencil
and thought "Well, why not?". Feel free to reject this PR if you feel
it's not worth the risk/effort at the moment.
<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
2023-11-09 21:28:10 +00:00
Brandy Carney
33200a9311 refactor(angular): use correct core instance for toast controller (#28493)
Issue number: N/A

---------

## What is the current behavior?
As a takeaway from our learning session about a menuController bug in
Ionic Angular, the team would like to update our other providers to use
the same architecture as the menuController to prevent this kind of
issue from happening again in the future.

We also noticed that the common provider does not provide much value and
it's easier to just have two separate implementations in `src` and
`standalone`. (There wasn't much code we could de-duplicate)

## What is the new behavior?
- Removed the common toast provider in favor of separate ones in
src/standalone

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

## Other information
2023-11-09 19:24:58 +00:00
Liam DeBeasi
aeeb84b77d refactor: introduce watch command (#28453)
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. -->

This is part of my work for hack day, but I wanted to tackle the
following problems:

1. There is no easy way to have angular, angular-server, vue,
vue-router, react, and react-router automatically recompile when you
make a change. Right now you have to manually run `npm run build` every
time you make a change.

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

- Adds `npm run build.watch` to let developers easily watch for changes
in each project.
## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
2023-11-09 16:50:19 +00:00
Liam DeBeasi
61b6bd0a0a refactor(angular): modal provider imports correct instance from core (#28486)
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. -->

As a takeaway from our learning session about a menuController bug in
Ionic Angular, the team would like to update our other providers to use
the same architecture as the menuController to prevent this kind of
issue from happening again in the future.

We also noticed that the common provider does not provide much value and
it's easier to just have two separate implementations in `src` and
`standalone`. (There wasn't much code we could de-duplicate)

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

- Removed the common modal provider in favor of separate ones in
src/standalone

We already have test coverage for the modalController, so I did not add
new ones

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
2023-11-09 16:40:36 +00:00
Liam DeBeasi
8227b0ee6d fix(header): collapsible large title does not flicker when collapse prop not reflected (#28472)
Issue number: resolves #28466

---------

<!-- 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 https://github.com/ionic-team/ionic-framework/issues/27060 I fixed an
issue where the main title would be visible briefly before the
collapsible large title a) was configured and b) hid the main title. I
accomplished this by using CSS to target
`ion-header[collapse="condense"]`. However, I failed to account for when
the property is not reflected on the host. Some JS frameworks allow the
property to remain on the element but some do not.

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

- I improved this fix by also targeting the class set on the host. This
class is set regardless of property reflection status.

| main | branch |
| - | - |
| <video
src="https://github.com/ionic-team/ionic-framework/assets/2721089/991523da-8549-451b-930f-5df45c2783de"></video>
| <video
src="https://github.com/ionic-team/ionic-framework/assets/2721089/149c9546-2d9b-42a2-89f1-a17fa146aee6"></video>
|

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

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

Dev build: `7.5.4-dev.11699282935.1db450b0`

---------

Co-authored-by: Brandy Carney <brandyscarney@users.noreply.github.com>
2023-11-09 14:46:01 +00:00
Maria Hutt
c1304b7004 refactor(angular): popover controller uses correct core instance (#28485)
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. -->

As a takeaway from our learning session about a menuController bug in
Ionic Angular, the team would like to update our other providers to use
the same architecture as the menuController to prevent this kind of
issue from happening again in the future.

We also noticed that the common provider does not provide much value and
it's easier to just have two separate implementations in src and
standalone. (There wasn't much code we could de-duplicate)

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

- Removed the common popover provider in favor of separate ones in
src/standalone

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

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

I didn't add tests because there's already existing ones for popover
controller.
2023-11-08 23:52:56 +00:00
Liam DeBeasi
c5dd622bbe refactor(angular): action sheet provider imports correct instance from core (#28474)
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. -->

As a takeaway from our learning session about a menuController bug in
Ionic Angular, the team would like to update our other providers to use
the same architecture as the menuController to prevent this kind of
issue from happening again in the future.

We also noticed that the common provider does not provide much value and
it's easier to just have two separate implementations in `src` and
`standalone`. (There wasn't much code we could de-duplicate)

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

- Removed the common action sheet provider in favor of separate ones in
src/standalone
## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
2023-11-08 17:46:25 +00:00
Liam DeBeasi
c053fd9c68 fix(searchbar): cancel icon aligns with back button (#28478)
Issue number: resolves #28468

---------

<!-- 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 cancel button in the searchbar used to align with the back button,
but that behavior gradually regressed between Ionic v4 and Ionic v7.

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

- Adjusted the padding on the searchbar back button
- Reduced the size of the searchbar back button. It was currently set to
25.6px whereas the `ion-back-button` icon was 24px. This caused the
icons to never align even with 9px. (This should cause a few additional
diffs)
- Added a screenshot test 

| v4 | v5 | v6 | v7 | branch |
| - | - | - | - | - |
| ![Screenshot 2023-11-06 at 5 41
16 PM](https://github.com/ionic-team/ionic-framework/assets/2721089/fadad5ba-00dc-42f2-b0c8-1968f47e90c9)
|
![image](https://github.com/ionic-team/ionic-framework/assets/2721089/798e30a8-5001-41eb-880d-bd3b0becd4cb)
|
![image](https://github.com/ionic-team/ionic-framework/assets/2721089/5e2841f7-a58c-43dc-8338-d9a355785ce9)
|
![image](https://github.com/ionic-team/ionic-framework/assets/2721089/20e590a9-5341-490f-8a3e-ca3666b899e1)
|
![image](https://github.com/ionic-team/ionic-framework/assets/2721089/d2143089-d636-44ec-a87e-28ef27709ffe)
|

Note that in v4 the alignment was slightly off. It was fixed in v5, but
then broke in v6 and remained unchanged in v7 (until now).


## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
Dev build: `7.5.4-dev.11699310489.151b2717`

---------

Co-authored-by: Brandy Carney <brandyscarney@users.noreply.github.com>
Co-authored-by: ionitron <hi@ionicframework.com>
2023-11-08 17:12:39 +00:00
Liam DeBeasi
9e1e55a898 merge release-7.5.4
Release 7.5.4
2023-11-08 11:22:37 -05:00
Shawn Taylor
4513e0c6b0 fix(item-divider): apply safe area to proper side regardless of direction (#28420)
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. -->
The safe area for Item Divider would change sides when the direction
changed. e.g., if the safe area padding should be on the left, it would
be on the left when the direction was LTR but would be on the right when
the direction was RTL. It should always be on the left.

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

- The left safe area padding is on the left side of an Item Divider
whether the direction is LTR or RTL.
- The right safe area padding is on the right side of an Item Divider
whether the direction is LTR or RTL.
- Updated LTR and RTL screenshots for item to include an item divider

Similar to #28403 but for Item Divider.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## 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: ionitron <hi@ionicframework.com>
Co-authored-by: Liam DeBeasi <liamdebeasi@users.noreply.github.com>
Co-authored-by: Brandy Carney <brandyscarney@users.noreply.github.com>
2023-11-08 15:32:37 +00:00
ionitron
95b52ac8ba chore(): update package lock files 2023-11-08 14:49:04 +00:00
123 changed files with 19102 additions and 2759 deletions

View File

@@ -8,7 +8,7 @@ runs:
steps:
- uses: actions/setup-node@v3
with:
node-version: 16
node-version: 18
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core

View File

@@ -140,7 +140,7 @@ jobs:
strategy:
fail-fast: false
matrix:
apps: [ng14, ng15, ng16]
apps: [ng14, ng15, ng16, ng17]
needs: [build-angular, build-angular-server]
runs-on: ubuntu-latest
steps:

View File

@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [7.5.5](https://github.com/ionic-team/ionic-framework/compare/v7.5.4...v7.5.5) (2023-11-15)
### Bug Fixes
* **accordion-group:** correct accordion is open on load ([#28510](https://github.com/ionic-team/ionic-framework/issues/28510)) ([a000dd2](https://github.com/ionic-team/ionic-framework/commit/a000dd2c0b65be8ab5b2ad19f2748fbca13d5085)), closes [#28506](https://github.com/ionic-team/ionic-framework/issues/28506)
* **action-sheet:** adjust height for safe area with scrollable options ([#28504](https://github.com/ionic-team/ionic-framework/issues/28504)) ([900267e](https://github.com/ionic-team/ionic-framework/commit/900267eb36c36f2af63435f6b46acca52b3bdab7)), closes [#27777](https://github.com/ionic-team/ionic-framework/issues/27777)
* **header:** collapsible large title does not flicker when collapse prop not reflected ([#28472](https://github.com/ionic-team/ionic-framework/issues/28472)) ([8227b0e](https://github.com/ionic-team/ionic-framework/commit/8227b0ee6d5250e122a34a83c644f8a74fbbafd5)), closes [#28466](https://github.com/ionic-team/ionic-framework/issues/28466)
* **item-divider:** apply safe area to proper side regardless of direction ([#28420](https://github.com/ionic-team/ionic-framework/issues/28420)) ([4513e0c](https://github.com/ionic-team/ionic-framework/commit/4513e0c6b066d4990800c707e1d97f69c8fcfb0c))
* **radio-group:** emit value change on componentDidLoad ([#28488](https://github.com/ionic-team/ionic-framework/issues/28488)) ([73b8bfd](https://github.com/ionic-team/ionic-framework/commit/73b8bfde3f060490958c10f58d0f68de80cb957f)), closes [#28356](https://github.com/ionic-team/ionic-framework/issues/28356)
* **searchbar:** cancel icon aligns with back button ([#28478](https://github.com/ionic-team/ionic-framework/issues/28478)) ([c053fd9](https://github.com/ionic-team/ionic-framework/commit/c053fd9c68d9b1add1335db80be962215946a0b1)), closes [#28468](https://github.com/ionic-team/ionic-framework/issues/28468)
## [7.5.4](https://github.com/ionic-team/ionic-framework/compare/v7.5.3...v7.5.4) (2023-11-08)

View File

@@ -3,6 +3,25 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [7.5.5](https://github.com/ionic-team/ionic-framework/compare/v7.5.4...v7.5.5) (2023-11-15)
### Bug Fixes
* **accordion-group:** correct accordion is open on load ([#28510](https://github.com/ionic-team/ionic-framework/issues/28510)) ([a000dd2](https://github.com/ionic-team/ionic-framework/commit/a000dd2c0b65be8ab5b2ad19f2748fbca13d5085)), closes [#28506](https://github.com/ionic-team/ionic-framework/issues/28506)
* **action-sheet:** adjust height for safe area with scrollable options ([#28504](https://github.com/ionic-team/ionic-framework/issues/28504)) ([900267e](https://github.com/ionic-team/ionic-framework/commit/900267eb36c36f2af63435f6b46acca52b3bdab7)), closes [#27777](https://github.com/ionic-team/ionic-framework/issues/27777)
* **header:** collapsible large title does not flicker when collapse prop not reflected ([#28472](https://github.com/ionic-team/ionic-framework/issues/28472)) ([8227b0e](https://github.com/ionic-team/ionic-framework/commit/8227b0ee6d5250e122a34a83c644f8a74fbbafd5)), closes [#28466](https://github.com/ionic-team/ionic-framework/issues/28466)
* **item-divider:** apply safe area to proper side regardless of direction ([#28420](https://github.com/ionic-team/ionic-framework/issues/28420)) ([4513e0c](https://github.com/ionic-team/ionic-framework/commit/4513e0c6b066d4990800c707e1d97f69c8fcfb0c))
* **radio-group:** emit value change on componentDidLoad ([#28488](https://github.com/ionic-team/ionic-framework/issues/28488)) ([73b8bfd](https://github.com/ionic-team/ionic-framework/commit/73b8bfde3f060490958c10f58d0f68de80cb957f)), closes [#28356](https://github.com/ionic-team/ionic-framework/issues/28356)
* **searchbar:** cancel icon aligns with back button ([#28478](https://github.com/ionic-team/ionic-framework/issues/28478)) ([c053fd9](https://github.com/ionic-team/ionic-framework/commit/c053fd9c68d9b1add1335db80be962215946a0b1)), closes [#28468](https://github.com/ionic-team/ionic-framework/issues/28468)
> [!NOTE]
> Ionic Vue developers utilizing the `v-ion-change` or `v-ion-input` workaround for https://github.com/ionic-team/ionic-framework/issues/27292 should remove this workaround when updating to Ionic v7.5.5.
## [7.5.4](https://github.com/ionic-team/ionic-framework/compare/v7.5.3...v7.5.4) (2023-11-08)

4130
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": "7.5.4",
"version": "7.5.5",
"description": "Base components for Ionic",
"keywords": [
"ionic",
@@ -31,7 +31,7 @@
"loader/"
],
"dependencies": {
"@stencil/core": "^4.7.1",
"@stencil/core": "^4.6.0-dev.1698410852.c526078",
"ionicons": "^7.2.1",
"tslib": "^2.1.0"
},
@@ -43,15 +43,14 @@
"@capacitor/status-bar": "^5.0.6",
"@ionic/eslint-config": "^0.3.0",
"@ionic/prettier-config": "^2.0.0",
"@jest/core": "^27.5.1",
"@playwright/test": "^1.39.0",
"@rollup/plugin-node-resolve": "^8.4.0",
"@rollup/plugin-virtual": "^2.0.3",
"@stencil/angular-output-target": "^0.8.3",
"@stencil/react-output-target": "^0.5.3",
"@stencil/sass": "^3.0.7",
"@stencil/vue-output-target": "^0.8.6",
"@types/jest": "^27.5.2",
"@stencil/vue-output-target": "^0.8.7",
"@types/jest": "^29.5.6",
"@types/node": "^14.6.0",
"@typescript-eslint/eslint-plugin": "^6.7.2",
"@typescript-eslint/parser": "^6.7.2",
@@ -62,8 +61,8 @@
"eslint-plugin-custom-rules": "file:custom-rules",
"execa": "^5.0.0",
"fs-extra": "^9.0.1",
"jest": "^27.5.1",
"jest-cli": "^27.5.1",
"jest": "^29.7.0",
"jest-cli": "^29.7.0",
"prettier": "^2.6.1",
"rollup": "^2.26.4",
"sass": "^1.33.0",

View File

@@ -180,6 +180,16 @@ export class AccordionGroup implements ComponentInterface {
if (this.readonly) {
this.readonlyChanged();
}
/**
* When binding values in frameworks such as Angular
* it is possible for the value to be set after the Web Component
* initializes but before the value watcher is set up in Stencil.
* As a result, the watcher callback may not be fired.
* We work around this by manually calling the watcher
* callback when the component has loaded and the watcher
* is configured.
*/
this.valueChanged();
}
/**

View File

@@ -128,8 +128,8 @@
height: 100%;
/* Fallback for browsers that do not support dvh */
max-height: 100vh;
max-height: 100dvh;
max-height: calc(100vh - (var(--ion-safe-area-top, 0) + var(--ion-safe-area-bottom, 0)));
max-height: calc(100dvh - (var(--ion-safe-area-top, 0) + var(--ion-safe-area-bottom, 0)));
}
.action-sheet-group {

View File

@@ -100,3 +100,69 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ config, title }) =>
});
});
});
/**
* This behavior needs to be tested in both modes but does not vary
* across directions due to the component only applying safe area
* to the top and bottom
*/
configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
test.describe(title('action-sheet: basic'), () => {
test.describe('safe area', () => {
test('should have padding added by the safe area', async ({ page }, testInfo) => {
testInfo.annotations.push({
type: 'issue',
description: 'https://github.com/ionic-team/ionic-framework/issues/27777',
});
await page.setContent(
`
<style>
:root {
--ion-safe-area-top: 60px;
--ion-safe-area-bottom: 40px;
}
</style>
<ion-action-sheet></ion-action-sheet>
<script>
const actionSheet = document.querySelector('ion-action-sheet');
actionSheet.header = 'Header';
actionSheet.subHeader = 'Sub Header';
actionSheet.buttons = [
'Add Reaction',
'Copy Text',
'Share Text',
'Copy Link to Message',
'Remind Me',
'Pin File',
'Star File',
'Mark Unread',
'Mark Read',
'Edit Title',
'Erase Title',
'Save Image',
'Copy Image',
'Erase Image',
'Delete File',
{
text: 'Cancel',
role: 'cancel'
},
];
</script>
`,
config
);
const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
const actionSheet = page.locator('ion-action-sheet');
await actionSheet.evaluate((el: HTMLIonActionSheetElement) => el.present());
await ionActionSheetDidPresent.next();
await expect(actionSheet).toHaveScreenshot(screenshot(`action-sheet-safe-area`));
});
});
});
});

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -136,7 +136,3 @@
justify-content: flex-end;
}
:host .datetime-view-buttons ion-button {
color: $text-color-step-200;
}

View File

@@ -130,7 +130,10 @@
* 2. This will only apply when that content has a collapse header (ion-header[collapse="condense"])
*
* We use opacity: 0 to avoid a layout shift.
* We target both the attribute and the class in the event that the attribute
* is not reflected on the host in some frameworks.
*/
ion-header:not(.header-collapse-main):has(~ ion-content ion-header[collapse="condense"]) {
ion-header:not(.header-collapse-main):has(~ ion-content ion-header[collapse="condense"],
~ ion-content ion-header.header-collapse-condense) {
opacity: 0;
}

View File

@@ -31,12 +31,19 @@
@include font-smoothing();
@include margin(0);
@include padding(
var(--padding-top),
var(--padding-end),
var(--padding-bottom),
calc(var(--padding-start) + var(--ion-safe-area-left, 0px))
);
@include padding(var(--padding-top), null, var(--padding-bottom), null);
/* stylelint-disable */
@include ltr() {
padding-right: var(--padding-end);
padding-left: calc(var(--padding-start) + var(--ion-safe-area-left, 0px));
}
@include rtl() {
padding-right: calc(var(--padding-start) + var(--ion-safe-area-right, 0px));
padding-left: var(--padding-end);
}
/* stylelint-enable */
display: flex;
@@ -67,12 +74,19 @@
.item-divider-inner {
@include margin(0);
@include padding(
var(--inner-padding-top),
calc(var(--ion-safe-area-right, 0px) + var(--inner-padding-end)),
var(--inner-padding-bottom),
var(--inner-padding-start)
);
@include padding(var(--inner-padding-top), null, var(--inner-padding-bottom), null);
/* stylelint-disable */
@include ltr() {
padding-right: calc(var(--ion-safe-area-right, 0px) + var(--inner-padding-end));
padding-left: var(--inner-padding-start);
}
@include rtl() {
padding-right: var(--inner-padding-start);
padding-left: calc(var(--ion-safe-area-left, 0px) + var(--inner-padding-end));
}
/* stylelint-enable */
display: flex;

View File

@@ -46,5 +46,33 @@ configs().forEach(({ title, screenshot, config }) => {
const divider = page.locator('ion-item-divider');
await expect(divider).toHaveScreenshot(screenshot(`item-divider-icon-start`));
});
/**
* This behavior needs to be tested for all modes & directions
* Safe padding should stay on the same side when the direction changes
*/
test('should have safe area padding', async ({ page }) => {
await page.setContent(
`
<style>
:root {
--ion-safe-area-left: 40px;
--ion-safe-area-right: 20px;
}
</style>
<ion-list>
<ion-item-divider>
<ion-label>Item Divider</ion-label>
<ion-button slot="end">Button</ion-button>
</ion-item-divider>
</ion-list>
`,
config
);
const list = page.locator('ion-list');
await expect(list).toHaveScreenshot(screenshot('item-divider-safe-area'));
});
});
});

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -52,7 +52,16 @@ export class RadioGroup implements ComponentInterface {
@Event() ionValueChange!: EventEmitter<RadioGroupChangeEventDetail>;
componentDidLoad() {
this.setRadioTabindex(this.value);
/**
* There's an issue when assigning a value to the radio group
* within the Angular primary content (rendering within the
* app component template). When the template is isolated to a route,
* the value is assigned correctly.
* To address this issue, we need to ensure that the watcher is
* called after the component has finished loading,
* allowing the emit to be dispatched correctly.
*/
this.valueChanged(this.value);
}
private setRadioTabindex = (value: any | undefined) => {

View File

@@ -34,7 +34,13 @@
// -----------------------------------------
.searchbar-cancel-button {
@include position(0, null, null, 5px);
/**
* The left edge of the cancel button
* should align with the left edge
* of the back button if the searchbar
* is used in a toolbar.
*/
@include position(0, null, null, 9px);
background-color: $searchbar-md-cancel-button-background-color;

View File

@@ -25,7 +25,7 @@ $searchbar-md-cancel-button-color: $text-color-step-100 !default;
$searchbar-md-cancel-button-background-color: transparent !default;
/// @prop - Font size of the searchbar cancel button
$searchbar-md-cancel-button-font-size: 1.6em !default;
$searchbar-md-cancel-button-font-size: 1.5em !default;
/// @prop - Color of the searchbar input search icon
$searchbar-md-input-search-icon-color: $text-color-step-400 !default;

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -198,3 +198,33 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, screenshot, c
});
});
});
configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
test.describe(title('searchbar: cancel button alignment'), () => {
test('should align with the back button when used in a toolbar', async ({ page }, testInfo) => {
testInfo.annotations.push({
type: 'issue',
description: 'https://github.com/ionic-team/ionic-framework/issues/28468',
});
await page.setContent(
`
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button default-href="#"></ion-back-button>
</ion-buttons>
<ion-title>Test</ion-title>
</ion-toolbar>
<ion-toolbar>
<ion-searchbar show-cancel-button="always"></ion-searchbar>
</ion-toolbar>
</ion-header>
`,
config
);
const header = page.locator('ion-header');
await expect(header).toHaveScreenshot(screenshot(`searchbar-back-button-align`));
});
});
});

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 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.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

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.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -197,20 +197,17 @@ export const config: Config = {
{
elements: ['ion-checkbox', 'ion-toggle'],
targetAttr: 'checked',
event: 'v-ion-change',
externalEvent: 'ionChange'
event: 'ion-change'
},
{
elements: ['ion-datetime', 'ion-radio-group', 'ion-radio', 'ion-range', 'ion-segment', 'ion-segment-button', 'ion-select', 'ion-accordion-group'],
targetAttr: 'value',
event: 'v-ion-change',
externalEvent: 'ionChange'
event: 'ion-change',
},
{
elements: ['ion-input', 'ion-searchbar', 'ion-textarea'],
targetAttr: 'value',
event: 'v-ion-input',
externalEvent: 'ionInput'
event: 'ion-input',
}
],
}),

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [7.5.5](https://github.com/ionic-team/ionic-framework/compare/v7.5.4...v7.5.5) (2023-11-15)
**Note:** Version bump only for package @ionic/docs
## [7.5.4](https://github.com/ionic-team/ionic-framework/compare/v7.5.3...v7.5.4) (2023-11-08)
**Note:** Version bump only for package @ionic/docs

View File

@@ -1,12 +1,12 @@
{
"name": "@ionic/docs",
"version": "7.5.4",
"version": "7.5.5",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@ionic/docs",
"version": "7.5.4",
"version": "7.5.5",
"license": "MIT"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/docs",
"version": "7.5.4",
"version": "7.5.5",
"description": "Pre-packaged API documentation for the Ionic docs.",
"main": "core.json",
"types": "core.d.ts",

View File

@@ -4,5 +4,5 @@
"docs",
"packages/*"
],
"version": "7.5.4"
"version": "7.5.5"
}

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [7.5.5](https://github.com/ionic-team/ionic-framework/compare/v7.5.4...v7.5.5) (2023-11-15)
**Note:** Version bump only for package @ionic/angular-server
## [7.5.4](https://github.com/ionic-team/ionic-framework/compare/v7.5.3...v7.5.4) (2023-11-08)
**Note:** Version bump only for package @ionic/angular-server

View File

@@ -1,15 +1,15 @@
{
"name": "@ionic/angular-server",
"version": "7.5.4",
"version": "7.5.5",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@ionic/angular-server",
"version": "7.5.4",
"version": "7.5.5",
"license": "MIT",
"dependencies": {
"@ionic/core": "^7.5.4"
"@ionic/core": "^7.5.5"
},
"devDependencies": {
"@angular-eslint/eslint-plugin": "^14.0.0",
@@ -1060,11 +1060,11 @@
"dev": true
},
"node_modules/@ionic/core": {
"version": "7.5.3",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.3.tgz",
"integrity": "sha512-nd4NV6gSgohLvKHGmf+jAcgzI1387eKq3enjBfE574FK/ikl5CeIltv0MBVJr9lz0pNSL/y9m1tdaFg+syASuA==",
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.5.tgz",
"integrity": "sha512-7Rn3OUz8QCob7yMuCLs5dVLpChscNCm+OqH8lqTzy3N/8VSKHLNPHIHTIa4DQm9HwjtpOB+XCTeIqbdWHkLgnA==",
"dependencies": {
"@stencil/core": "^4.6.0",
"@stencil/core": "^4.7.2",
"ionicons": "^7.2.1",
"tslib": "^2.1.0"
}
@@ -1462,9 +1462,9 @@
"license": "MIT"
},
"node_modules/@stencil/core": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.6.0.tgz",
"integrity": "sha512-5Y6/fP28aspPDRB+Tz5GuB1jRVGuUEk5/rnyE8ACGcuzEOG+zR0A/IHRJSU3XmCxUlVDKfKoO6St5W84oUCVMA==",
"version": "4.7.2",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.7.2.tgz",
"integrity": "sha512-sPPDYrXiTbfeUF5CCyfqysXK/yfTHC4xYR1+nHzGkS2vhRSBOLp0oPuB+xkJLKA+K2ZqDJUxpOnDxy1CLWwBXA==",
"bin": {
"stencil": "bin/stencil"
},
@@ -7330,11 +7330,11 @@
"dev": true
},
"@ionic/core": {
"version": "7.5.3",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.3.tgz",
"integrity": "sha512-nd4NV6gSgohLvKHGmf+jAcgzI1387eKq3enjBfE574FK/ikl5CeIltv0MBVJr9lz0pNSL/y9m1tdaFg+syASuA==",
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.5.tgz",
"integrity": "sha512-7Rn3OUz8QCob7yMuCLs5dVLpChscNCm+OqH8lqTzy3N/8VSKHLNPHIHTIa4DQm9HwjtpOB+XCTeIqbdWHkLgnA==",
"requires": {
"@stencil/core": "^4.6.0",
"@stencil/core": "^4.7.2",
"ionicons": "^7.2.1",
"tslib": "^2.1.0"
}
@@ -7581,9 +7581,9 @@
}
},
"@stencil/core": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.6.0.tgz",
"integrity": "sha512-5Y6/fP28aspPDRB+Tz5GuB1jRVGuUEk5/rnyE8ACGcuzEOG+zR0A/IHRJSU3XmCxUlVDKfKoO6St5W84oUCVMA=="
"version": "4.7.2",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.7.2.tgz",
"integrity": "sha512-sPPDYrXiTbfeUF5CCyfqysXK/yfTHC4xYR1+nHzGkS2vhRSBOLp0oPuB+xkJLKA+K2ZqDJUxpOnDxy1CLWwBXA=="
},
"@types/estree": {
"version": "0.0.39",

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/angular-server",
"version": "7.5.4",
"version": "7.5.5",
"description": "Angular SSR Module for Ionic",
"keywords": [
"ionic",
@@ -27,6 +27,7 @@
"test": "echo 'angular no tests yet'",
"build": "ng-packagr -p ng-package.json -c tsconfig.json",
"build.prod": "npm run clean && npm run build",
"build.watch": "npm run build -- --watch",
"clean": "rm -rf ./dist",
"lint": "eslint . --ext .ts && npm run prettier",
"lint.fix": "eslint . --ext .ts --fix && npm run prettier.fix",
@@ -61,6 +62,6 @@
},
"prettier": "@ionic/prettier-config",
"dependencies": {
"@ionic/core": "^7.5.4"
"@ionic/core": "^7.5.5"
}
}

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [7.5.5](https://github.com/ionic-team/ionic-framework/compare/v7.5.4...v7.5.5) (2023-11-15)
**Note:** Version bump only for package @ionic/angular
## [7.5.4](https://github.com/ionic-team/ionic-framework/compare/v7.5.3...v7.5.4) (2023-11-08)
**Note:** Version bump only for package @ionic/angular

View File

@@ -1,14 +1,7 @@
export { ActionSheetController } from './providers/action-sheet-controller';
export { AlertController } from './providers/alert-controller';
export { LoadingController } from './providers/loading-controller';
export { MenuController } from './providers/menu-controller';
export { ModalController } from './providers/modal-controller';
export { PickerController } from './providers/picker-controller';
export { PopoverController } from './providers/popover-controller';
export { ToastController } from './providers/toast-controller';
export { AnimationController } from './providers/animation-controller';
export { GestureController } from './providers/gesture-controller';
export { DomController } from './providers/dom-controller';
export { NavController } from './providers/nav-controller';
@@ -39,5 +32,6 @@ export * from './directives/control-value-accessors';
export { ProxyCmp } from './utils/proxy';
export { IonicRouteStrategy } from './utils/routing';
export { OverlayBaseController } from './utils/overlay';
export { raf } from './utils/util';

View File

@@ -1,6 +1,6 @@
// TODO(FW-2827): types
interface ControllerShape<Opts, HTMLElm> {
export interface ControllerShape<Opts, HTMLElm> {
create(options: Opts): Promise<HTMLElm>;
dismiss(data?: any, role?: string, id?: string): Promise<boolean>;
getTop(): Promise<HTMLElm | undefined>;

View File

@@ -1,15 +1,15 @@
{
"name": "@ionic/angular",
"version": "7.5.4",
"version": "7.5.5",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@ionic/angular",
"version": "7.5.4",
"version": "7.5.5",
"license": "MIT",
"dependencies": {
"@ionic/core": "^7.5.4",
"@ionic/core": "^7.5.5",
"ionicons": "^7.0.0",
"jsonc-parser": "^3.0.0",
"tslib": "^2.3.0"
@@ -1227,11 +1227,11 @@
"dev": true
},
"node_modules/@ionic/core": {
"version": "7.5.3",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.3.tgz",
"integrity": "sha512-nd4NV6gSgohLvKHGmf+jAcgzI1387eKq3enjBfE574FK/ikl5CeIltv0MBVJr9lz0pNSL/y9m1tdaFg+syASuA==",
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.5.tgz",
"integrity": "sha512-7Rn3OUz8QCob7yMuCLs5dVLpChscNCm+OqH8lqTzy3N/8VSKHLNPHIHTIa4DQm9HwjtpOB+XCTeIqbdWHkLgnA==",
"dependencies": {
"@stencil/core": "^4.6.0",
"@stencil/core": "^4.7.2",
"ionicons": "^7.2.1",
"tslib": "^2.1.0"
}
@@ -1583,9 +1583,9 @@
}
},
"node_modules/@stencil/core": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.6.0.tgz",
"integrity": "sha512-5Y6/fP28aspPDRB+Tz5GuB1jRVGuUEk5/rnyE8ACGcuzEOG+zR0A/IHRJSU3XmCxUlVDKfKoO6St5W84oUCVMA==",
"version": "4.7.2",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.7.2.tgz",
"integrity": "sha512-sPPDYrXiTbfeUF5CCyfqysXK/yfTHC4xYR1+nHzGkS2vhRSBOLp0oPuB+xkJLKA+K2ZqDJUxpOnDxy1CLWwBXA==",
"bin": {
"stencil": "bin/stencil"
},
@@ -8093,11 +8093,11 @@
"dev": true
},
"@ionic/core": {
"version": "7.5.3",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.3.tgz",
"integrity": "sha512-nd4NV6gSgohLvKHGmf+jAcgzI1387eKq3enjBfE574FK/ikl5CeIltv0MBVJr9lz0pNSL/y9m1tdaFg+syASuA==",
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.5.5.tgz",
"integrity": "sha512-7Rn3OUz8QCob7yMuCLs5dVLpChscNCm+OqH8lqTzy3N/8VSKHLNPHIHTIa4DQm9HwjtpOB+XCTeIqbdWHkLgnA==",
"requires": {
"@stencil/core": "^4.6.0",
"@stencil/core": "^4.7.2",
"ionicons": "^7.2.1",
"tslib": "^2.1.0"
}
@@ -8327,9 +8327,9 @@
}
},
"@stencil/core": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.6.0.tgz",
"integrity": "sha512-5Y6/fP28aspPDRB+Tz5GuB1jRVGuUEk5/rnyE8ACGcuzEOG+zR0A/IHRJSU3XmCxUlVDKfKoO6St5W84oUCVMA=="
"version": "4.7.2",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.7.2.tgz",
"integrity": "sha512-sPPDYrXiTbfeUF5CCyfqysXK/yfTHC4xYR1+nHzGkS2vhRSBOLp0oPuB+xkJLKA+K2ZqDJUxpOnDxy1CLWwBXA=="
},
"@types/estree": {
"version": "0.0.39",

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/angular",
"version": "7.5.4",
"version": "7.5.5",
"description": "Angular specific wrappers for @ionic/core",
"keywords": [
"ionic",
@@ -28,6 +28,7 @@
"build.core": "node scripts/build-core.js",
"build.link": "npm run build && node scripts/link-copy.js",
"build.ng": "ng-packagr -p ng-package.json -c tsconfig.json",
"build.watch": "npm run build.ng -- --watch",
"clean": "node scripts/clean.js",
"clean-generated": "node ./scripts/clean-generated.js",
"lint": "npm run eslint && npm run prettier -- --write --cache",
@@ -47,7 +48,7 @@
}
},
"dependencies": {
"@ionic/core": "^7.5.4",
"@ionic/core": "^7.5.5",
"ionicons": "^7.0.0",
"jsonc-parser": "^3.0.0",
"tslib": "^2.3.0"

View File

@@ -20,15 +20,9 @@ export * from './directives/validators';
// PROVIDERS
export {
ActionSheetController,
AlertController,
LoadingController,
ModalController,
PickerController,
PopoverController,
ToastController,
AnimationController,
GestureController,
DomController,
NavController,
Config,
@@ -41,7 +35,13 @@ export {
ViewDidEnter,
ViewDidLeave,
} from '@ionic/angular/common';
export { AnimationController } from './providers/animation-controller';
export { ActionSheetController } from './providers/action-sheet-controller';
export { GestureController } from './providers/gesture-controller';
export { MenuController } from './providers/menu-controller';
export { ModalController } from './providers/modal-controller';
export { PopoverController } from './providers/popover-controller';
export { ToastController } from './providers/toast-controller';
// PACKAGE MODULE
export { IonicModule } from './ionic-module';

View File

@@ -1,12 +1,6 @@
import { CommonModule, DOCUMENT } from '@angular/common';
import { ModuleWithProviders, APP_INITIALIZER, NgModule, NgZone } from '@angular/core';
import {
ModalController,
PopoverController,
ConfigToken,
AngularDelegate,
provideComponentInputBinding,
} from '@ionic/angular/common';
import { ConfigToken, AngularDelegate, provideComponentInputBinding } from '@ionic/angular/common';
import { IonicConfig } from '@ionic/core';
import { appInitialize } from './app-initialize';
@@ -29,6 +23,8 @@ import { IonModal } from './directives/overlays/modal';
import { IonPopover } from './directives/overlays/popover';
import { DIRECTIVES } from './directives/proxies-list';
import { IonMaxValidator, IonMinValidator } from './directives/validators';
import { ModalController } from './providers/modal-controller';
import { PopoverController } from './providers/popover-controller';
const DECLARATIONS = [
// generated proxies

View File

@@ -0,0 +1,13 @@
import { Injectable } from '@angular/core';
import { OverlayBaseController } from '@ionic/angular/common';
import type { ActionSheetOptions } from '@ionic/core';
import { actionSheetController } from '@ionic/core';
@Injectable({
providedIn: 'root',
})
export class ActionSheetController extends OverlayBaseController<ActionSheetOptions, HTMLIonActionSheetElement> {
constructor() {
super(actionSheetController);
}
}

View File

@@ -0,0 +1,33 @@
import { Injectable } from '@angular/core';
import { createAnimation, getTimeGivenProgression } from '@ionic/core';
import type { Animation } from '@ionic/core';
@Injectable({
providedIn: 'root',
})
export class AnimationController {
/**
* Create a new animation
*/
create(animationId?: string): Animation {
return createAnimation(animationId);
}
/**
* EXPERIMENTAL
*
* Given a progression and a cubic bezier function,
* this utility returns the time value(s) at which the
* cubic bezier reaches the given time progression.
*
* If the cubic bezier never reaches the progression
* the result will be an empty array.
*
* This is most useful for switching between easing curves
* when doing a gesture animation (i.e. going from linear easing
* during a drag, to another easing when `progressEnd` is called)
*/
easingTime(p0: number[], p1: number[], p2: number[], p3: number[], progression: number): number[] {
return getTimeGivenProgression(p0, p1, p2, p3, progression);
}
}

View File

@@ -0,0 +1,25 @@
import { Injectable, NgZone } from '@angular/core';
import type { Gesture, GestureConfig } from '@ionic/core';
import { createGesture } from '@ionic/core';
@Injectable({
providedIn: 'root',
})
export class GestureController {
constructor(private zone: NgZone) {}
/**
* Create a new gesture
*/
create(opts: GestureConfig, runInsideAngularZone = false): Gesture {
if (runInsideAngularZone) {
Object.getOwnPropertyNames(opts).forEach((key) => {
if (typeof opts[key] === 'function') {
const fn = opts[key];
opts[key] = (...props: any[]) => this.zone.run(() => fn(...props));
}
});
}
return createGesture(opts);
}
}

View File

@@ -0,0 +1,22 @@
import { Injector, Injectable, EnvironmentInjector, inject } from '@angular/core';
import { AngularDelegate, OverlayBaseController } from '@ionic/angular/common';
import type { ModalOptions } from '@ionic/core';
import { modalController } from '@ionic/core';
@Injectable()
export class ModalController extends OverlayBaseController<ModalOptions, HTMLIonModalElement> {
private angularDelegate = inject(AngularDelegate);
private injector = inject(Injector);
private environmentInjector = inject(EnvironmentInjector);
constructor() {
super(modalController);
}
create(opts: ModalOptions): Promise<HTMLIonModalElement> {
return super.create({
...opts,
delegate: this.angularDelegate.create(this.environmentInjector, this.injector, 'modal'),
});
}
}

View File

@@ -0,0 +1,21 @@
import { Injector, inject, EnvironmentInjector } from '@angular/core';
import { AngularDelegate, OverlayBaseController } from '@ionic/angular/common';
import type { PopoverOptions } from '@ionic/core';
import { popoverController } from '@ionic/core';
export class PopoverController extends OverlayBaseController<PopoverOptions, HTMLIonPopoverElement> {
private angularDelegate = inject(AngularDelegate);
private injector = inject(Injector);
private environmentInjector = inject(EnvironmentInjector);
constructor() {
super(popoverController);
}
create(opts: PopoverOptions): Promise<HTMLIonPopoverElement> {
return super.create({
...opts,
delegate: this.angularDelegate.create(this.environmentInjector, this.injector, 'popover'),
});
}
}

View File

@@ -0,0 +1,13 @@
import { Injectable } from '@angular/core';
import { OverlayBaseController } from '@ionic/angular/common';
import type { ToastOptions } from '@ionic/core';
import { toastController } from '@ionic/core';
@Injectable({
providedIn: 'root',
})
export class ToastController extends OverlayBaseController<ToastOptions, HTMLIonToastElement> {
constructor() {
super(toastController);
}
}

View File

@@ -5,17 +5,17 @@ export { IonRouterOutlet } from './navigation/router-outlet';
export { IonRouterLink, IonRouterLinkWithHref } from './navigation/router-link-delegate';
export { IonTabs } from './navigation/tabs';
export { provideIonicAngular } from './providers/ionic-angular';
export { ActionSheetController } from './providers/action-sheet-controller';
export { AnimationController } from './providers/animation-controller';
export { GestureController } from './providers/gesture-controller';
export { MenuController } from './providers/menu-controller';
export { ModalController } from './providers/modal-controller';
export { PopoverController } from './providers/popover-controller';
export { ToastController } from './providers/toast-controller';
export {
ActionSheetController,
AlertController,
LoadingController,
ModalController,
PickerController,
PopoverController,
ToastController,
AnimationController,
GestureController,
DomController,
NavController,
Config,

View File

@@ -1,9 +1,8 @@
import { Injectable } from '@angular/core';
import { OverlayBaseController } from '@ionic/angular/common';
import type { ActionSheetOptions } from '@ionic/core/components';
import { actionSheetController } from '@ionic/core/components';
import { OverlayBaseController } from '../utils/overlay';
@Injectable({
providedIn: 'root',
})

View File

@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import type { Animation } from '@ionic/core/components';
import type { Animation } from '@ionic/core';
import { createAnimation, getTimeGivenProgression } from '@ionic/core/components';
@Injectable({

View File

@@ -1,4 +1,4 @@
import { NgZone, Injectable } from '@angular/core';
import { Injectable, NgZone } from '@angular/core';
import type { Gesture, GestureConfig } from '@ionic/core/components';
import { createGesture } from '@ionic/core/components';

View File

@@ -1,16 +1,13 @@
import { DOCUMENT } from '@angular/common';
import { APP_INITIALIZER } from '@angular/core';
import type { Provider } from '@angular/core';
import {
AngularDelegate,
ConfigToken,
ModalController,
PopoverController,
provideComponentInputBinding,
} from '@ionic/angular/common';
import { AngularDelegate, ConfigToken, provideComponentInputBinding } from '@ionic/angular/common';
import { initialize } from '@ionic/core/components';
import type { IonicConfig } from '@ionic/core/components';
import { ModalController } from './modal-controller';
import { PopoverController } from './popover-controller';
export const provideIonicAngular = (config?: IonicConfig): Provider[] => {
/**
* TODO FW-4967

View File

@@ -1,11 +1,8 @@
import { Injector, Injectable, EnvironmentInjector, inject } from '@angular/core';
import { AngularDelegate, OverlayBaseController } from '@ionic/angular/common';
import type { ModalOptions } from '@ionic/core/components';
import { modalController } from '@ionic/core/components';
import { OverlayBaseController } from '../utils/overlay';
import { AngularDelegate } from './angular-delegate';
@Injectable()
export class ModalController extends OverlayBaseController<ModalOptions, HTMLIonModalElement> {
private angularDelegate = inject(AngularDelegate);

View File

@@ -1,12 +1,8 @@
import { Injector, Injectable, inject, EnvironmentInjector } from '@angular/core';
import { Injector, inject, EnvironmentInjector } from '@angular/core';
import { AngularDelegate, OverlayBaseController } from '@ionic/angular/common';
import type { PopoverOptions } from '@ionic/core/components';
import { popoverController } from '@ionic/core/components';
import { OverlayBaseController } from '../utils/overlay';
import { AngularDelegate } from './angular-delegate';
@Injectable()
export class PopoverController extends OverlayBaseController<PopoverOptions, HTMLIonPopoverElement> {
private angularDelegate = inject(AngularDelegate);
private injector = inject(Injector);

View File

@@ -1,9 +1,8 @@
import { Injectable } from '@angular/core';
import { OverlayBaseController } from '@ionic/angular/common';
import type { ToastOptions } from '@ionic/core/components';
import { toastController } from '@ionic/core/components';
import { OverlayBaseController } from '../utils/overlay';
@Injectable({
providedIn: 'root',
})

View File

@@ -0,0 +1,156 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"test-app": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/test-app/browser",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"buildOptimizer": true,
"assets": [
"src/favicon.ico",
{
"glob": "**/*",
"input": "src/assets",
"output": "assets"
},
{
"glob": "**/*.svg",
"input": "node_modules/ionicons/dist/ionicons/svg",
"output": "./svg"
}
],
"styles": ["src/styles.css"],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"aot": true,
"progress": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb"
}
]
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"buildTarget": "test-app:build"
},
"configurations": {
"production": {
"buildTarget": "test-app:build:production"
},
"development": {
"buildTarget": "test-app:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"buildTarget": "test-app:build"
}
},
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
}
},
"server": {
"builder": "@angular-devkit/build-angular:server",
"options": {
"outputPath": "dist/test-app/server",
"main": "server.ts",
"tsConfig": "tsconfig.server.json"
},
"configurations": {
"production": {
"outputHashing": "media",
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"sourceMap": false,
"optimization": true
}
}
},
"serve-ssr": {
"builder": "@angular-devkit/build-angular:ssr-dev-server",
"options": {
"browserTarget": "test-app:build",
"serverTarget": "test-app:server"
},
"configurations": {
"production": {
"browserTarget": "test-app:build:production",
"serverTarget": "test-app:server:production"
}
}
},
"prerender": {
"builder": "@angular-devkit/build-angular:prerender",
"options": {
"browserTarget": "test-app:build:production",
"serverTarget": "test-app:server:production",
"routes": []
}
}
}
}
},
"cli": {
"schematicCollections": ["@angular-eslint/schematics"],
"cache": {
"enabled": false
}
}
}

View File

View File

@@ -0,0 +1,5 @@
it("should be on Angular 17", () => {
cy.visit('/lazy');
cy.get('ion-title').contains('Angular 17');
});

View File

@@ -0,0 +1,8 @@
it("binding route data to inputs should work", () => {
cy.visit('/lazy/version-test/bind-route/test?query=test');
cy.get('#route-params').contains('test');
cy.get('#query-params').contains('test');
cy.get('#data').contains('data:bindToComponentInputs');
cy.get('#resolve').contains('resolve:bindToComponentInputs');
});

View File

@@ -0,0 +1,20 @@
describe('Modal Nav Params', () => {
beforeEach(() => {
cy.visit('/lazy/version-test/modal-nav-params');
});
it('should assign the rootParams when presented in a modal multiple times', () => {
cy.contains('Open Modal').click();
cy.get('ion-modal').should('exist').should('be.visible');
cy.get('ion-modal').contains('OK');
cy.contains("Close").click();
cy.get('ion-modal').should('not.be.visible');
cy.contains('Open Modal').click();
cy.get('ion-modal').should('exist').should('be.visible');
cy.get('ion-modal').contains('OK').should('exist');
});
});

View File

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,69 @@
{
"name": "ionic-angular-test-app",
"version": "0.0.0",
"private": true,
"scripts": {
"ng": "ng",
"start": "ng serve",
"sync:build": "sh scripts/build-ionic.sh",
"sync": "sh scripts/sync.sh",
"build": "ng build --configuration production --no-progress",
"lint": "ng lint",
"serve:ssr": "node dist/test-app/server/main.js",
"build:ssr": "ng build --prod && ng run test-app:server:production",
"dev:ssr": "ng run test-app:serve-ssr",
"prerender": "ng run test-app:prerender",
"cy.open": "cypress open",
"cy.run": "cypress run",
"test": "concurrently \"npm run start -- --configuration production\" \"wait-on http-get://localhost:4200 && npm run cy.run\" --kill-others --success first",
"test.watch": "concurrently \"npm run start\" \"wait-on http-get://localhost:4200 && npm run cy.open\" --kill-others --success first"
},
"dependencies": {
"@angular/animations": "^17.0.2",
"@angular/common": "^17.0.2",
"@angular/compiler": "^17.0.2",
"@angular/core": "^17.0.2",
"@angular/forms": "^17.0.2",
"@angular/platform-browser": "^17.0.2",
"@angular/platform-browser-dynamic": "^17.0.2",
"@angular/platform-server": "^17.0.2",
"@angular/router": "^17.0.2",
"@angular/ssr": "^17.0.0",
"@ionic/angular": "^7.0.0",
"@ionic/angular-server": "^7.0.0",
"core-js": "^3.33.2",
"express": "^4.15.2",
"ionicons": "^7.2.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"typescript-eslint-language-service": "^4.1.5",
"zone.js": "~0.14.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "^17.0.0",
"@angular-eslint/builder": "^17.0.0",
"@angular-eslint/eslint-plugin": "^17.0.0",
"@angular-eslint/eslint-plugin-template": "^17.0.0",
"@angular-eslint/schematics": "^17.0.0",
"@angular-eslint/template-parser": "^17.0.0",
"@angular/cli": "^17.0.0",
"@angular/compiler-cli": "^17.0.2",
"@angular/language-service": "^17.0.2",
"@types/express": "^4.17.7",
"@types/ws": "8.5.3",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"concurrently": "^6.0.0",
"cypress": "^13.2.0",
"eslint": "^7.26.0",
"ts-loader": "^6.2.2",
"ts-node": "^8.3.0",
"typescript": "~5.2.2",
"wait-on": "^5.2.1",
"webpack": "^5.61.0",
"webpack-cli": "^4.9.2"
},
"engines": {
"node": ">= 18"
}
}

View File

@@ -0,0 +1,71 @@
import 'zone.js/node';
import { APP_BASE_HREF } from '@angular/common';
import { CommonEngine } from '@angular/ssr';
import * as express from 'express';
import { existsSync } from 'node:fs';
import { join } from 'node:path';
import bootstrap from './src/main.server';
// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
const distFolder = join(process.cwd(), 'dist/test-app/browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html'))
? join(distFolder, 'index.original.html')
: join(distFolder, 'index.html');
const commonEngine = new CommonEngine();
server.set('view engine', 'html');
server.set('views', distFolder);
// Example Express Rest API endpoints
// server.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.get('*.*', express.static(distFolder, {
maxAge: '1y'
}));
// All regular routes use the Angular engine
server.get('*', (req, res, next) => {
const { protocol, originalUrl, baseUrl, headers } = req;
commonEngine
.render({
bootstrap,
documentFilePath: indexHtml,
url: `${protocol}://${headers.host}${originalUrl}`,
publicPath: distFolder,
providers: [
{ provide: APP_BASE_HREF, useValue: baseUrl },],
})
.then((html) => res.send(html))
.catch((err) => next(err));
});
return server;
}
function run(): void {
const port = process.env['PORT'] || 4000;
// Start up the Node server
const server = app();
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
run();
}
export default bootstrap;

View File

@@ -0,0 +1,10 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { routes } from './app.routes';
@NgModule({
imports: [RouterModule.forRoot(routes, { bindToComponentInputs: true })],
exports: [RouterModule]
})
export class AppRoutingModule { }

View File

@@ -0,0 +1,41 @@
import { Component, Input, OnInit } from "@angular/core";
import { IonicModule } from '@ionic/angular';
@Component({
selector: 'app-bind-route',
template: `
<ion-header>
<ion-toolbar>
<ion-title>bindToComponentInputs</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<div>
<h3>Bind Route</h3>
<p id="route-params">Route params: id: {{id}}</p>
<p id="query-params">Query params: query: {{query}}</p>
<p id="data">Data: title: {{title}}</p>
<p id="resolve">Resolve: name: {{name}}</p>
</div>
</ion-content>
`,
standalone: true,
imports: [IonicModule]
})
export class BindComponentInputsComponent implements OnInit {
@Input() id?: string; // path parameter
@Input() query?: string; // query parameter
@Input() title?: string; // data property
@Input() name?: string; // resolve property
ngOnInit(): void {
console.log('BindComponentInputsComponent.ngOnInit', {
id: this.id,
query: this.query,
title: this.title,
name: this.name
});
}
}

View File

@@ -0,0 +1,45 @@
import { Component } from "@angular/core";
import { IonicModule } from "@ionic/angular";
import { NavRootComponent } from "./nav-root.component";
@Component({
selector: 'app-modal-nav-params',
template: `
<ion-header>
<ion-toolbar>
<ion-title>Modal Nav Params</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-button id="open">Open Modal</ion-button>
<ion-modal #modal trigger="open">
<ng-template>
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-button (click)="modal.dismiss()">Close</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-nav [root]="root" [rootParams]="rootParams"></ion-nav>
</ion-content>
</ng-template>
</ion-modal>
</ion-content>
`,
standalone: true,
imports: [IonicModule, NavRootComponent]
})
export class ModalNavParamsComponent {
root = NavRootComponent;
rootParams = {
params: {
id: 123
}
};
}

View File

@@ -0,0 +1,38 @@
import { JsonPipe } from "@angular/common";
import { Component } from "@angular/core";
import { IonicModule } from "@ionic/angular";
/**
* This is used to track if any occurences of
* the ion-nav root component being attached to
* the DOM result in the rootParams not being
* assigned to the component instance.
*
* https://github.com/ionic-team/ionic-framework/issues/27146
*/
let rootParamsException = false;
@Component({
selector: 'app-modal-content',
template: `
{{ hasException ? 'ERROR' : 'OK' }}
`,
standalone: true,
imports: [IonicModule, JsonPipe]
})
export class NavRootComponent {
params: any;
ngOnInit() {
if (this.params === undefined) {
rootParamsException = true;
}
}
get hasException() {
return rootParamsException;
}
}

View File

@@ -0,0 +1,25 @@
import { NgModule } from "@angular/core";
import { RouterModule } from "@angular/router";
@NgModule({
imports: [
RouterModule.forChild([
{
path: 'modal-nav-params',
loadComponent: () => import('./modal-nav-params/modal-nav-params.component').then(m => m.ModalNavParamsComponent),
},
{
path: 'bind-route/:id',
data: {
title: 'data:bindToComponentInputs'
},
resolve: {
name: () => 'resolve:bindToComponentInputs'
},
loadComponent: () => import('./bind-component-inputs/bind-component-inputs.component').then(c => c.BindComponentInputsComponent)
}
])
],
exports: [RouterModule]
})
export class VersionTestRoutingModule { }

View File

@@ -0,0 +1,35 @@
{
"compileOnSave": false,
"compilerOptions": {
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": false,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "ES2022",
"module": "ES2022",
"emitDecoratorMetadata": true,
"typeRoots": ["node_modules/@types"],
"lib": ["ES2022", "dom"],
"plugins": [
{
"name": "typescript-eslint-language-service"
}
],
"useDefineForClassFields": false
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}

View File

@@ -41,11 +41,21 @@ Cypress.Commands.add('ionSwipeToGoBack', (complete = false, selector = 'ion-rout
cy.wait(150);
});
/**
* getStack is a query because it has automatic
* retries built in which will let us account for
* async routing without having to use
* arbitrary cy.wait calls.
*/
Cypress.Commands.addQuery('getStack', (selector) => {
return () => {
const el = cy.$$(selector);
return Array.from(el.children()).map((el) => el.tagName.toLowerCase());
}
});
Cypress.Commands.add('testStack', (selector, expected) => {
cy.document().then((doc) => {
const children = Array.from(doc.querySelector(selector).children).map((el) => el.tagName.toLowerCase());
expect(children).to.deep.equal(expected);
});
cy.getStack(selector).should('deep.equal', expected);
});
Cypress.Commands.add('testLifeCycle', (selector, expected) => {

View File

@@ -1,11 +1,9 @@
describe('Navigation', () => {
beforeEach(() => {
cy.visit('/lazy/navigation');
cy.visit('/lazy/navigation/page1?ionic:_testing=true');
})
it('should navigate correctly', () => {
cy.visit('/lazy/navigation/page1');
cy.wait(2000);
cy.testStack('ion-router-outlet', ['app-navigation-page2', 'app-navigation-page1']);
cy.get('app-navigation-page2').should('have.attr', 'aria-hidden').and('equal', 'true');

View File

@@ -1,6 +1,6 @@
describe('Nested Outlet', () => {
beforeEach(() => {
cy.visit('/lazy/nested-outlet/page');
cy.visit('/lazy/nested-outlet/page?ionic:_testing=true');
})
it('should navigate correctly', () => {

View File

@@ -33,5 +33,11 @@ describe('Providers', () => {
cy.get('#set-menu-count').click();
cy.get('#registered-menu-count').should('have.text', '1');
});
it('should open an action sheet', () => {
cy.get('button#open-action-sheet').click();
cy.get('ion-action-sheet').should('be.visible');
});
});

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