Compare commits

..

1 Commits

Author SHA1 Message Date
Brandy Smith
408065aa84 fix(list): migrate to scoped 2025-07-02 14:11:12 -04:00
502 changed files with 30553 additions and 19701 deletions

View File

@@ -56,6 +56,14 @@ closeAndLock:
bug reports and feature requests. Please use our [forum](https://forum.ionicframework.com) for questions about the framework.
Thank you for using Ionic!
- label: "ionitron: appflow"
message: >
Thanks for the issue! This issue appears to be related to Ionic Appflow. We use this issue tracker exclusively for
bug reports and feature requests. Please use the [Ionic Appflow Support Forum](https://ionic.zendesk.com/hc/en-us/requests/new)
to report this issue.
Thank you for using Ionic!
- label: "ionitron: missing template"
message: >
@@ -137,6 +145,65 @@ noReproduction:
lock: true
dryRun: false
wrongRepo:
repos:
- label: "ionitron: capacitor"
repo: capacitor
message: >
Thanks for the issue! We use this issue tracker exclusively for bug reports and feature requests
associated with the Ionic Framework. It appears that this issue is associated with Capacitor.
I am moving this issue to the Capacitor repository. Please track this issue over there.
Thank you for using Ionic!
- label: "ionitron: v3"
repo: ionic-v3
message: >
Thanks for the issue! We have moved the source code and issues for Ionic 3 into a separate repository.
I am moving this issue to the repository for Ionic 3. Please track this issue over there.
Thank you for using Ionic!
- label: "ionitron: cli"
repo: ionic-cli
message: >
Thanks for the issue! We use this issue tracker exclusively for bug reports and feature requests
associated with the Ionic Framework. It appears that this issue is associated with the Ionic CLI.
I am moving this issue to the Ionic CLI repository. Please track this issue over there.
Thank you for using Ionic!
- label: "ionitron: docs"
repo: ionic-docs
message: >
Thanks for the issue! We use this issue tracker exclusively for bug reports and feature requests
associated with the Ionic Framework. It appears that this issue is associated with the Ionic Documentation.
I am moving this issue to the Ionic Docs repository. Please track this issue over there.
Thank you for using Ionic!
- label: "ionitron: stencil"
repo: stencil
message: >
Thanks for the issue! We use this issue tracker exclusively for bug reports and feature requests
associated with the Ionic Framework. It appears that this issue is associated with Stencil.
I am moving this issue to the Stencil repository. Please track this issue over there.
Thank you for using Ionic!
- label: "ionitron: native"
repo: ionic-native
message: >
Thanks for the issue! We use this issue tracker exclusively for bug reports and feature requests
associated with the Ionic Framework. It appears that this issue is associated with Ionic Native.
I am moving this issue to the Ionic Native repository. Please track this issue over there.
Thank you for using Ionic!
close: true
lock: true
dryRun: false
screenshot:
appId: 18001
checkName: "build"

View File

@@ -3,23 +3,23 @@ description: 'Build Ionic Angular Server'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
- uses: actions/setup-node@v4
with:
node-version: 24.x
node-version: 22.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core
path: ./core
filename: CoreBuild.zip
- name: 🕸️ Install Angular Server Dependencies
- name: Install Angular Server Dependencies
run: npm ci
shell: bash
working-directory: ./packages/angular-server
- name: 🔄 Sync
- name: Sync
run: npm run sync
shell: bash
working-directory: ./packages/angular-server
- name: 🏗️ Build
- name: Build
run: npm run build.prod
shell: bash
working-directory: ./packages/angular-server

View File

@@ -3,31 +3,31 @@ description: 'Build Ionic Angular'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v6
- uses: actions/setup-node@v4
with:
node-version: 24.x
node-version: 22.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core
path: ./core
filename: CoreBuild.zip
- name: 🕸️ Install Angular Dependencies
- name: Install Angular Dependencies
run: npm ci
shell: bash
working-directory: ./packages/angular
- name: 🔄 Sync
- name: Sync
run: npm run sync
shell: bash
working-directory: ./packages/angular
- name: 🖌️ Lint
- name: Lint
run: npm run lint
shell: bash
working-directory: ./packages/angular
- name: 🏗️ Build
- name: Build
run: npm run build
shell: bash
working-directory: ./packages/angular
- name: 🔍 Check Diff
- name: Check Diff
run: git diff --exit-code
shell: bash
working-directory: ./packages/angular

View File

@@ -8,20 +8,20 @@ inputs:
runs:
using: 'composite'
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24.x
node-version: 22.x
- name: 🕸️ Install Dependencies
- name: Install Dependencies
run: npm ci
working-directory: ./core
shell: bash
- name: 📦 Install Stencil ${{ inputs.stencil-version }}
- name: Install Stencil ${{ inputs.stencil-version }}
working-directory: ./core
run: npm i @stencil/core@${{ inputs.stencil-version }}
shell: bash
- name: 🏗️ Build Core
- name: Build Core
run: npm run build -- --ci --debug --verbose
working-directory: ./core
shell: bash

View File

@@ -8,22 +8,22 @@ inputs:
runs:
using: 'composite'
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24.x
- name: 🕸️ Install Dependencies
node-version: 22.x
- name: Install Dependencies
run: npm install
working-directory: ./core
shell: bash
# If an Ionicons version was specified install that.
# Otherwise just use the version defined in the package.json.
- name: 📦 Install Ionicons Version
- name: Install Ionicons Version
if: inputs.ionicons-version != ''
run: npm install ionicons@${{ inputs.ionicons-version }}
working-directory: ./core
shell: bash
- name: 🏗️ Build Core
- name: Build Core
run: npm run build -- --ci
working-directory: ./core
shell: bash
@@ -31,6 +31,4 @@ runs:
with:
name: ionic-core
output: core/CoreBuild.zip
# Include generated proxy files from Stencil output targets so
# framework builds can detect when they need to be updated
paths: core/dist core/components core/css core/hydrate core/loader core/src/components.d.ts core/api.txt packages/angular/src/directives/proxies.ts packages/angular/src/directives/proxies-list.ts packages/angular/standalone/src/directives/proxies.ts packages/vue/src/proxies.ts packages/react/src/components/proxies.ts packages/react/src/components/inner-proxies.ts packages/react/src/components/routing-proxies.ts
paths: core/dist core/components core/css core/hydrate core/loader core/src/components.d.ts core/api.txt

View File

@@ -3,9 +3,9 @@ description: 'Build Ionic React Router'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
- uses: actions/setup-node@v4
with:
node-version: 24.x
node-version: 22.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core
@@ -16,19 +16,19 @@ runs:
name: ionic-react
path: ./packages/react
filename: ReactBuild.zip
- name: 🕸️ Install Dependencies
- name: Install Dependencies
run: npm ci
shell: bash
working-directory: ./packages/react-router
- name: 🔄 Sync
- name: Sync
run: npm run sync
shell: bash
working-directory: ./packages/react-router
- name: 🖌️ Lint
- name: Lint
run: npm run lint
shell: bash
working-directory: ./packages/react-router
- name: 🏗️ Build
- name: Build
run: npm run build
shell: bash
working-directory: ./packages/react-router

View File

@@ -3,35 +3,35 @@ description: 'Build Ionic React'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
- uses: actions/setup-node@v4
with:
node-version: 24.x
node-version: 22.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core
path: ./core
filename: CoreBuild.zip
- name: 🕸️ Install React Dependencies
- name: Install React Dependencies
run: npm ci
shell: bash
working-directory: ./packages/react
- name: 🔄 Sync
- name: Sync
run: npm run sync
shell: bash
working-directory: ./packages/react
- name: 🖌️ Lint
- name: Lint
run: npm run lint
shell: bash
working-directory: ./packages/react
- name: 🏗️ Build
- name: Build
run: npm run build
shell: bash
working-directory: ./packages/react
- name: 🧪 Test Spec
- name: Test Spec
run: npm run test.spec
shell: bash
working-directory: ./packages/react
- name: 🔍 Check Diff
- name: Check Diff
run: git diff --exit-code
shell: bash
working-directory: ./packages/react

View File

@@ -3,9 +3,9 @@ description: 'Builds Ionic Vue Router'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
- uses: actions/setup-node@v4
with:
node-version: 24.x
node-version: 22.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core
@@ -16,23 +16,23 @@ runs:
name: ionic-vue
path: ./packages/vue
filename: VueBuild.zip
- name: 🕸️ Install Vue Router Dependencies
- name: Install Vue Router Dependencies
run: npm ci
shell: bash
working-directory: ./packages/vue-router
- name: 🔄 Sync
- name: Sync
run: npm run sync
shell: bash
working-directory: ./packages/vue-router
- name: 🖌️ Lint
- name: Lint
run: npm run lint
shell: bash
working-directory: ./packages/vue-router
- name: 🏗️ Build
- name: Build
run: npm run build
shell: bash
working-directory: ./packages/vue-router
- name: 🧪 Test Spec
- name: Test Spec
run: npm run test.spec
shell: bash
working-directory: ./packages/vue-router

View File

@@ -3,31 +3,31 @@ description: 'Build Ionic Vue'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
- uses: actions/setup-node@v4
with:
node-version: 24.x
node-version: 22.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core
path: ./core
filename: CoreBuild.zip
- name: 🕸️ Install Vue Dependencies
- name: Install Vue Dependencies
run: npm ci
shell: bash
working-directory: ./packages/vue
- name: 🔄 Sync
- name: Sync
run: npm run sync
shell: bash
working-directory: ./packages/vue
- name: 🖌️ Lint
- name: Lint
run: npm run lint
shell: bash
working-directory: ./packages/vue
- name: 🏗️ Build
- name: Build
run: npm run build
shell: bash
working-directory: ./packages/vue
- name: 🔍 Check Diff
- name: Check Diff
run: git diff --exit-code
shell: bash
working-directory: ./packages/vue

View File

@@ -10,10 +10,10 @@ inputs:
runs:
using: 'composite'
steps:
- uses: actions/download-artifact@v6
- uses: actions/download-artifact@v4
with:
name: ${{ inputs.name }}
path: ${{ inputs.path }}
- name: 🔎 Extract Archive
- name: Extract Archive
run: unzip -q -o ${{ inputs.path }}/${{ inputs.filename }}
shell: bash

View File

@@ -8,51 +8,48 @@ inputs:
tag:
description: 'The tag to publish to on NPM.'
preid:
description: "Prerelease identifier such as 'alpha', 'beta', 'rc', or 'next'. Leave blank to skip prerelease tagging."
description: 'The prerelease identifier used when doing a prerelease.'
working-directory:
description: 'The directory of the package.'
folder:
default: './'
description: 'A folder containing a package.json file.'
node-version:
description: 'Node.js version to use when publishing.'
required: false
default: '24.x'
token:
description: 'The NPM authentication token required to publish.'
runs:
using: 'composite'
steps:
- name: 🟢 Configure Node for Publish
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
registry-url: 'https://registry.npmjs.org'
node-version: 22.x
# Provenance requires npm 9.5.0+
- name: 📦 Install latest npm
- name: Install latest npm
run: npm install -g npm@latest
shell: bash
# This ensures the local version of Lerna is installed
# and that we do not use the global Lerna version
- name: 🕸️ Install root dependencies
- name: Install root dependencies
run: npm ci
shell: bash
- name: 📦 Install Dependencies
- name: Install Dependencies
run: npx lerna@5 bootstrap --include-dependencies --scope ${{ inputs.scope }} --ignore-scripts -- --legacy-peer-deps
shell: bash
working-directory: ${{ inputs.working-directory }}
- name: 🏷️ Set Version
run: |
if [ -z "${{ inputs.preid }}" ]; then
npx lerna@5 version ${{ inputs.version }} --yes --exact --no-changelog --no-push --no-git-tag-version
else
npx lerna@5 version ${{ inputs.version }} --yes --exact --no-changelog --no-push --no-git-tag-version --preid=${{ inputs.preid }}
fi
- name: Update Version
run: npx lerna@5 version ${{ inputs.version }} --yes --exact --no-changelog --no-push --no-git-tag-version --preid=${{ inputs.preid }}
shell: bash
working-directory: ${{ inputs.working-directory }}
- name: 🏗️ Run Build
- name: Run Build
run: npm run build
shell: bash
working-directory: ${{ inputs.working-directory }}
- name: 🚀 Publish to NPM
- name: Prepare NPM Token
run: echo //registry.npmjs.org/:_authToken=${NPM_TOKEN} > .npmrc
working-directory: ${{ inputs.working-directory }}
shell: bash
env:
NPM_TOKEN: ${{ inputs.token }}
- name: Publish to NPM
run: npm publish ${{ inputs.folder }} --tag ${{ inputs.tag }} --provenance
shell: bash
working-directory: ${{ inputs.working-directory }}

View File

@@ -6,9 +6,9 @@ inputs:
runs:
using: 'composite'
steps:
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
- uses: actions/setup-node@v4
with:
node-version: 24.x
node-version: 22.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core
@@ -24,23 +24,19 @@ runs:
name: ionic-angular-server
path: ./packages/angular-server
filename: AngularServerBuild.zip
- name: 🧪 Create Test App
- name: Create Test App
run: ./build.sh ${{ inputs.app }}
shell: bash
working-directory: ./packages/angular/test
- name: 🕸️ Install Dependencies
- name: Install Dependencies
run: npm install
shell: bash
working-directory: ./packages/angular/test/build/${{ inputs.app }}
- name: 📦 Install Playwright Browsers
run: npx playwright install
shell: bash
working-directory: ./packages/angular/test/build/${{ inputs.app }}
- name: 🔄 Sync Built Changes
- name: Sync Built Changes
run: npm run sync
shell: bash
working-directory: ./packages/angular/test/build/${{ inputs.app }}
- name: 🧪 Run Tests
- name: Run Tests
run: npm run test
shell: bash
working-directory: ./packages/angular/test/build/${{ inputs.app }}

View File

@@ -3,16 +3,16 @@ description: 'Test Core Clean Build'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
- uses: actions/setup-node@v4
with:
node-version: 24.x
node-version: 22.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core
path: ./core
filename: CoreBuild.zip
- name: 🔍 Check Diff
- name: Check Diff
run: |
git diff --exit-code || {
echo -e "\033[1;31m⚠ Error: Differences Detected ⚠️\033[0m"

View File

@@ -3,21 +3,21 @@ description: 'Test Core Lint'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
- uses: actions/setup-node@v4
with:
node-version: 24.x
- name: 🕸️ Install Dependencies
node-version: 22.x
- name: Install Dependencies
run: npm ci
working-directory: ./core
shell: bash
- name: 🖌️ Lint
- name: Lint
run: npm run lint
shell: bash
working-directory: ./core
# Lint changes should be pushed
# to the branch before the branch
# is merge eligible.
- name: 🔎 Check Lint Results
- name: Check Lint Results
run: git diff --exit-code
shell: bash
working-directory: ./core

View File

@@ -13,19 +13,19 @@ inputs:
runs:
using: 'composite'
steps:
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
- uses: actions/setup-node@v4
with:
node-version: 24.x
node-version: 22.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core
path: ./core
filename: CoreBuild.zip
- name: 🕸️ Install Dependencies
- name: Install Dependencies
run: npm install
shell: bash
working-directory: ./core
- name: 🧪 Test
- name: Test
if: inputs.update != 'true'
run: npm run test.e2e.docker.ci ${{ inputs.component }} -- --shard=${{ inputs.shard }}/${{ inputs.totalShards }}
shell: bash
@@ -60,13 +60,13 @@ runs:
fi
shell: bash
working-directory: ./core
- name: 📦 Archive Updated Screenshots
- name: Archive Updated Screenshots
if: inputs.update == 'true' && steps.test-and-update.outputs.hasUpdatedScreenshots == 'true'
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v4
with:
name: updated-screenshots-${{ inputs.shard }}-${{ inputs.totalShards }}
path: UpdatedScreenshots-${{ inputs.shard }}-${{ inputs.totalShards }}.zip
- name: 📦 Archive Test Results
- name: Archive Test Results
# The always() ensures that this step
# runs even if the previous step fails.
# We want the test results to be archived

View File

@@ -6,14 +6,14 @@ inputs:
runs:
using: 'composite'
steps:
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
- uses: actions/setup-node@v4
with:
node-version: 24.x
- name: 🕸️ Install Dependencies
node-version: 22.x
- name: Install Dependencies
run: npm ci
working-directory: ./core
shell: bash
- name: 📦 Install Stencil ${{ inputs.stencil-version }}
- name: Install Stencil ${{ inputs.stencil-version }}
run: npm install @stencil/core@${{ inputs.stencil-version }}
shell: bash
working-directory: ./core
@@ -23,7 +23,7 @@ runs:
name: ionic-core
path: ./core
filename: CoreBuild.zip
- name: 🧪 Test
- name: Test
run: npm run test.spec -- --ci
shell: bash
working-directory: ./core

View File

@@ -6,9 +6,9 @@ inputs:
runs:
using: 'composite'
steps:
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
- uses: actions/setup-node@v4
with:
node-version: 24.x
node-version: 22.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core
@@ -24,23 +24,23 @@ runs:
name: ionic-react-router
path: ./packages/react-router
filename: ReactRouterBuild.zip
- name: 🧪 Create Test App
- name: Create Test App
run: ./build.sh ${{ inputs.app }}
shell: bash
working-directory: ./packages/react/test
- name: 🕸️ Install Dependencies
- name: Install Dependencies
run: npm install
shell: bash
working-directory: ./packages/react/test/build/${{ inputs.app }}
- name: 🔄 Sync Built Changes
- name: Sync Built Changes
run: npm run sync
shell: bash
working-directory: ./packages/react/test/build/${{ inputs.app }}
- name: 🏗️ Build
- name: Build
run: npm run build
shell: bash
working-directory: ./packages/react/test/build/${{ inputs.app }}
- name: 🧪 Run Tests
- name: Run Tests
run: npm run e2e
shell: bash
working-directory: ./packages/react/test/build/${{ inputs.app }}

View File

@@ -6,9 +6,9 @@ inputs:
runs:
using: 'composite'
steps:
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
- uses: actions/setup-node@v4
with:
node-version: 24.x
node-version: 22.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core
@@ -24,23 +24,23 @@ runs:
name: ionic-react-router
path: ./packages/react-router
filename: ReactRouterBuild.zip
- name: 🧪 Create Test App
- name: Create Test App
run: ./build.sh ${{ inputs.app }}
shell: bash
working-directory: ./packages/react-router/test
- name: 🕸️ Install Dependencies
- name: Install Dependencies
run: npm install
shell: bash
working-directory: ./packages/react-router/test/build/${{ inputs.app }}
- name: 🔄 Sync Built Changes
- name: Sync Built Changes
run: npm run sync
shell: bash
working-directory: ./packages/react-router/test/build/${{ inputs.app }}
- name: 🏗️ Build
- name: Build
run: npm run build
shell: bash
working-directory: ./packages/react-router/test/build/${{ inputs.app }}
- name: 🧪 Run Tests
- name: Run Tests
run: npm run e2e
shell: bash
working-directory: ./packages/react-router/test/build/${{ inputs.app }}

View File

@@ -6,9 +6,9 @@ inputs:
runs:
using: 'composite'
steps:
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
- uses: actions/setup-node@v4
with:
node-version: 24.x
node-version: 22.x
- uses: ./.github/workflows/actions/download-archive
with:
name: ionic-core
@@ -24,23 +24,23 @@ runs:
name: ionic-vue-router
path: ./packages/vue-router
filename: VueRouterBuild.zip
- name: 🧪 Create Test App
- name: Create Test App
run: ./build.sh ${{ inputs.app }}
shell: bash
working-directory: ./packages/vue/test
- name: 📦 Install Dependencies
- name: Install Dependencies
run: npm install
shell: bash
working-directory: ./packages/vue/test/build/${{ inputs.app }}
- name: 🔄 Sync
- name: Sync
run: npm run sync
shell: bash
working-directory: ./packages/vue/test/build/${{ inputs.app }}
- name: 🧪 Run Spec Tests
- name: Run Spec Tests
run: npm run test:unit
shell: bash
working-directory: ./packages/vue/test/build/${{ inputs.app }}
- name: 🧪 Run E2E Tests
- name: Run E2E Tests
run: npm run test:e2e
shell: bash
working-directory: ./packages/vue/test/build/${{ inputs.app }}

View File

@@ -7,13 +7,13 @@ on:
runs:
using: 'composite'
steps:
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
- uses: actions/setup-node@v4
with:
node-version: 24.x
- uses: actions/download-artifact@v6
node-version: 22.x
- uses: actions/download-artifact@v4
with:
path: ./artifacts
- name: 🔎 Extract Archives
- name: Extract Archives
# This finds all .zip files in the ./artifacts
# directory, including nested directories.
# It then unzips every .zip to the root directory
@@ -21,7 +21,7 @@ runs:
find . -type f -name 'UpdatedScreenshots-*.zip' -exec unzip -q -o -d ../ {} \;
shell: bash
working-directory: ./artifacts
- name: 📸 Push Screenshots
- name: Push Screenshots
# Configure user as Ionitron
# and push only the changed .png snapshots
# to the remote branch.

View File

@@ -10,10 +10,10 @@ inputs:
runs:
using: 'composite'
steps:
- name: 🗄️ Create Archive
- name: Create Archive
run: zip -q -r ${{ inputs.output }} ${{ inputs.paths }}
shell: bash
- uses: actions/upload-artifact@v5
- uses: actions/upload-artifact@v4
with:
name: ${{ inputs.name }}
path: ${{ inputs.output }}

View File

@@ -22,7 +22,7 @@ jobs:
build-core:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-core
with:
ionicons-version: ${{ inputs.ionicons_npm_release_tag }}
@@ -31,21 +31,21 @@ jobs:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-core-clean-build
test-core-lint:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-core-lint
test-core-spec:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-core-spec
test-core-screenshot:
@@ -62,7 +62,7 @@ jobs:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-core-screenshot
with:
shard: ${{ matrix.shard }}
@@ -90,14 +90,14 @@ jobs:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-vue
build-vue-router:
needs: [build-vue]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-vue-router
test-vue-e2e:
@@ -108,7 +108,7 @@ jobs:
needs: [build-vue, build-vue-router]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-vue-e2e
with:
app: ${{ matrix.apps }}
@@ -126,14 +126,14 @@ jobs:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-angular
build-angular-server:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-angular-server
test-angular-e2e:
@@ -144,7 +144,7 @@ jobs:
needs: [build-angular, build-angular-server]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-angular-e2e
with:
app: ${{ matrix.apps }}
@@ -162,14 +162,14 @@ jobs:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-react
build-react-router:
needs: [build-react]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-react-router
test-react-router-e2e:
@@ -180,7 +180,7 @@ jobs:
needs: [build-react, build-react-router]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-react-router-e2e
with:
app: ${{ matrix.apps }}
@@ -202,7 +202,7 @@ jobs:
needs: [build-react, build-react-router]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-react-e2e
with:
app: ${{ matrix.apps }}

View File

@@ -14,8 +14,8 @@ jobs:
permissions:
security-events: write
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: github/codeql-action/init@v4
- uses: actions/checkout@v4
- uses: github/codeql-action/init@v3
with:
languages: javascript
- uses: github/codeql-action/analyze@v4
- uses: github/codeql-action/analyze@v3

View File

@@ -9,35 +9,24 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Validate PR title
if: |
!contains(github.event.pull_request.title, 'release') &&
!contains(github.event.pull_request.title, 'chore')
uses: amannn/action-semantic-pull-request@v6
uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
# Configure that a scope must always be provided.
requireScope: true
# Configure allowed commit types
types: |
feat
fix
docs
style
refactor
perf
test
build
ci
revert
release
chore
# Configure additional validation for the subject based on a regex.
# This example ensures the subject doesn't start with an uppercase character.
subjectPattern: ^(?![A-Z]).+$
# If `subjectPattern` is configured, you can use this property to
# override the default error message that is shown when the pattern
# doesn't match. The variables `subject` and `title` can be used
# If `subjectPattern` is configured, you can use this property to
# override the default error message that is shown when the pattern
# doesn't match. The variables `subject` and `title` can be used
# within the message.
subjectPatternError: |
The subject "{subject}" found in the pull request title "{title}" didn't match the configured pattern. Please ensure that the subject doesn't start with an uppercase character.
# If the PR contains one of these newline-delimited labels, the
# validation is skipped. If you want to rerun the validation when
# labels change, you might want to use the `labeled` and `unlabeled`
# event triggers in your workflow.
ignoreLabels: |
release

View File

@@ -9,7 +9,7 @@ jobs:
outputs:
dev-hash: ${{ steps.create-dev-hash.outputs.DEV_HASH }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
# A 1 is required before the timestamp
# as lerna will fail when there is a leading 0
# See https://github.com/lerna/lerna/issues/2840
@@ -30,6 +30,8 @@ jobs:
with:
tag: dev
version: ${{ needs.create-dev-hash.outputs.dev-hash }}
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
get-build:
name: Get your dev build!

View File

@@ -13,7 +13,7 @@ jobs:
triage:
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v6
- uses: actions/labeler@v5
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
sync-labels: true

View File

@@ -12,7 +12,7 @@ jobs:
outputs:
nightly-hash: ${{ steps.create-nightly-hash.outputs.NIGHTLY_HASH }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
# A 1 is required before the timestamp
# as lerna will fail when there is a leading 0
# See https://github.com/lerna/lerna/issues/2840
@@ -35,3 +35,5 @@ jobs:
with:
tag: nightly
version: ${{ needs.create-nightly-hash.outputs.nightly-hash }}
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@@ -14,16 +14,15 @@ on:
preid:
description: 'The prerelease identifier used when doing a prerelease.'
type: string
permissions:
contents: read
id-token: write
secrets:
NPM_TOKEN:
required: true
jobs:
release-core:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/publish-npm
with:
scope: '@ionic/core'
@@ -31,6 +30,7 @@ jobs:
version: ${{ inputs.version }}
preid: ${{ inputs.preid }}
working-directory: 'core'
token: ${{ secrets.NPM_TOKEN }}
- name: Cache Built @ionic/core
uses: ./.github/workflows/actions/upload-archive
with:
@@ -48,7 +48,7 @@ jobs:
needs: [release-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- name: Restore @ionic/docs built cache
uses: ./.github/workflows/actions/download-archive
with:
@@ -62,12 +62,13 @@ jobs:
version: ${{ inputs.version }}
preid: ${{ inputs.preid }}
working-directory: 'packages/docs'
token: ${{ secrets.NPM_TOKEN }}
release-angular:
needs: [release-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- name: Restore @ionic/core built cache
uses: ./.github/workflows/actions/download-archive
with:
@@ -82,6 +83,7 @@ jobs:
preid: ${{ inputs.preid }}
working-directory: 'packages/angular'
folder: './dist'
token: ${{ secrets.NPM_TOKEN }}
- name: Cache Built @ionic/angular
uses: ./.github/workflows/actions/upload-archive
with:
@@ -93,7 +95,7 @@ jobs:
needs: [release-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- name: Restore @ionic/core built cache
uses: ./.github/workflows/actions/download-archive
with:
@@ -107,6 +109,7 @@ jobs:
version: ${{ inputs.version }}
preid: ${{ inputs.preid }}
working-directory: 'packages/react'
token: ${{ secrets.NPM_TOKEN }}
- name: Cache Built @ionic/react
uses: ./.github/workflows/actions/upload-archive
with:
@@ -118,7 +121,7 @@ jobs:
needs: [release-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- name: Restore @ionic/core built cache
uses: ./.github/workflows/actions/download-archive
with:
@@ -132,6 +135,7 @@ jobs:
version: ${{ inputs.version }}
preid: ${{ inputs.preid }}
working-directory: 'packages/vue'
token: ${{ secrets.NPM_TOKEN }}
- name: Cache Built @ionic/vue
uses: ./.github/workflows/actions/upload-archive
with:
@@ -143,7 +147,7 @@ jobs:
needs: [release-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- name: Restore @ionic/core built cache
uses: ./.github/workflows/actions/download-archive
with:
@@ -158,12 +162,13 @@ jobs:
preid: ${{ inputs.preid }}
working-directory: 'packages/angular-server'
folder: './dist'
token: ${{ secrets.NPM_TOKEN }}
release-react-router:
needs: [release-react]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- name: Restore @ionic/core built cache
uses: ./.github/workflows/actions/download-archive
with:
@@ -183,12 +188,13 @@ jobs:
version: ${{ inputs.version }}
preid: ${{ inputs.preid }}
working-directory: 'packages/react-router'
token: ${{ secrets.NPM_TOKEN }}
release-vue-router:
needs: [release-vue]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- name: Restore @ionic/core built cache
uses: ./.github/workflows/actions/download-archive
with:
@@ -208,3 +214,4 @@ jobs:
version: ${{ inputs.version }}
preid: ${{ inputs.preid }}
working-directory: 'packages/vue-router'
token: ${{ secrets.NPM_TOKEN }}

View File

@@ -25,7 +25,6 @@ on:
preid:
type: choice
description: Which prerelease identifier should be used? This is only needed when version is "prepatch", "preminor", "premajor", or "prerelease".
default: ''
options:
- ''
- alpha
@@ -36,19 +35,20 @@ on:
jobs:
release-ionic:
permissions:
contents: read
id-token: write
uses: ./.github/workflows/release-ionic.yml
with:
tag: ${{ inputs.tag }}
version: ${{ inputs.version }}
preid: ${{ inputs.preid }}
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
finalize-release:
needs: [release-ionic]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
with:
token: ${{ secrets.IONITRON_TOKEN }}
fetch-depth: 0
@@ -76,7 +76,7 @@ jobs:
needs: [finalize-release]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
# Pull the latest version of the reference
# branch instead of the revision that triggered
# the workflow otherwise we won't get the commit

View File

@@ -26,7 +26,7 @@ jobs:
build-core-with-stencil-nightly:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-core-stencil-prerelease
with:
stencil-version: ${{ inputs.npm_release_tag || 'nightly' }}
@@ -35,21 +35,21 @@ jobs:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-core-clean-build
test-core-lint:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-core-lint
test-core-spec:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-core-spec
with:
stencil-version: ${{ inputs.npm_release_tag || 'nightly' }}
@@ -72,7 +72,7 @@ jobs:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-core-screenshot
with:
shard: ${{ matrix.shard }}
@@ -100,14 +100,14 @@ jobs:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-vue
build-vue-router:
needs: [build-vue]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-vue-router
test-vue-e2e:
@@ -118,7 +118,7 @@ jobs:
needs: [build-vue, build-vue-router]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-vue-e2e
with:
app: ${{ matrix.apps }}
@@ -136,14 +136,14 @@ jobs:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-angular
build-angular-server:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-angular-server
test-angular-e2e:
@@ -154,7 +154,7 @@ jobs:
needs: [build-angular, build-angular-server]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-angular-e2e
with:
app: ${{ matrix.apps }}
@@ -172,14 +172,14 @@ jobs:
needs: [build-core-with-stencil-nightly]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-react
build-react-router:
needs: [build-react]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-react-router
test-react-router-e2e:
@@ -190,7 +190,7 @@ jobs:
needs: [build-react, build-react-router]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-react-router-e2e
with:
app: ${{ matrix.apps }}
@@ -212,7 +212,7 @@ jobs:
needs: [build-react, build-react-router]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-react-e2e
with:
app: ${{ matrix.apps }}
@@ -225,35 +225,3 @@ jobs:
- name: Check build matrix status
if: ${{ needs.test-react-e2e.result != 'success' }}
run: exit 1
send-success-messages:
needs: [test-core-clean-build, test-core-lint, test-core-spec, verify-screenshots, verify-test-vue-e2e, verify-test-angular-e2e, verify-test-react-router-e2e, verify-test-react-e2e]
runs-on: ubuntu-latest
if: ${{ !cancelled() && contains(needs.*.result, 'success') }}
steps:
- name: Notify success on Discord
run: |
curl -H "Content-Type:application/json" \
-d '{"embeds": [{"title": "✅ Workflow ${{github.workflow}} #${{github.run_number}} finished successfully", "color": 65280, "url": "${{github.server_url}}/${{github.repository}}/actions/runs/${{github.run_id}}"}]}' \
${{secrets.DISCORD_NOTIFY_WEBHOOK}}
- name: Notify success on Slack
run: |
curl -H "Content-Type:application/json" \
-d '{"title": "✅ Workflow ${{github.workflow}} #${{github.run_number}} finished successfully", "url": "${{github.server_url}}/${{github.repository}}/actions/runs/${{github.run_id}}"}' \
${{secrets.SLACK_NOTIFY_SUCCESS_WEBHOOK}}
send-failure-messages:
needs: [test-core-clean-build, test-core-lint, test-core-spec, verify-screenshots, verify-test-vue-e2e, verify-test-angular-e2e, verify-test-react-router-e2e, verify-test-react-e2e]
runs-on: ubuntu-latest
if: ${{ !cancelled() && contains(needs.*.result, 'failure') }}
steps:
- name: Notify failure on Discord
run: |
curl -H "Content-Type:application/json" \
-d '{"content": "Alerting <@&1347593178580254761>!", "embeds": [{"title": "❌ Workflow ${{github.workflow}} #${{github.run_number}} failed", "color": 16711680, "url": "${{github.server_url}}/${{github.repository}}/actions/runs/${{github.run_id}}"}]}' \
${{secrets.DISCORD_NOTIFY_WEBHOOK}}
- name: Notify failure on Slack
run: |
curl -H "Content-Type:application/json" \
-d '{"title": "❌ Workflow ${{github.workflow}} #${{github.run_number}} failed", "url": "${{github.server_url}}/${{github.repository}}/actions/runs/${{github.run_id}}"}' \
${{secrets.SLACK_NOTIFY_FAILURE_WEBHOOK}}

View File

@@ -26,7 +26,7 @@ jobs:
build-core:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/build-core
test-core-screenshot:
@@ -47,7 +47,7 @@ jobs:
needs: [build-core]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
- uses: ./.github/workflows/actions/test-core-screenshot
with:
shard: ${{ matrix.shard }}
@@ -59,7 +59,7 @@ jobs:
runs-on: ubuntu-latest
needs: [test-core-screenshot]
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@v4
# Normally, we could just push with the
# default GITHUB_TOKEN, but that will
# not cause the build workflow

View File

@@ -3,189 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [8.7.9](https://github.com/ionic-team/ionic-framework/compare/v8.7.8...v8.7.9) (2025-11-05)
### Bug Fixes
* **accordion-group:** skip initial animation ([#30729](https://github.com/ionic-team/ionic-framework/issues/30729)) ([58d5638](https://github.com/ionic-team/ionic-framework/commit/58d563805fca1db88caeeb40a8f710ac30416d93)), closes [#30613](https://github.com/ionic-team/ionic-framework/issues/30613)
## [8.7.8](https://github.com/ionic-team/ionic-framework/compare/v8.7.7...v8.7.8) (2025-10-29)
### Bug Fixes
* **checkbox, toggle:** fire ionFocus and ionBlur ([#30733](https://github.com/ionic-team/ionic-framework/issues/30733)) ([54a1c86](https://github.com/ionic-team/ionic-framework/commit/54a1c86d6a5d533b0c8c2d18edc62454a7c17bab))
## [8.7.7](https://github.com/ionic-team/ionic-framework/compare/v8.7.6...v8.7.7) (2025-10-15)
### Bug Fixes
* **header:** ensure one banner role in condensed header ([#30718](https://github.com/ionic-team/ionic-framework/issues/30718)) ([12084af](https://github.com/ionic-team/ionic-framework/commit/12084af163ed811b9c6bda3c7850fc0c53c60c7b))
* **header:** prevent flickering during iOS page transitions ([#30705](https://github.com/ionic-team/ionic-framework/issues/30705)) ([820fa28](https://github.com/ionic-team/ionic-framework/commit/820fa2854331722d22efd0e38a1936117477967a)), closes [#25326](https://github.com/ionic-team/ionic-framework/issues/25326)
* **select:** improve screen reader announcement timing for validation errors ([#30723](https://github.com/ionic-team/ionic-framework/issues/30723)) ([03303d7](https://github.com/ionic-team/ionic-framework/commit/03303d73f0bfe2380ced7931525fc52fd8576367))
## [8.7.6](https://github.com/ionic-team/ionic-framework/compare/v8.7.5...v8.7.6) (2025-10-08)
### Bug Fixes
* **tabs:** respect stencil lifecycle order for tab selection ([#30702](https://github.com/ionic-team/ionic-framework/issues/30702)) ([7bb9535](https://github.com/ionic-team/ionic-framework/commit/7bb9535f601d2469ce60687a9c03f8b1cfe4aba4)), closes [#30611](https://github.com/ionic-team/ionic-framework/issues/30611)
## [8.7.5](https://github.com/ionic-team/ionic-framework/compare/v8.7.4...v8.7.5) (2025-09-24)
### Bug Fixes
* **modal:** allow sheet modals to skip focus trap ([#30689](https://github.com/ionic-team/ionic-framework/issues/30689)) ([a40d957](https://github.com/ionic-team/ionic-framework/commit/a40d957ad9c1897af365a91b45b00228a00d614c)), closes [#30684](https://github.com/ionic-team/ionic-framework/issues/30684)
* **vue:** emit component-specific overlay events ([#30688](https://github.com/ionic-team/ionic-framework/issues/30688)) ([024d090](https://github.com/ionic-team/ionic-framework/commit/024d090122548e26ec2cdcfae4637dde8f288278)), closes [#30641](https://github.com/ionic-team/ionic-framework/issues/30641)
## [8.7.4](https://github.com/ionic-team/ionic-framework/compare/v8.7.3...v8.7.4) (2025-09-17)
### Bug Fixes
* **input:** improve error text accessibility ([#30635](https://github.com/ionic-team/ionic-framework/issues/30635)) ([c339bc3](https://github.com/ionic-team/ionic-framework/commit/c339bc36827b62ef871325869a9a5db9b17ac785))
* **overlays,picker:** remove invalid aria-hidden attribute ([#30563](https://github.com/ionic-team/ionic-framework/issues/30563)) ([49f96d7](https://github.com/ionic-team/ionic-framework/commit/49f96d7f1e9050a95e3e33a821c0467ecc0bed64)), closes [#30040](https://github.com/ionic-team/ionic-framework/issues/30040)
* **segment-view:** scroll and select the right item when the component is in RTL context; ([#30675](https://github.com/ionic-team/ionic-framework/issues/30675)) ([66f517d](https://github.com/ionic-team/ionic-framework/commit/66f517d5b2154fff00b294a78f4107f057a580c6)), closes [#30079](https://github.com/ionic-team/ionic-framework/issues/30079)
## [8.7.3](https://github.com/ionic-team/ionic-framework/compare/v8.7.2...v8.7.3) (2025-08-20)
### Bug Fixes
* **checkbox:** add aria attributes to ignore checkbox icon ([#30633](https://github.com/ionic-team/ionic-framework/issues/30633)) ([e9e6605](https://github.com/ionic-team/ionic-framework/commit/e9e6605862a05a46d26c26a144ed1cf22133a2b7)), closes [#30231](https://github.com/ionic-team/ionic-framework/issues/30231)
* **refresher:** prevent focus-related scroll jumps on refresh ([#30636](https://github.com/ionic-team/ionic-framework/issues/30636)) ([1899b49](https://github.com/ionic-team/ionic-framework/commit/1899b49d252abc6003f763cea8db2a51efa941ec))
## [8.7.2](https://github.com/ionic-team/ionic-framework/compare/v8.7.1...v8.7.2) (2025-08-06)
### Bug Fixes
* **reorder-group:** add children fallback for framework compatibility ([#30593](https://github.com/ionic-team/ionic-framework/issues/30593)) ([1cd81b9](https://github.com/ionic-team/ionic-framework/commit/1cd81b92301378d55bce63a01dfcf95a91c92652)), closes [#30592](https://github.com/ionic-team/ionic-framework/issues/30592)
* **tabs:** add fallback to select tab if router integration fails ([#30599](https://github.com/ionic-team/ionic-framework/issues/30599)) ([a2e803a](https://github.com/ionic-team/ionic-framework/commit/a2e803a553dc58fc0e1599e515a56180a7ab263a)), closes [#30552](https://github.com/ionic-team/ionic-framework/issues/30552)
## [8.7.1](https://github.com/ionic-team/ionic-framework/compare/v8.7.0...v8.7.1) (2025-07-31)
### Dependencies
* **stencil:** upgrade `@stencil/core` to version 4.36.2
# [8.7.0](https://github.com/ionic-team/ionic-framework/compare/v8.6.7...v8.7.0) (2025-07-30)
### Features
* **css:** add new css utility classes for display and flex utils ([#30567](https://github.com/ionic-team/ionic-framework/issues/30567)) ([75f6c05](https://github.com/ionic-team/ionic-framework/commit/75f6c05fb96313ef890cc80a229a3a3ed3d57460)), closes [#22469](https://github.com/ionic-team/ionic-framework/issues/22469)
* **datetime:** add border property to highlightedDates ([#30534](https://github.com/ionic-team/ionic-framework/issues/30534)) ([d5627c7](https://github.com/ionic-team/ionic-framework/commit/d5627c73681faf658ea3b869f3fb04d708391eb9)), closes [#29833](https://github.com/ionic-team/ionic-framework/issues/29833)
* **deps:** update ionicons to v8 ([#30390](https://github.com/ionic-team/ionic-framework/issues/30390)) ([74cd71a](https://github.com/ionic-team/ionic-framework/commit/74cd71af243183aa738d11b280e155bdfd652126)), closes [#30445](https://github.com/ionic-team/ionic-framework/issues/30445)
* **modal:** add IonModalToken for injecting modal elements in Angular components ([#30474](https://github.com/ionic-team/ionic-framework/issues/30474)) ([30d1910](https://github.com/ionic-team/ionic-framework/commit/30d1910d6ea5428b414d0e127e7681f59426c538))
* **reorder-group:** add ionReorderStart, ionReorderMove, ionReorderEnd events ([#30471](https://github.com/ionic-team/ionic-framework/issues/30471)) ([b154f4e](https://github.com/ionic-team/ionic-framework/commit/b154f4ed095890f57ccab539fd9217976a5466e5)), closes [#23148](https://github.com/ionic-team/ionic-framework/issues/23148) [#27614](https://github.com/ionic-team/ionic-framework/issues/27614)
## [8.6.7](https://github.com/ionic-team/ionic-framework/compare/v8.6.6...v8.6.7) (2025-07-30)
### Dependencies
* **stencil:** downgrade `@stencil/core` to version 4.33.1
_Stencil has been downgraded due to an uncaught regression in Reorder._
## [8.6.6](https://github.com/ionic-team/ionic-framework/compare/v8.6.5...v8.6.6) (2025-07-30)
### Dependencies
* **stencil:** upgrade `@stencil/core` to version 4.36.2
## [8.6.5](https://github.com/ionic-team/ionic-framework/compare/v8.6.4...v8.6.5) (2025-07-16)
### Bug Fixes
* **input-otp:** improve autofill detection and invalid character handling ([#30541](https://github.com/ionic-team/ionic-framework/issues/30541)) ([8b4023d](https://github.com/ionic-team/ionic-framework/commit/8b4023d520212c254395a5be6d3a76dcbee6f2da)), closes [#30459](https://github.com/ionic-team/ionic-framework/issues/30459)
* **input:** prevent layout shift when hiding password toggle ([#30533](https://github.com/ionic-team/ionic-framework/issues/30533)) ([f1defba](https://github.com/ionic-team/ionic-framework/commit/f1defba2acb417c6f243b2902923d85efbb6f879)), closes [#29562](https://github.com/ionic-team/ionic-framework/issues/29562)
* **item:** allow nested content to be conditionally interactive ([#30519](https://github.com/ionic-team/ionic-framework/issues/30519)) ([3f730ab](https://github.com/ionic-team/ionic-framework/commit/3f730ab1d77be54d1faf14168eee9e9dc41002d6)), closes [#29763](https://github.com/ionic-team/ionic-framework/issues/29763)
* **modal:** dismiss child modals when parent is dismissed ([#30540](https://github.com/ionic-team/ionic-framework/issues/30540)) ([9b0099f](https://github.com/ionic-team/ionic-framework/commit/9b0099f462fda6d40b49dde1a1c97afbbbee2287)), closes [#30389](https://github.com/ionic-team/ionic-framework/issues/30389)
* **modal:** dismiss modal when parent element is removed from DOM ([#30544](https://github.com/ionic-team/ionic-framework/issues/30544)) ([850338c](https://github.com/ionic-team/ionic-framework/commit/850338cbd5c76addbc2cc3068b93071dea14c0af)), closes [#30389](https://github.com/ionic-team/ionic-framework/issues/30389)
* **modal:** improve card modal background transition from portrait to landscape ([#30551](https://github.com/ionic-team/ionic-framework/issues/30551)) ([d37b9b8](https://github.com/ionic-team/ionic-framework/commit/d37b9b8e468b7b2c9cda8b27fe7019bb905ad2bf))
* **segment-view:** scroll to correct content when height is not set ([#30547](https://github.com/ionic-team/ionic-framework/issues/30547)) ([d14311f](https://github.com/ionic-team/ionic-framework/commit/d14311fb65ae3de7ba7578791ce1ea44f186c413)), closes [#30543](https://github.com/ionic-team/ionic-framework/issues/30543)
## [8.6.4](https://github.com/ionic-team/ionic-framework/compare/v8.6.3...v8.6.4) (2025-07-09)
### Bug Fixes
* **modal:** support iOS card view transitions for viewport changes ([#30520](https://github.com/ionic-team/ionic-framework/issues/30520)) ([0fd9e82](https://github.com/ionic-team/ionic-framework/commit/0fd9e824508333a53175d7da5f681fc3126a2394)), closes [#30296](https://github.com/ionic-team/ionic-framework/issues/30296)
## [8.6.3](https://github.com/ionic-team/ionic-framework/compare/v8.6.2...v8.6.3) (2025-07-02)
### Bug Fixes
* **angular:** update schematics to support Angular's latest build system ([#30525](https://github.com/ionic-team/ionic-framework/issues/30525)) ([08e3e7a](https://github.com/ionic-team/ionic-framework/commit/08e3e7ab5165baea668571af9845933b5befeb46)), closes [ionic-team/ionic-docs#2091](https://github.com/ionic-team/ionic-docs/issues/2091)
* **modal:** add conditional tabIndex for handle cycling ([#30510](https://github.com/ionic-team/ionic-framework/issues/30510)) ([ee47660](https://github.com/ionic-team/ionic-framework/commit/ee47660745428e04c78cfef0555f3c5788959a8c))
* **select:** focus the correct selected item in an action sheet interface with a header ([#30481](https://github.com/ionic-team/ionic-framework/issues/30481)) ([80a111c](https://github.com/ionic-team/ionic-framework/commit/80a111cffac70e831eb57e827301370163ef4e2a)), closes [#30480](https://github.com/ionic-team/ionic-framework/issues/30480)
## [8.6.2](https://github.com/ionic-team/ionic-framework/compare/v8.6.1...v8.6.2) (2025-06-18)

View File

@@ -3,186 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [8.7.9](https://github.com/ionic-team/ionic-framework/compare/v8.7.8...v8.7.9) (2025-11-05)
### Bug Fixes
* **accordion-group:** skip initial animation ([#30729](https://github.com/ionic-team/ionic-framework/issues/30729)) ([58d5638](https://github.com/ionic-team/ionic-framework/commit/58d563805fca1db88caeeb40a8f710ac30416d93)), closes [#30613](https://github.com/ionic-team/ionic-framework/issues/30613)
## [8.7.8](https://github.com/ionic-team/ionic-framework/compare/v8.7.7...v8.7.8) (2025-10-29)
### Bug Fixes
* **checkbox, toggle:** fire ionFocus and ionBlur ([#30733](https://github.com/ionic-team/ionic-framework/issues/30733)) ([54a1c86](https://github.com/ionic-team/ionic-framework/commit/54a1c86d6a5d533b0c8c2d18edc62454a7c17bab))
## [8.7.7](https://github.com/ionic-team/ionic-framework/compare/v8.7.6...v8.7.7) (2025-10-15)
### Bug Fixes
* **header:** ensure one banner role in condensed header ([#30718](https://github.com/ionic-team/ionic-framework/issues/30718)) ([12084af](https://github.com/ionic-team/ionic-framework/commit/12084af163ed811b9c6bda3c7850fc0c53c60c7b))
* **header:** prevent flickering during iOS page transitions ([#30705](https://github.com/ionic-team/ionic-framework/issues/30705)) ([820fa28](https://github.com/ionic-team/ionic-framework/commit/820fa2854331722d22efd0e38a1936117477967a)), closes [#25326](https://github.com/ionic-team/ionic-framework/issues/25326)
* **select:** improve screen reader announcement timing for validation errors ([#30723](https://github.com/ionic-team/ionic-framework/issues/30723)) ([03303d7](https://github.com/ionic-team/ionic-framework/commit/03303d73f0bfe2380ced7931525fc52fd8576367))
## [8.7.6](https://github.com/ionic-team/ionic-framework/compare/v8.7.5...v8.7.6) (2025-10-08)
### Bug Fixes
* **tabs:** respect stencil lifecycle order for tab selection ([#30702](https://github.com/ionic-team/ionic-framework/issues/30702)) ([7bb9535](https://github.com/ionic-team/ionic-framework/commit/7bb9535f601d2469ce60687a9c03f8b1cfe4aba4)), closes [#30611](https://github.com/ionic-team/ionic-framework/issues/30611)
## [8.7.5](https://github.com/ionic-team/ionic-framework/compare/v8.7.4...v8.7.5) (2025-09-24)
### Bug Fixes
* **modal:** allow sheet modals to skip focus trap ([#30689](https://github.com/ionic-team/ionic-framework/issues/30689)) ([a40d957](https://github.com/ionic-team/ionic-framework/commit/a40d957ad9c1897af365a91b45b00228a00d614c)), closes [#30684](https://github.com/ionic-team/ionic-framework/issues/30684)
## [8.7.4](https://github.com/ionic-team/ionic-framework/compare/v8.7.3...v8.7.4) (2025-09-17)
### Bug Fixes
* **input:** improve error text accessibility ([#30635](https://github.com/ionic-team/ionic-framework/issues/30635)) ([c339bc3](https://github.com/ionic-team/ionic-framework/commit/c339bc36827b62ef871325869a9a5db9b17ac785))
* **overlays,picker:** remove invalid aria-hidden attribute ([#30563](https://github.com/ionic-team/ionic-framework/issues/30563)) ([49f96d7](https://github.com/ionic-team/ionic-framework/commit/49f96d7f1e9050a95e3e33a821c0467ecc0bed64)), closes [#30040](https://github.com/ionic-team/ionic-framework/issues/30040)
* **segment-view:** scroll and select the right item when the component is in RTL context; ([#30675](https://github.com/ionic-team/ionic-framework/issues/30675)) ([66f517d](https://github.com/ionic-team/ionic-framework/commit/66f517d5b2154fff00b294a78f4107f057a580c6)), closes [#30079](https://github.com/ionic-team/ionic-framework/issues/30079)
## [8.7.3](https://github.com/ionic-team/ionic-framework/compare/v8.7.2...v8.7.3) (2025-08-20)
### Bug Fixes
* **checkbox:** add aria attributes to ignore checkbox icon ([#30633](https://github.com/ionic-team/ionic-framework/issues/30633)) ([e9e6605](https://github.com/ionic-team/ionic-framework/commit/e9e6605862a05a46d26c26a144ed1cf22133a2b7)), closes [#30231](https://github.com/ionic-team/ionic-framework/issues/30231)
* **refresher:** prevent focus-related scroll jumps on refresh ([#30636](https://github.com/ionic-team/ionic-framework/issues/30636)) ([1899b49](https://github.com/ionic-team/ionic-framework/commit/1899b49d252abc6003f763cea8db2a51efa941ec))
## [8.7.2](https://github.com/ionic-team/ionic-framework/compare/v8.7.1...v8.7.2) (2025-08-06)
### Bug Fixes
* **reorder-group:** add children fallback for framework compatibility ([#30593](https://github.com/ionic-team/ionic-framework/issues/30593)) ([1cd81b9](https://github.com/ionic-team/ionic-framework/commit/1cd81b92301378d55bce63a01dfcf95a91c92652)), closes [#30592](https://github.com/ionic-team/ionic-framework/issues/30592)
* **tabs:** add fallback to select tab if router integration fails ([#30599](https://github.com/ionic-team/ionic-framework/issues/30599)) ([a2e803a](https://github.com/ionic-team/ionic-framework/commit/a2e803a553dc58fc0e1599e515a56180a7ab263a)), closes [#30552](https://github.com/ionic-team/ionic-framework/issues/30552)
## [8.7.1](https://github.com/ionic-team/ionic-framework/compare/v8.7.0...v8.7.1) (2025-07-31)
### Dependencies
* **stencil:** upgrade `@stencil/core` to version 4.36.2
# [8.7.0](https://github.com/ionic-team/ionic-framework/compare/v8.6.7...v8.7.0) (2025-07-30)
### Features
* **css:** add new css utility classes for display and flex utils ([#30567](https://github.com/ionic-team/ionic-framework/issues/30567)) ([75f6c05](https://github.com/ionic-team/ionic-framework/commit/75f6c05fb96313ef890cc80a229a3a3ed3d57460)), closes [#22469](https://github.com/ionic-team/ionic-framework/issues/22469)
* **datetime:** add border property to highlightedDates ([#30534](https://github.com/ionic-team/ionic-framework/issues/30534)) ([d5627c7](https://github.com/ionic-team/ionic-framework/commit/d5627c73681faf658ea3b869f3fb04d708391eb9)), closes [#29833](https://github.com/ionic-team/ionic-framework/issues/29833)
* **deps:** update ionicons to v8 ([#30390](https://github.com/ionic-team/ionic-framework/issues/30390)) ([74cd71a](https://github.com/ionic-team/ionic-framework/commit/74cd71af243183aa738d11b280e155bdfd652126)), closes [#30445](https://github.com/ionic-team/ionic-framework/issues/30445)
* **reorder-group:** add ionReorderStart, ionReorderMove, ionReorderEnd events ([#30471](https://github.com/ionic-team/ionic-framework/issues/30471)) ([b154f4e](https://github.com/ionic-team/ionic-framework/commit/b154f4ed095890f57ccab539fd9217976a5466e5)), closes [#23148](https://github.com/ionic-team/ionic-framework/issues/23148) [#27614](https://github.com/ionic-team/ionic-framework/issues/27614)
## [8.6.7](https://github.com/ionic-team/ionic-framework/compare/v8.6.6...v8.6.7) (2025-07-30)
### Dependencies
* **stencil:** downgrade `@stencil/core` to version 4.33.1
_Stencil has been downgraded due to an uncaught regression in Reorder._
## [8.6.6](https://github.com/ionic-team/ionic-framework/compare/v8.6.5...v8.6.6) (2025-07-30)
### Dependencies
* **stencil:** upgrade `@stencil/core` to version 4.36.2
## [8.6.5](https://github.com/ionic-team/ionic-framework/compare/v8.6.4...v8.6.5) (2025-07-16)
### Bug Fixes
* **input-otp:** improve autofill detection and invalid character handling ([#30541](https://github.com/ionic-team/ionic-framework/issues/30541)) ([8b4023d](https://github.com/ionic-team/ionic-framework/commit/8b4023d520212c254395a5be6d3a76dcbee6f2da)), closes [#30459](https://github.com/ionic-team/ionic-framework/issues/30459)
* **input:** prevent layout shift when hiding password toggle ([#30533](https://github.com/ionic-team/ionic-framework/issues/30533)) ([f1defba](https://github.com/ionic-team/ionic-framework/commit/f1defba2acb417c6f243b2902923d85efbb6f879)), closes [#29562](https://github.com/ionic-team/ionic-framework/issues/29562)
* **item:** allow nested content to be conditionally interactive ([#30519](https://github.com/ionic-team/ionic-framework/issues/30519)) ([3f730ab](https://github.com/ionic-team/ionic-framework/commit/3f730ab1d77be54d1faf14168eee9e9dc41002d6)), closes [#29763](https://github.com/ionic-team/ionic-framework/issues/29763)
* **modal:** dismiss child modals when parent is dismissed ([#30540](https://github.com/ionic-team/ionic-framework/issues/30540)) ([9b0099f](https://github.com/ionic-team/ionic-framework/commit/9b0099f462fda6d40b49dde1a1c97afbbbee2287)), closes [#30389](https://github.com/ionic-team/ionic-framework/issues/30389)
* **modal:** dismiss modal when parent element is removed from DOM ([#30544](https://github.com/ionic-team/ionic-framework/issues/30544)) ([850338c](https://github.com/ionic-team/ionic-framework/commit/850338cbd5c76addbc2cc3068b93071dea14c0af)), closes [#30389](https://github.com/ionic-team/ionic-framework/issues/30389)
* **modal:** improve card modal background transition from portrait to landscape ([#30551](https://github.com/ionic-team/ionic-framework/issues/30551)) ([d37b9b8](https://github.com/ionic-team/ionic-framework/commit/d37b9b8e468b7b2c9cda8b27fe7019bb905ad2bf))
* **segment-view:** scroll to correct content when height is not set ([#30547](https://github.com/ionic-team/ionic-framework/issues/30547)) ([d14311f](https://github.com/ionic-team/ionic-framework/commit/d14311fb65ae3de7ba7578791ce1ea44f186c413)), closes [#30543](https://github.com/ionic-team/ionic-framework/issues/30543)
## [8.6.4](https://github.com/ionic-team/ionic-framework/compare/v8.6.3...v8.6.4) (2025-07-09)
### Bug Fixes
* **modal:** support iOS card view transitions for viewport changes ([#30520](https://github.com/ionic-team/ionic-framework/issues/30520)) ([0fd9e82](https://github.com/ionic-team/ionic-framework/commit/0fd9e824508333a53175d7da5f681fc3126a2394)), closes [#30296](https://github.com/ionic-team/ionic-framework/issues/30296)
## [8.6.3](https://github.com/ionic-team/ionic-framework/compare/v8.6.2...v8.6.3) (2025-07-02)
### Bug Fixes
* **modal:** add conditional tabIndex for handle cycling ([#30510](https://github.com/ionic-team/ionic-framework/issues/30510)) ([ee47660](https://github.com/ionic-team/ionic-framework/commit/ee47660745428e04c78cfef0555f3c5788959a8c))
* **select:** focus the correct selected item in an action sheet interface with a header ([#30481](https://github.com/ionic-team/ionic-framework/issues/30481)) ([80a111c](https://github.com/ionic-team/ionic-framework/commit/80a111cffac70e831eb57e827301370163ef4e2a)), closes [#30480](https://github.com/ionic-team/ionic-framework/issues/30480)
## [8.6.2](https://github.com/ionic-team/ionic-framework/compare/v8.6.1...v8.6.2) (2025-06-18)

View File

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

View File

@@ -1508,9 +1508,6 @@ ion-reorder-group,none
ion-reorder-group,prop,disabled,boolean,true,false,false
ion-reorder-group,method,complete,complete(listOrReorder?: boolean | any[]) => Promise<any>
ion-reorder-group,event,ionItemReorder,ItemReorderEventDetail,true
ion-reorder-group,event,ionReorderEnd,ReorderEndEventDetail,true
ion-reorder-group,event,ionReorderMove,ReorderMoveEventDetail,true
ion-reorder-group,event,ionReorderStart,void,true
ion-ripple-effect,shadow
ion-ripple-effect,prop,type,"bounded" | "unbounded",'bounded',false,false

174
core/package-lock.json generated
View File

@@ -1,20 +1,20 @@
{
"name": "@ionic/core",
"version": "8.7.9",
"version": "8.6.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@ionic/core",
"version": "8.7.9",
"version": "8.6.2",
"license": "MIT",
"dependencies": {
"@stencil/core": "4.38.0",
"ionicons": "^8.0.13",
"@stencil/core": "4.33.1",
"ionicons": "^7.2.2",
"tslib": "^2.1.0"
},
"devDependencies": {
"@axe-core/playwright": "^4.11.0",
"@axe-core/playwright": "^4.10.2",
"@capacitor/core": "^7.0.0",
"@capacitor/haptics": "^7.0.0",
"@capacitor/keyboard": "^7.0.0",
@@ -22,7 +22,7 @@
"@clack/prompts": "^0.11.0",
"@ionic/eslint-config": "^0.3.0",
"@ionic/prettier-config": "^2.0.0",
"@playwright/test": "^1.56.1",
"@playwright/test": "^1.53.2",
"@rollup/plugin-node-resolve": "^8.4.0",
"@rollup/plugin-virtual": "^2.0.3",
"@stencil/angular-output-target": "^0.10.0",
@@ -57,12 +57,12 @@
"dev": true
},
"node_modules/@axe-core/playwright": {
"version": "4.11.0",
"resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.11.0.tgz",
"integrity": "sha512-70vBT/Ylqpm65RQz2iCG2o0JJCEG/WCNyefTr2xcOcr1CoSee60gNQYUMZZ7YukoKkFLv26I/jjlsvwwp532oQ==",
"version": "4.10.2",
"resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.10.2.tgz",
"integrity": "sha512-6/b5BJjG6hDaRNtgzLIfKr5DfwyiLHO4+ByTLB0cJgWSM8Ll7KqtdblIS6bEkwSF642/Ex91vNqIl3GLXGlceg==",
"dev": true,
"dependencies": {
"axe-core": "~4.11.0"
"axe-core": "~4.10.3"
},
"peerDependencies": {
"playwright-core": ">= 1.0.0"
@@ -663,36 +663,36 @@
"dev": true
},
"node_modules/@capacitor/core": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-7.4.4.tgz",
"integrity": "sha512-xzjxpr+d2zwTpCaN0k+C6wKSZzWFAb9OVEUtmO72ihjr/NEDoLvsGl4WLfjWPcCO2zOy0b2X52tfRWjECFUjtw==",
"version": "7.4.0",
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-7.4.0.tgz",
"integrity": "sha512-P6NnjoHyobZgTjynlZSn27d0SUj6j38inlNxFnKZr9qwU7/r6+0Sg2nWkGkIH/pMmXHsvGD8zVe6KUq1UncIjA==",
"dev": true,
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/@capacitor/haptics": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/@capacitor/haptics/-/haptics-7.0.2.tgz",
"integrity": "sha512-vqfeEM6s2zMgLjpITCTUIy7P/hadq/Gr5E/RClFgMJPB41Y5FsqOKD+j85/uwh8N2cf/aWaPeXUmjnTzJbEB2g==",
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/@capacitor/haptics/-/haptics-7.0.1.tgz",
"integrity": "sha512-ewZmspE5krgDUj5ZvUDcfNZvgerAIr+3bDSk6DLzyvBZ/dYmr/tMLu5H6WtYaaKYZJ32aZAudGpIal5epDyBYA==",
"dev": true,
"peerDependencies": {
"@capacitor/core": ">=7.0.0"
}
},
"node_modules/@capacitor/keyboard": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/@capacitor/keyboard/-/keyboard-7.0.3.tgz",
"integrity": "sha512-BIBKjmky5rOYNhvYhNeDi0MMvjwYZ6YF9JoCYcGKvKY+XLJKtezsEL78XfOlgWZBkbfR8uq3tzktY6PqgoYLKA==",
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/@capacitor/keyboard/-/keyboard-7.0.1.tgz",
"integrity": "sha512-Gi064vOARMac+x9/DmEFeywN9oAETMf3OYsMuYm9gA8SvdsDJ3QJqMoFnSEIORYXe21Jzt2SIEdLlpT65P/b2g==",
"dev": true,
"peerDependencies": {
"@capacitor/core": ">=7.0.0"
}
},
"node_modules/@capacitor/status-bar": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/@capacitor/status-bar/-/status-bar-7.0.3.tgz",
"integrity": "sha512-JyRpVnKwHij9hgPWolF6PK+HT3e2HSPjN11/h2OmKxq8GAdPGARFLv+97eZl0pvuvm0Kka/LpiLb5whXISBg7Q==",
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/@capacitor/status-bar/-/status-bar-7.0.1.tgz",
"integrity": "sha512-iDv3mXYo9CdxYRVwt3/pRyuk25p7Sn4GfaS/zMZyVIqTzsvKLCIIH3GdKK+ta+nsNcAVpCw/t5jFEBt1D18ctA==",
"dev": true,
"peerDependencies": {
"@capacitor/core": ">=7.0.0"
@@ -1715,12 +1715,12 @@
}
},
"node_modules/@playwright/test": {
"version": "1.56.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.56.1.tgz",
"integrity": "sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg==",
"version": "1.53.2",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.53.2.tgz",
"integrity": "sha512-tEB2U5z74ebBeyfGNZ3Jfg29AnW+5HlWhvHtb/Mqco9pFdZU1ZLNdVb2UtB5CvmiilNr2ZfVH/qMmAROG/XTzw==",
"dev": true,
"dependencies": {
"playwright": "1.56.1"
"playwright": "1.53.2"
},
"bin": {
"playwright": "cli.js"
@@ -1914,9 +1914,10 @@
}
},
"node_modules/@stencil/core": {
"version": "4.38.0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.38.0.tgz",
"integrity": "sha512-oC3QFKO0X1yXVvETgc8OLY525MNKhn9vISBrbtKnGoPlokJ6rI8Vk1RK22TevnNrHLI4SExNLbcDnqilKR35JQ==",
"version": "4.33.1",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.33.1.tgz",
"integrity": "sha512-12k9xhAJBkpg598it+NRmaYIdEe6TSnsL/v6/KRXDcUyTK11VYwZQej2eHnMWtqot+znJ+GNTqb5YbiXi+5Low==",
"license": "MIT",
"bin": {
"stencil": "bin/stencil"
},
@@ -3033,9 +3034,9 @@
}
},
"node_modules/axe-core": {
"version": "4.11.0",
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.0.tgz",
"integrity": "sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ==",
"version": "4.10.3",
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz",
"integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==",
"dev": true,
"engines": {
"node": ">=4"
@@ -3473,9 +3474,9 @@
]
},
"node_modules/chalk": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
"integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
"integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
"dev": true,
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
@@ -5710,12 +5711,11 @@
}
},
"node_modules/ionicons": {
"version": "8.0.13",
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-8.0.13.tgz",
"integrity": "sha512-2QQVyG2P4wszne79jemMjWYLp0DBbDhr4/yFroPCxvPP1wtMxgdIV3l5n+XZ5E9mgoXU79w7yTWpm2XzJsISxQ==",
"license": "MIT",
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.2.2.tgz",
"integrity": "sha512-I3iYIfc9Q9FRifWyFSwTAvbEABWlWY32i0sAVDDPGYnaIZVugkLCZFbEcrphW6ixVPg8tt1oLwalo/JJwbEqnA==",
"dependencies": {
"@stencil/core": "^4.35.3"
"@stencil/core": "^4.0.3"
}
},
"node_modules/is-alphabetical": {
@@ -8592,12 +8592,12 @@
}
},
"node_modules/playwright": {
"version": "1.56.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.56.1.tgz",
"integrity": "sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==",
"version": "1.53.2",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.53.2.tgz",
"integrity": "sha512-6K/qQxVFuVQhRQhFsVZ9fGeatxirtrpPgxzBYWyZLEXJzqYwuL4fuNmfOfD5et1tJE4GScKyPNeLhZeRwuTU3A==",
"dev": true,
"dependencies": {
"playwright-core": "1.56.1"
"playwright-core": "1.53.2"
},
"bin": {
"playwright": "cli.js"
@@ -8610,9 +8610,9 @@
}
},
"node_modules/playwright-core": {
"version": "1.56.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.56.1.tgz",
"integrity": "sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==",
"version": "1.53.2",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.2.tgz",
"integrity": "sha512-ox/OytMy+2w1jcYEYlOo1Hhp8hZkLCximMTUTMBXjGUA1KoFfiSZ+DU+3a739jsPY0yoKH2TFy9S2fsJas8yAw==",
"dev": true,
"bin": {
"playwright-core": "cli.js"
@@ -10652,12 +10652,12 @@
},
"dependencies": {
"@axe-core/playwright": {
"version": "4.11.0",
"resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.11.0.tgz",
"integrity": "sha512-70vBT/Ylqpm65RQz2iCG2o0JJCEG/WCNyefTr2xcOcr1CoSee60gNQYUMZZ7YukoKkFLv26I/jjlsvwwp532oQ==",
"version": "4.10.2",
"resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.10.2.tgz",
"integrity": "sha512-6/b5BJjG6hDaRNtgzLIfKr5DfwyiLHO4+ByTLB0cJgWSM8Ll7KqtdblIS6bEkwSF642/Ex91vNqIl3GLXGlceg==",
"dev": true,
"requires": {
"axe-core": "~4.11.0"
"axe-core": "~4.10.3"
}
},
"@babel/code-frame": {
@@ -11101,32 +11101,32 @@
"dev": true
},
"@capacitor/core": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-7.4.4.tgz",
"integrity": "sha512-xzjxpr+d2zwTpCaN0k+C6wKSZzWFAb9OVEUtmO72ihjr/NEDoLvsGl4WLfjWPcCO2zOy0b2X52tfRWjECFUjtw==",
"version": "7.4.0",
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-7.4.0.tgz",
"integrity": "sha512-P6NnjoHyobZgTjynlZSn27d0SUj6j38inlNxFnKZr9qwU7/r6+0Sg2nWkGkIH/pMmXHsvGD8zVe6KUq1UncIjA==",
"dev": true,
"requires": {
"tslib": "^2.1.0"
}
},
"@capacitor/haptics": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/@capacitor/haptics/-/haptics-7.0.2.tgz",
"integrity": "sha512-vqfeEM6s2zMgLjpITCTUIy7P/hadq/Gr5E/RClFgMJPB41Y5FsqOKD+j85/uwh8N2cf/aWaPeXUmjnTzJbEB2g==",
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/@capacitor/haptics/-/haptics-7.0.1.tgz",
"integrity": "sha512-ewZmspE5krgDUj5ZvUDcfNZvgerAIr+3bDSk6DLzyvBZ/dYmr/tMLu5H6WtYaaKYZJ32aZAudGpIal5epDyBYA==",
"dev": true,
"requires": {}
},
"@capacitor/keyboard": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/@capacitor/keyboard/-/keyboard-7.0.3.tgz",
"integrity": "sha512-BIBKjmky5rOYNhvYhNeDi0MMvjwYZ6YF9JoCYcGKvKY+XLJKtezsEL78XfOlgWZBkbfR8uq3tzktY6PqgoYLKA==",
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/@capacitor/keyboard/-/keyboard-7.0.1.tgz",
"integrity": "sha512-Gi064vOARMac+x9/DmEFeywN9oAETMf3OYsMuYm9gA8SvdsDJ3QJqMoFnSEIORYXe21Jzt2SIEdLlpT65P/b2g==",
"dev": true,
"requires": {}
},
"@capacitor/status-bar": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/@capacitor/status-bar/-/status-bar-7.0.3.tgz",
"integrity": "sha512-JyRpVnKwHij9hgPWolF6PK+HT3e2HSPjN11/h2OmKxq8GAdPGARFLv+97eZl0pvuvm0Kka/LpiLb5whXISBg7Q==",
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/@capacitor/status-bar/-/status-bar-7.0.1.tgz",
"integrity": "sha512-iDv3mXYo9CdxYRVwt3/pRyuk25p7Sn4GfaS/zMZyVIqTzsvKLCIIH3GdKK+ta+nsNcAVpCw/t5jFEBt1D18ctA==",
"dev": true,
"requires": {}
},
@@ -11862,12 +11862,12 @@
}
},
"@playwright/test": {
"version": "1.56.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.56.1.tgz",
"integrity": "sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg==",
"version": "1.53.2",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.53.2.tgz",
"integrity": "sha512-tEB2U5z74ebBeyfGNZ3Jfg29AnW+5HlWhvHtb/Mqco9pFdZU1ZLNdVb2UtB5CvmiilNr2ZfVH/qMmAROG/XTzw==",
"dev": true,
"requires": {
"playwright": "1.56.1"
"playwright": "1.53.2"
}
},
"@rollup/plugin-node-resolve": {
@@ -11983,9 +11983,9 @@
"requires": {}
},
"@stencil/core": {
"version": "4.38.0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.38.0.tgz",
"integrity": "sha512-oC3QFKO0X1yXVvETgc8OLY525MNKhn9vISBrbtKnGoPlokJ6rI8Vk1RK22TevnNrHLI4SExNLbcDnqilKR35JQ==",
"version": "4.33.1",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.33.1.tgz",
"integrity": "sha512-12k9xhAJBkpg598it+NRmaYIdEe6TSnsL/v6/KRXDcUyTK11VYwZQej2eHnMWtqot+znJ+GNTqb5YbiXi+5Low==",
"requires": {
"@rollup/rollup-darwin-arm64": "4.34.9",
"@rollup/rollup-darwin-x64": "4.34.9",
@@ -12770,9 +12770,9 @@
}
},
"axe-core": {
"version": "4.11.0",
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.0.tgz",
"integrity": "sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ==",
"version": "4.10.3",
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz",
"integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==",
"dev": true
},
"babel-jest": {
@@ -13075,9 +13075,9 @@
"dev": true
},
"chalk": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
"integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
"integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
"dev": true
},
"chalk-template": {
@@ -14744,11 +14744,11 @@
}
},
"ionicons": {
"version": "8.0.13",
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-8.0.13.tgz",
"integrity": "sha512-2QQVyG2P4wszne79jemMjWYLp0DBbDhr4/yFroPCxvPP1wtMxgdIV3l5n+XZ5E9mgoXU79w7yTWpm2XzJsISxQ==",
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.2.2.tgz",
"integrity": "sha512-I3iYIfc9Q9FRifWyFSwTAvbEABWlWY32i0sAVDDPGYnaIZVugkLCZFbEcrphW6ixVPg8tt1oLwalo/JJwbEqnA==",
"requires": {
"@stencil/core": "^4.35.3"
"@stencil/core": "^4.0.3"
}
},
"is-alphabetical": {
@@ -16811,19 +16811,19 @@
}
},
"playwright": {
"version": "1.56.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.56.1.tgz",
"integrity": "sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==",
"version": "1.53.2",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.53.2.tgz",
"integrity": "sha512-6K/qQxVFuVQhRQhFsVZ9fGeatxirtrpPgxzBYWyZLEXJzqYwuL4fuNmfOfD5et1tJE4GScKyPNeLhZeRwuTU3A==",
"dev": true,
"requires": {
"fsevents": "2.3.2",
"playwright-core": "1.56.1"
"playwright-core": "1.53.2"
}
},
"playwright-core": {
"version": "1.56.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.56.1.tgz",
"integrity": "sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==",
"version": "1.53.2",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.2.tgz",
"integrity": "sha512-ox/OytMy+2w1jcYEYlOo1Hhp8hZkLCximMTUTMBXjGUA1KoFfiSZ+DU+3a739jsPY0yoKH2TFy9S2fsJas8yAw==",
"dev": true
},
"postcss": {

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/core",
"version": "8.7.9",
"version": "8.6.2",
"description": "Base components for Ionic",
"keywords": [
"ionic",
@@ -31,12 +31,12 @@
"loader/"
],
"dependencies": {
"@stencil/core": "4.38.0",
"ionicons": "^8.0.13",
"@stencil/core": "4.33.1",
"ionicons": "^7.2.2",
"tslib": "^2.1.0"
},
"devDependencies": {
"@axe-core/playwright": "^4.11.0",
"@axe-core/playwright": "^4.10.2",
"@capacitor/core": "^7.0.0",
"@capacitor/haptics": "^7.0.0",
"@capacitor/keyboard": "^7.0.0",
@@ -44,7 +44,7 @@
"@clack/prompts": "^0.11.0",
"@ionic/eslint-config": "^0.3.0",
"@ionic/prettier-config": "^2.0.0",
"@playwright/test": "^1.56.1",
"@playwright/test": "^1.53.2",
"@rollup/plugin-node-resolve": "^8.4.0",
"@rollup/plugin-virtual": "^2.0.3",
"@stencil/angular-output-target": "^0.10.0",

View File

@@ -30,7 +30,7 @@ import { PopoverSize, PositionAlign, PositionReference, PositionSide, TriggerAct
import { RadioGroupChangeEventDetail, RadioGroupCompareFn } from "./components/radio-group/radio-group-interface";
import { PinFormatter, RangeChangeEventDetail, RangeKnobMoveEndEventDetail, RangeKnobMoveStartEventDetail, RangeValue } from "./components/range/range-interface";
import { RefresherEventDetail } from "./components/refresher/refresher-interface";
import { ItemReorderEventDetail, ReorderEndEventDetail, ReorderMoveEventDetail } from "./components/reorder-group/reorder-group-interface";
import { ItemReorderEventDetail } from "./components/reorder-group/reorder-group-interface";
import { NavigationHookCallback } from "./components/route/route-interface";
import { SearchbarChangeEventDetail, SearchbarInputEventDetail } from "./components/searchbar/searchbar-interface";
import { SegmentChangeEventDetail, SegmentValue } from "./components/segment/segment-interface";
@@ -68,7 +68,7 @@ export { PopoverSize, PositionAlign, PositionReference, PositionSide, TriggerAct
export { RadioGroupChangeEventDetail, RadioGroupCompareFn } from "./components/radio-group/radio-group-interface";
export { PinFormatter, RangeChangeEventDetail, RangeKnobMoveEndEventDetail, RangeKnobMoveStartEventDetail, RangeValue } from "./components/range/range-interface";
export { RefresherEventDetail } from "./components/refresher/refresher-interface";
export { ItemReorderEventDetail, ReorderEndEventDetail, ReorderMoveEventDetail } from "./components/reorder-group/reorder-group-interface";
export { ItemReorderEventDetail } from "./components/reorder-group/reorder-group-interface";
export { NavigationHookCallback } from "./components/route/route-interface";
export { SearchbarChangeEventDetail, SearchbarInputEventDetail } from "./components/searchbar/searchbar-interface";
export { SegmentChangeEventDetail, SegmentValue } from "./components/segment/segment-interface";
@@ -2783,7 +2783,7 @@ export namespace Components {
}
interface IonReorderGroup {
/**
* Completes the reorder operation. Must be called by the `ionReorderEnd` event. If a list of items is passed, the list will be reordered and returned in the proper order. If no parameters are passed or if `true` is passed in, the reorder will complete and the item will remain in the position it was dragged to. If `false` is passed, the reorder will complete and the item will bounce back to its original position.
* Completes the reorder operation. Must be called by the `ionItemReorder` event. If a list of items is passed, the list will be reordered and returned in the proper order. If no parameters are passed or if `true` is passed in, the reorder will complete and the item will remain in the position it was dragged to. If `false` is passed, the reorder will complete and the item will bounce back to its original position.
* @param listOrReorder A list of items to be sorted and returned in the new order or a boolean of whether or not the reorder should reposition the item.
*/
"complete": (listOrReorder?: boolean | any[]) => Promise<any>;
@@ -4769,9 +4769,6 @@ declare global {
};
interface HTMLIonReorderGroupElementEventMap {
"ionItemReorder": ItemReorderEventDetail;
"ionReorderStart": void;
"ionReorderMove": ReorderMoveEventDetail;
"ionReorderEnd": ReorderEndEventDetail;
}
interface HTMLIonReorderGroupElement extends Components.IonReorderGroup, HTMLStencilElement {
addEventListener<K extends keyof HTMLIonReorderGroupElementEventMap>(type: K, listener: (this: HTMLIonReorderGroupElement, ev: IonReorderGroupCustomEvent<HTMLIonReorderGroupElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
@@ -8056,22 +8053,9 @@ declare namespace LocalJSX {
*/
"disabled"?: boolean;
/**
* Event that needs to be listened to in order to complete the reorder action.
* @deprecated Use `ionReorderEnd` instead. If you are accessing `event.detail.from` or `event.detail.to` and relying on them being different you should now add checks as they are always emitted in `ionReorderEnd`, even when they are the same.
* Event that needs to be listened to in order to complete the reorder action. Once the event has been emitted, the `complete()` method then needs to be called in order to finalize the reorder action.
*/
"onIonItemReorder"?: (event: IonReorderGroupCustomEvent<ItemReorderEventDetail>) => void;
/**
* Event that is emitted when the reorder gesture ends. The from and to properties are always available, regardless of if the reorder gesture moved the item. If the item did not change from its start position, the from and to properties will be the same. Once the event has been emitted, the `complete()` method then needs to be called in order to finalize the reorder action.
*/
"onIonReorderEnd"?: (event: IonReorderGroupCustomEvent<ReorderEndEventDetail>) => void;
/**
* Event that is emitted as the reorder gesture moves.
*/
"onIonReorderMove"?: (event: IonReorderGroupCustomEvent<ReorderMoveEventDetail>) => void;
/**
* Event that is emitted when the reorder gesture starts.
*/
"onIonReorderStart"?: (event: IonReorderGroupCustomEvent<void>) => void;
}
interface IonRippleEffect {
/**

View File

@@ -38,40 +38,7 @@ const enum AccordionState {
})
export class Accordion implements ComponentInterface {
private accordionGroupEl?: HTMLIonAccordionGroupElement | null;
private accordionGroupUpdateHandler = () => {
/**
* Determine if this update will cause an actual state change.
* We only want to mark as "interacted" if the state is changing.
*/
const accordionGroup = this.accordionGroupEl;
if (accordionGroup) {
const value = accordionGroup.value;
const accordionValue = this.value;
const shouldExpand = Array.isArray(value) ? value.includes(accordionValue) : value === accordionValue;
const isExpanded = this.state === AccordionState.Expanded || this.state === AccordionState.Expanding;
const stateWillChange = shouldExpand !== isExpanded;
/**
* Only mark as interacted if:
* 1. This is not the first update we've received with a defined value
* 2. The state is actually changing (prevents redundant updates from enabling animations)
*/
if (this.hasReceivedFirstUpdate && stateWillChange) {
this.hasInteracted = true;
}
/**
* Only count this as the first update if the group value is defined.
* This prevents the initial undefined value from the group's componentDidLoad
* from being treated as the first real update.
*/
if (value !== undefined) {
this.hasReceivedFirstUpdate = true;
}
}
this.updateState();
};
private updateListener = () => this.updateState(false);
private contentEl: HTMLDivElement | undefined;
private contentElWrapper: HTMLDivElement | undefined;
private headerEl: HTMLDivElement | undefined;
@@ -83,25 +50,6 @@ export class Accordion implements ComponentInterface {
@State() state: AccordionState = AccordionState.Collapsed;
@State() isNext = false;
@State() isPrevious = false;
/**
* Tracks whether a user-initiated interaction has occurred.
* Animations are disabled until the first interaction happens.
* This prevents the accordion from animating when it's programmatically
* set to an expanded or collapsed state on initial load.
*/
@State() hasInteracted = false;
/**
* Tracks if this accordion has ever been expanded.
* Used to prevent the first expansion from animating.
*/
private hasEverBeenExpanded = false;
/**
* Tracks if this accordion has received its first update from the group.
* Used to distinguish initial programmatic sets from user interactions.
*/
private hasReceivedFirstUpdate = false;
/**
* The value of the accordion. Defaults to an autogenerated
@@ -140,15 +88,15 @@ export class Accordion implements ComponentInterface {
connectedCallback() {
const accordionGroupEl = (this.accordionGroupEl = this.el?.closest('ion-accordion-group'));
if (accordionGroupEl) {
this.updateState();
addEventListener(accordionGroupEl, 'ionValueChange', this.accordionGroupUpdateHandler);
this.updateState(true);
addEventListener(accordionGroupEl, 'ionValueChange', this.updateListener);
}
}
disconnectedCallback() {
const accordionGroupEl = this.accordionGroupEl;
if (accordionGroupEl) {
removeEventListener(accordionGroupEl, 'ionValueChange', this.accordionGroupUpdateHandler);
removeEventListener(accordionGroupEl, 'ionValueChange', this.updateListener);
}
}
@@ -264,16 +212,10 @@ export class Accordion implements ComponentInterface {
ionItem.appendChild(iconEl);
};
private expandAccordion = () => {
private expandAccordion = (initialUpdate = false) => {
const { contentEl, contentElWrapper } = this;
/**
* If the content elements aren't available yet, just set the state.
* This happens on initial render before the DOM is ready.
*/
if (contentEl === undefined || contentElWrapper === undefined) {
if (initialUpdate || contentEl === undefined || contentElWrapper === undefined) {
this.state = AccordionState.Expanded;
this.hasEverBeenExpanded = true;
return;
}
@@ -285,12 +227,6 @@ export class Accordion implements ComponentInterface {
cancelAnimationFrame(this.currentRaf);
}
/**
* Mark that this accordion has been expanded at least once.
* This allows subsequent expansions to animate.
*/
this.hasEverBeenExpanded = true;
if (this.shouldAnimate()) {
raf(() => {
this.state = AccordionState.Expanding;
@@ -311,14 +247,9 @@ export class Accordion implements ComponentInterface {
}
};
private collapseAccordion = () => {
private collapseAccordion = (initialUpdate = false) => {
const { contentEl } = this;
/**
* If the content element isn't available yet, just set the state.
* This happens on initial render before the DOM is ready.
*/
if (contentEl === undefined) {
if (initialUpdate || contentEl === undefined) {
this.state = AccordionState.Collapsed;
return;
}
@@ -360,19 +291,6 @@ export class Accordion implements ComponentInterface {
* of what is set in the config.
*/
private shouldAnimate = () => {
/**
* Don't animate until after the first user interaction.
* This prevents animations on initial load when accordions
* start in an expanded or collapsed state programmatically.
*
* Additionally, don't animate the very first expansion even if
* hasInteracted is true. This handles edge cases like React StrictMode
* where effects run twice and might incorrectly mark as interacted.
*/
if (!this.hasInteracted || !this.hasEverBeenExpanded) {
return false;
}
if (typeof (window as any) === 'undefined') {
return false;
}
@@ -394,7 +312,7 @@ export class Accordion implements ComponentInterface {
return true;
};
private updateState = async () => {
private updateState = async (initialUpdate = false) => {
const accordionGroup = this.accordionGroupEl;
const accordionValue = this.value;
@@ -407,10 +325,10 @@ export class Accordion implements ComponentInterface {
const shouldExpand = Array.isArray(value) ? value.includes(accordionValue) : value === accordionValue;
if (shouldExpand) {
this.expandAccordion();
this.expandAccordion(initialUpdate);
this.isNext = this.isPrevious = false;
} else {
this.collapseAccordion();
this.collapseAccordion(initialUpdate);
/**
* When using popout or inset,
@@ -468,12 +386,6 @@ export class Accordion implements ComponentInterface {
if (disabled || readonly) return;
/**
* Mark that the user has interacted with the accordion.
* This enables animations for all future state changes.
*/
this.hasInteracted = true;
if (accordionGroupEl) {
/**
* Because the accordion group may or may

View File

@@ -200,87 +200,6 @@ it('should set default values if not provided', async () => {
expect(accordion.classList.contains('accordion-collapsed')).toEqual(false);
});
it('should not animate when initial value is set before load', async () => {
const page = await newSpecPage({
components: [Item, Accordion, AccordionGroup],
});
const accordionGroup = page.doc.createElement('ion-accordion-group');
accordionGroup.innerHTML = `
<ion-accordion value="first">
<ion-item slot="header">Label</ion-item>
<div slot="content">Content</div>
</ion-accordion>
<ion-accordion value="second">
<ion-item slot="header">Label</ion-item>
<div slot="content">Content</div>
</ion-accordion>
`;
accordionGroup.value = 'first';
page.body.appendChild(accordionGroup);
await page.waitForChanges();
const firstAccordion = accordionGroup.querySelector('ion-accordion[value="first"]')!;
expect(firstAccordion.classList.contains('accordion-expanded')).toEqual(true);
expect(firstAccordion.classList.contains('accordion-expanding')).toEqual(false);
});
it('should not animate when initial value is set after load', async () => {
const page = await newSpecPage({
components: [Item, Accordion, AccordionGroup],
});
const accordionGroup = page.doc.createElement('ion-accordion-group');
accordionGroup.innerHTML = `
<ion-accordion value="first">
<ion-item slot="header">Label</ion-item>
<div slot="content">Content</div>
</ion-accordion>
<ion-accordion value="second">
<ion-item slot="header">Label</ion-item>
<div slot="content">Content</div>
</ion-accordion>
`;
page.body.appendChild(accordionGroup);
await page.waitForChanges();
accordionGroup.value = 'first';
await page.waitForChanges();
const firstAccordion = accordionGroup.querySelector('ion-accordion[value="first"]')!;
expect(firstAccordion.classList.contains('accordion-expanded')).toEqual(true);
expect(firstAccordion.classList.contains('accordion-expanding')).toEqual(false);
});
it('should not have animated class on first expansion', async () => {
const page = await newSpecPage({
components: [Item, Accordion, AccordionGroup],
html: `
<ion-accordion-group>
<ion-accordion value="first">
<ion-item slot="header">Label</ion-item>
<div slot="content">Content</div>
</ion-accordion>
</ion-accordion-group>
`,
});
const accordionGroup = page.body.querySelector('ion-accordion-group')!;
const firstAccordion = page.body.querySelector('ion-accordion[value="first"]')!;
// First expansion should not have the animated class
accordionGroup.value = 'first';
await page.waitForChanges();
expect(firstAccordion.classList.contains('accordion-animated')).toEqual(false);
expect(firstAccordion.classList.contains('accordion-expanded')).toEqual(true);
});
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/27047
it('should not have animated class when animated="false"', async () => {
const page = await newSpecPage({

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -125,7 +125,7 @@
<ion-toolbar color="dark">
<ion-buttons slot="start">
<ion-back-button class="ion-display-none"></ion-back-button>
<ion-back-button class="ion-hide"></ion-back-button>
</ion-buttons>
<ion-title>Hidden</ion-title>
</ion-toolbar>

View File

@@ -361,7 +361,11 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
target,
};
let fill = this.fill;
if (fill === undefined) {
/**
* We check both undefined and null to
* work around https://github.com/ionic-team/stencil/issues/3586.
*/
if (fill == null) {
fill = this.inToolbar || this.inListHeader ? 'clear' : 'solid';
}

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

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1018 B

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 968 B

After

Width:  |  Height:  |  Size: 1004 B

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,6 +1,5 @@
import type { ComponentInterface, EventEmitter } from '@stencil/core';
import { Build, Component, Element, Event, Host, Method, Prop, State, h } from '@stencil/core';
import { checkInvalidState } from '@utils/forms';
import { Component, Element, Event, Host, Method, Prop, h } from '@stencil/core';
import type { Attributes } from '@utils/helpers';
import { inheritAriaAttributes, renderHiddenInput } from '@utils/helpers';
import { createColorClasses, hostContext } from '@utils/theme';
@@ -35,8 +34,8 @@ export class Checkbox implements ComponentInterface {
private inputLabelId = `${this.inputId}-lbl`;
private helperTextId = `${this.inputId}-helper-text`;
private errorTextId = `${this.inputId}-error-text`;
private focusEl?: HTMLElement;
private inheritedAttributes: Attributes = {};
private validationObserver?: MutationObserver;
@Element() el!: HTMLIonCheckboxElement;
@@ -122,13 +121,6 @@ export class Checkbox implements ComponentInterface {
*/
@Prop() required = false;
/**
* Track validation state for proper aria-live announcements.
*/
@State() isInvalid = false;
@State() private hintTextId?: string;
/**
* Emitted when the checked property has changed as a result of a user action such as a click.
*
@@ -146,69 +138,18 @@ export class Checkbox implements ComponentInterface {
*/
@Event() ionBlur!: EventEmitter<void>;
connectedCallback() {
const { el } = this;
// Watch for class changes to update validation state.
if (Build.isBrowser && typeof MutationObserver !== 'undefined') {
this.validationObserver = new MutationObserver(() => {
const newIsInvalid = checkInvalidState(el);
if (this.isInvalid !== newIsInvalid) {
this.isInvalid = newIsInvalid;
/**
* Screen readers tend to announce changes
* to `aria-describedby` when the attribute
* is changed during a blur event for a
* native form control.
* However, the announcement can be spotty
* when using a non-native form control
* and `forceUpdate()`.
* This is due to `forceUpdate()` internally
* rescheduling the DOM update to a lower
* priority queue regardless if it's called
* inside a Promise or not, thus causing
* the screen reader to potentially miss the
* change.
* By using a State variable inside a Promise,
* it guarantees a re-render immediately at
* a higher priority.
*/
Promise.resolve().then(() => {
this.hintTextId = this.getHintTextId();
});
}
});
this.validationObserver.observe(el, {
attributes: true,
attributeFilter: ['class'],
});
}
// Always set initial state
this.isInvalid = checkInvalidState(el);
}
componentWillLoad() {
this.inheritedAttributes = {
...inheritAriaAttributes(this.el),
};
this.hintTextId = this.getHintTextId();
}
disconnectedCallback() {
// Clean up validation observer to prevent memory leaks.
if (this.validationObserver) {
this.validationObserver.disconnect();
this.validationObserver = undefined;
}
}
/** @internal */
@Method()
async setFocus() {
this.el.focus();
if (this.focusEl) {
this.focusEl.focus();
}
}
/**
@@ -228,6 +169,7 @@ export class Checkbox implements ComponentInterface {
private toggleChecked = (ev: Event) => {
ev.preventDefault();
this.setFocus();
this.setChecked(!this.checked);
this.indeterminate = false;
};
@@ -265,10 +207,10 @@ export class Checkbox implements ComponentInterface {
ev.stopPropagation();
};
private getHintTextId(): string | undefined {
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
private getHintTextID(): string | undefined {
const { el, helperText, errorText, helperTextId, errorTextId } = this;
if (isInvalid && errorText) {
if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
return errorTextId;
}
@@ -284,7 +226,7 @@ export class Checkbox implements ComponentInterface {
* This element should only be rendered if hint text is set.
*/
private renderHintText() {
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
const { helperText, errorText, helperTextId, errorTextId } = this;
/**
* undefined and empty string values should
@@ -297,11 +239,11 @@ export class Checkbox implements ComponentInterface {
return (
<div class="checkbox-bottom">
<div id={helperTextId} class="helper-text" part="supporting-text helper-text" aria-live="polite">
{!isInvalid ? helperText : null}
<div id={helperTextId} class="helper-text" part="supporting-text helper-text">
{helperText}
</div>
<div id={errorTextId} class="error-text" part="supporting-text error-text" role="alert">
{isInvalid ? errorText : null}
<div id={errorTextId} class="error-text" part="supporting-text error-text">
{errorText}
</div>
</div>
);
@@ -336,17 +278,13 @@ export class Checkbox implements ComponentInterface {
<Host
role="checkbox"
aria-checked={indeterminate ? 'mixed' : `${checked}`}
aria-describedby={this.hintTextId}
aria-invalid={this.isInvalid ? 'true' : undefined}
aria-describedby={this.getHintTextID()}
aria-invalid={this.getHintTextID() === this.errorTextId}
aria-labelledby={hasLabelContent ? this.inputLabelId : null}
aria-label={inheritedAttributes['aria-label'] || null}
aria-disabled={disabled ? 'true' : null}
aria-required={required ? 'true' : undefined}
tabindex={disabled ? undefined : 0}
onKeyDown={this.onKeyDown}
onFocus={this.onFocus}
onBlur={this.onBlur}
onClick={this.onClick}
class={createColorClasses(color, {
[mode]: true,
'in-item': hostContext('ion-item', el),
@@ -358,6 +296,7 @@ export class Checkbox implements ComponentInterface {
[`checkbox-alignment-${alignment}`]: alignment !== undefined,
[`checkbox-label-placement-${labelPlacement}`]: true,
})}
onClick={this.onClick}
>
<label class="checkbox-wrapper" htmlFor={inputId}>
{/*
@@ -370,6 +309,9 @@ export class Checkbox implements ComponentInterface {
disabled={disabled}
id={inputId}
onChange={this.toggleChecked}
onFocus={() => this.onFocus()}
onBlur={() => this.onBlur()}
ref={(focusEl) => (this.focusEl = focusEl)}
required={required}
{...inheritedAttributes}
/>
@@ -386,7 +328,7 @@ export class Checkbox implements ComponentInterface {
{this.renderHintText()}
</div>
<div class="native-wrapper">
<svg class="checkbox-icon" viewBox="0 0 24 24" part="container" aria-hidden="true">
<svg class="checkbox-icon" viewBox="0 0 24 24" part="container">
{path}
</svg>
</div>

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -44,10 +44,7 @@ configs().forEach(({ title, screenshot, config }) => {
});
});
/**
* This behavior does not vary across modes/directions
*/
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
test.describe(title('checkbox: ionChange'), () => {
test('should fire ionChange when interacting with checkbox', async ({ page }) => {
await page.setContent(
@@ -136,195 +133,4 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, screenshot, c
expect(clickCount).toBe(1);
});
});
test.describe(title('checkbox: ionFocus'), () => {
test('should not have visual regressions', async ({ page, pageUtils }) => {
await page.setContent(
`
<style>
#container {
display: inline-block;
padding: 10px;
}
</style>
<div id="container">
<ion-checkbox>Unchecked</ion-checkbox>
</div>
`,
config
);
await pageUtils.pressKeys('Tab');
const container = page.locator('#container');
await expect(container).toHaveScreenshot(screenshot(`checkbox-focus`));
});
test('should not have visual regressions when interacting with checkbox in item', async ({ page, pageUtils }) => {
await page.setContent(
`
<ion-item class="ion-focused">
<ion-checkbox>Unchecked</ion-checkbox>
</ion-item>
`,
config
);
// Test focus with keyboard navigation
await pageUtils.pressKeys('Tab');
const item = page.locator('ion-item');
await expect(item).toHaveScreenshot(screenshot(`checkbox-in-item-focus`));
});
test('should fire ionFocus when checkbox is focused', async ({ page, pageUtils }) => {
await page.setContent(
`
<ion-checkbox aria-label="checkbox" value="my-checkbox"></ion-checkbox>
`,
config
);
const ionFocus = await page.spyOnEvent('ionFocus');
// Test focus with keyboard navigation
await pageUtils.pressKeys('Tab');
expect(ionFocus).toHaveReceivedEventTimes(1);
// Reset focus
const checkbox = page.locator('ion-checkbox');
const checkboxBoundingBox = (await checkbox.boundingBox())!;
await page.mouse.click(0, checkboxBoundingBox.height + 1);
// Test focus with click
await checkbox.click();
expect(ionFocus).toHaveReceivedEventTimes(2);
});
test('should fire ionFocus when interacting with checkbox in item', async ({ page, pageUtils }) => {
await page.setContent(
`
<ion-item>
<ion-checkbox aria-label="checkbox" value="my-checkbox"></ion-checkbox>
</ion-item>
`,
config
);
const ionFocus = await page.spyOnEvent('ionFocus');
// Test focus with keyboard navigation
await pageUtils.pressKeys('Tab');
expect(ionFocus).toHaveReceivedEventTimes(1);
// Verify that the event target is the checkbox and not the item
const eventByKeyboard = ionFocus.events[0];
expect((eventByKeyboard.target as HTMLElement).tagName.toLowerCase()).toBe('ion-checkbox');
// Reset focus
const checkbox = page.locator('ion-checkbox');
const checkboxBoundingBox = (await checkbox.boundingBox())!;
await page.mouse.click(0, checkboxBoundingBox.height + 1);
// Test focus with click
const item = page.locator('ion-item');
await item.click();
expect(ionFocus).toHaveReceivedEventTimes(2);
// Verify that the event target is the checkbox and not the item
const eventByClick = ionFocus.events[0];
expect((eventByClick.target as HTMLElement).tagName.toLowerCase()).toBe('ion-checkbox');
});
test('should not fire when programmatically setting a value', async ({ page }) => {
await page.setContent(
`
<ion-checkbox aria-label="checkbox" value="my-checkbox"></ion-checkbox>
`,
config
);
const ionFocus = await page.spyOnEvent('ionFocus');
const checkbox = page.locator('ion-checkbox');
await checkbox.evaluate((el: HTMLIonCheckboxElement) => (el.checked = true));
expect(ionFocus).not.toHaveReceivedEvent();
});
});
test.describe(title('checkbox: ionBlur'), () => {
test('should fire ionBlur when checkbox is blurred', async ({ page, pageUtils }) => {
await page.setContent(
`
<ion-checkbox aria-label="checkbox" value="my-checkbox"></ion-checkbox>
`,
config
);
const ionBlur = await page.spyOnEvent('ionBlur');
// Test blur with keyboard navigation
// Focus the checkbox
await pageUtils.pressKeys('Tab');
// Blur the checkbox
await pageUtils.pressKeys('Tab');
expect(ionBlur).toHaveReceivedEventTimes(1);
// Test blur with click
const checkbox = page.locator('ion-checkbox');
// Focus the checkbox
await checkbox.click();
// Blur the checkbox by clicking outside of it
const checkboxBoundingBox = (await checkbox.boundingBox())!;
await page.mouse.click(0, checkboxBoundingBox.height + 1);
expect(ionBlur).toHaveReceivedEventTimes(2);
});
test('should fire ionBlur after interacting with checkbox in item', async ({ page, pageUtils }) => {
await page.setContent(
`
<ion-item>
<ion-checkbox aria-label="checkbox" value="my-checkbox"></ion-checkbox>
</ion-item>
`,
config
);
const ionBlur = await page.spyOnEvent('ionBlur');
// Test blur with keyboard navigation
// Focus the checkbox
await pageUtils.pressKeys('Tab');
// Blur the checkbox
await pageUtils.pressKeys('Tab');
expect(ionBlur).toHaveReceivedEventTimes(1);
// Verify that the event target is the checkbox and not the item
const event = ionBlur.events[0];
expect((event.target as HTMLElement).tagName.toLowerCase()).toBe('ion-checkbox');
// Test blur with click
const item = page.locator('ion-item');
await item.click();
// Blur the checkbox by clicking outside of it
const itemBoundingBox = (await item.boundingBox())!;
await page.mouse.click(0, itemBoundingBox.height + 1);
expect(ionBlur).toHaveReceivedEventTimes(2);
// Verify that the event target is the checkbox and not the item
const eventByClick = ionBlur.events[0];
expect((eventByClick.target as HTMLElement).tagName.toLowerCase()).toBe('ion-checkbox');
});
});
});

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -50,20 +50,6 @@
<ion-checkbox checked style="width: 200px">Specified width</ion-checkbox><br />
<ion-checkbox checked style="width: 100%">Full-width</ion-checkbox><br />
</ion-content>
<script>
document.addEventListener('ionBlur', (ev) => {
console.log('ionBlur', ev);
});
document.addEventListener('ionChange', (ev) => {
console.log('ionChange', ev);
});
document.addEventListener('ionFocus', (ev) => {
console.log('ionFocus', ev);
});
</script>
</ion-app>
</body>
</html>

View File

@@ -246,20 +246,6 @@
</div>
</div>
</ion-content>
<script>
document.addEventListener('ionBlur', (ev) => {
console.log('ionBlur', ev);
});
document.addEventListener('ionChange', (ev) => {
console.log('ionChange', ev);
});
document.addEventListener('ionFocus', (ev) => {
console.log('ionFocus', ev);
});
</script>
</ion-app>
</body>
</html>

View File

@@ -1,184 +0,0 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Checkbox - Validation</title>
<meta
name="viewport"
content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
<style>
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-row-gap: 30px;
grid-column-gap: 30px;
}
h2 {
font-size: 12px;
font-weight: normal;
color: var(--ion-color-step-600);
margin-top: 10px;
margin-bottom: 5px;
}
.validation-info {
margin: 20px;
padding: 10px;
background: var(--ion-color-light);
border-radius: 4px;
}
</style>
</head>
<body>
<ion-app>
<ion-header>
<ion-toolbar>
<ion-title>Checkbox - Validation Test</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<div class="validation-info">
<h2>Screen Reader Testing Instructions:</h2>
<ol>
<li>Enable your screen reader (VoiceOver, NVDA, JAWS, etc.)</li>
<li>Tab through the form fields</li>
<li>When you tab away from an empty required field, the error should be announced immediately</li>
<li>The error text should be announced BEFORE the next field is announced</li>
<li>Test in Chrome, Safari, and Firefox to verify consistent behavior</li>
</ol>
</div>
<div class="grid">
<div>
<h2>Required Field</h2>
<ion-checkbox
id="terms-checkbox"
helper-text="You must agree to continue"
error-text="Please accept the terms and conditions"
required
>I agree to the terms and conditions</ion-checkbox
>
</div>
<div>
<h2>Optional Field (No Validation)</h2>
<ion-checkbox id="optional-checkbox" helper-text="You can skip this field">Optional Checkbox</ion-checkbox>
</div>
</div>
<div class="ion-padding">
<ion-button id="submit-btn" expand="block" disabled>Submit Form</ion-button>
<ion-button id="reset-btn" expand="block" fill="outline">Reset Form</ion-button>
</div>
</ion-content>
</ion-app>
<script>
// Simple validation logic
const checkboxes = document.querySelectorAll('ion-checkbox');
const submitBtn = document.getElementById('submit-btn');
const resetBtn = document.getElementById('reset-btn');
// Track which fields have been touched
const touchedFields = new Set();
// Validation functions
const validators = {
'terms-checkbox': (checked) => {
return checked === true;
},
'optional-checkbox': () => true, // Always valid
};
function validateField(checkbox) {
const checkboxId = checkbox.id;
const checked = checkbox.checked;
const isValid = validators[checkboxId] ? validators[checkboxId](checked) : true;
// Only show validation state if field has been touched
if (touchedFields.has(checkboxId)) {
if (isValid) {
checkbox.classList.remove('ion-invalid');
checkbox.classList.add('ion-valid');
} else {
checkbox.classList.remove('ion-valid');
checkbox.classList.add('ion-invalid');
}
checkbox.classList.add('ion-touched');
}
return isValid;
}
function validateForm() {
let allValid = true;
checkboxes.forEach((checkbox) => {
if (checkbox.id !== 'optional-checkbox') {
const isValid = validateField(checkbox);
if (!isValid) {
allValid = false;
}
}
});
submitBtn.disabled = !allValid;
return allValid;
}
// Add event listeners
checkboxes.forEach((checkbox) => {
// Mark as touched on blur
checkbox.addEventListener('ionBlur', (e) => {
console.log('Blur event on:', checkbox.id);
touchedFields.add(checkbox.id);
validateField(checkbox);
validateForm();
const isInvalid = checkbox.classList.contains('ion-invalid');
if (isInvalid) {
console.log('Field marked invalid:', checkbox.innerText, checkbox.errorText);
}
});
// Validate on change
checkbox.addEventListener('ionChange', (e) => {
console.log('Change event on:', checkbox.id);
if (touchedFields.has(checkbox.id)) {
validateField(checkbox);
validateForm();
}
});
});
// Reset button
resetBtn.addEventListener('click', () => {
checkboxes.forEach((checkbox) => {
checkbox.checked = false;
checkbox.classList.remove('ion-valid', 'ion-invalid', 'ion-touched');
});
touchedFields.clear();
submitBtn.disabled = true;
});
// Submit button
submitBtn.addEventListener('click', () => {
if (validateForm()) {
alert('Form submitted successfully!');
}
});
// Initial setup
validateForm();
</script>
</body>
</html>

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -22,15 +22,15 @@ export type DatetimePresentation = 'date-time' | 'time-date' | 'date' | 'time' |
export type TitleSelectedDatesFormatter = (selectedDates: string[]) => string;
/**
* DatetimeHighlightStyle must include textColor, backgroundColor, or border.
* It cannot be an empty object.
*/
export type DatetimeHighlightStyle = {
textColor?: string;
backgroundColor?: string;
border?: string;
} & ({ textColor: string } | { backgroundColor: string } | { border: string });
export type DatetimeHighlightStyle =
| {
textColor: string;
backgroundColor?: string;
}
| {
textColor?: string;
backgroundColor: string;
};
export type DatetimeHighlight = { date: string } & DatetimeHighlightStyle;

View File

@@ -3,7 +3,6 @@ import { Component, Element, Event, Host, Method, Prop, State, Watch, h, writeTa
import { startFocusVisible } from '@utils/focus-visible';
import { getElementRoot, raf, renderHiddenInput } from '@utils/helpers';
import { printIonError, printIonWarning } from '@utils/logging';
import { FOCUS_TRAP_DISABLE_CLASS } from '@utils/overlays';
import { isRTL } from '@utils/rtl';
import { createColorClasses } from '@utils/theme';
import { caretDownSharp, caretUpSharp, chevronBack, chevronDown, chevronForward } from 'ionicons/icons';
@@ -1599,7 +1598,7 @@ export class Datetime implements ComponentInterface {
forcePresentation === 'time-date'
? [this.renderTimePickerColumns(forcePresentation), this.renderDatePickerColumns(forcePresentation)]
: [this.renderDatePickerColumns(forcePresentation), this.renderTimePickerColumns(forcePresentation)];
return <ion-picker class={FOCUS_TRAP_DISABLE_CLASS}>{renderArray}</ion-picker>;
return <ion-picker>{renderArray}</ion-picker>;
}
private renderDatePickerColumns(forcePresentation: string) {
@@ -2336,7 +2335,6 @@ export class Datetime implements ComponentInterface {
`${dateStyle ? dateStyle.backgroundColor : ''}`,
'important'
);
el.style.setProperty('border', `${dateStyle ? dateStyle.border : ''}`, 'important');
}
}}
tabindex="-1"

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

@@ -5,8 +5,6 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
test.describe(title('datetime: custom'), () => {
test.beforeEach(async ({ page }) => {
await page.goto(`/src/components/datetime/test/custom`, config);
await page.locator('.datetime-ready').last().waitFor();
});
test('should allow styling wheel style datetimes', async ({ page }) => {
@@ -32,13 +30,6 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
test('should allow styling calendar days in grid style datetimes', async ({ page }) => {
const datetime = page.locator('#custom-calendar-days');
// Wait for calendar days to be rendered
await page.waitForFunction(() => {
const datetime = document.querySelector('#custom-calendar-days');
const calendarDays = datetime?.shadowRoot?.querySelectorAll('.calendar-day');
return calendarDays && calendarDays.length > 0;
});
await expect(datetime).toHaveScreenshot(screenshot(`datetime-custom-calendar-days`));
});
});

View File

@@ -164,7 +164,7 @@
const customDatetime = document.querySelector('#custom-calendar-days');
// Mock the current day to always have the same screenshots
const mockToday = '2023-06-10T16:22:00.000Z';
const mockToday = '2023-06-10T16:22';
Date = class extends Date {
constructor(...args) {
if (args.length === 0) {

View File

@@ -22,23 +22,11 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
await expect(monthYearToggle).toContainText('January 2022');
// Click to open the picker
await monthYearToggle.click();
await page.waitForChanges();
// Wait for the picker to be open
await page.locator('.month-year-picker-open').waitFor();
// Wait a bit for the picker to fully load
await page.waitForTimeout(200);
const ionChange = await page.spyOnEvent('ionChange');
// Click on February
await monthColumnItems.filter({ hasText: 'February' }).click();
// Wait for changes
await ionChange.next();
// February
await monthColumnItems.nth(1).click();
await page.waitForChanges();
await expect(monthYearToggle).toContainText('February 2022');
@@ -50,23 +38,13 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
const datetime = page.locator('ion-datetime');
const ionChange = await page.spyOnEvent('ionChange');
// Click to open the picker
await monthYearToggle.click();
await page.waitForChanges();
// Wait for the picker to be open
await page.locator('.month-year-picker-open').waitFor();
// February
await monthColumnItems.nth(1).click();
// Wait a bit for the picker to fully load
await page.waitForTimeout(200);
// Click on February
await monthColumnItems.filter({ hasText: 'February' }).click();
// Wait for changes
await ionChange.next();
await page.waitForChanges();
await expect(ionChange).toHaveReceivedEventTimes(1);
await expect(datetime).toHaveJSProperty('value', '2022-02-28');
});

View File

@@ -21,19 +21,16 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
date: '2023-01-01', // ensure selected date style overrides highlight
textColor: '#800080',
backgroundColor: '#ffc0cb',
border: '2px solid purple',
},
{
date: '2023-01-02',
textColor: '#b22222',
backgroundColor: '#fa8072',
border: '2px solid purple',
},
{
date: '2023-01-03',
textColor: '#0000ff',
backgroundColor: '#add8e6',
border: '2px solid purple',
},
];
});
@@ -55,7 +52,6 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
return {
textColor: '#b22222',
backgroundColor: '#fa8072',
border: '2px solid purple',
};
}
@@ -63,7 +59,6 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
return {
textColor: '#800080',
backgroundColor: '#ffc0cb',
border: '2px solid purple',
};
}
@@ -71,7 +66,6 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
return {
textColor: '#0000ff',
backgroundColor: '#add8e6',
border: '2px solid purple',
};
}
@@ -83,7 +77,7 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
await expect(datetime).toHaveScreenshot(screenshot(`datetime-highlightedDates-callback`));
});
test('should render highlights correctly when only using only one color property', async ({ page }) => {
test('should render highlights correctly when only using one color or the other', async ({ page }) => {
const datetime = page.locator('ion-datetime');
await datetime.evaluate((el: HTMLIonDatetimeElement) => {
@@ -96,10 +90,6 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
date: '2023-01-03',
textColor: '#0000ff',
},
{
date: '2023-01-04',
border: '2px solid purple',
},
];
});

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -78,10 +78,6 @@
textColor: 'blue',
backgroundColor: 'lightblue',
},
{
date: '2023-01-07',
border: '2px dotted red',
},
];
document.querySelector('#withCallback').highlightedDates = (isoString) => {
@@ -107,7 +103,6 @@
date: new Date().toISOString().split('T')[0],
textColor: 'purple',
backgroundColor: 'pink',
border: '2px solid purple',
},
];
</script>

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

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