Compare commits
14 Commits
ionic-modu
...
ROU-11368
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e619c72d43 | ||
|
|
07d257f7f5 | ||
|
|
12ad1ed76c | ||
|
|
131de8b8ea | ||
|
|
74710d4cf6 | ||
|
|
3626302d32 | ||
|
|
c1574ffe1f | ||
|
|
e50ba30c22 | ||
|
|
7ba6b9d0c2 | ||
|
|
56b8b1de81 | ||
|
|
a1ea905c97 | ||
|
|
22ce04fc88 | ||
|
|
fbe3116ed5 | ||
|
|
120fabbc98 |
67
.github/ionic-issue-bot.yml
vendored
@@ -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"
|
||||
|
||||
@@ -3,23 +3,23 @@ description: 'Build Ionic Angular Server'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -8,20 +8,20 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.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
|
||||
@@ -29,4 +29,4 @@ runs:
|
||||
with:
|
||||
name: ionic-core
|
||||
output: core/CoreBuild.zip
|
||||
paths: core/dist core/components core/src/foundations core/css core/themes core/hydrate core/loader core/src/components.d.ts
|
||||
paths: core/dist core/components core/src/foundations core/css core/hydrate core/loader core/src/components.d.ts
|
||||
|
||||
16
.github/workflows/actions/build-core/action.yml
vendored
@@ -8,22 +8,22 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.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/src/foundations core/css core/themes 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/src/foundations core/css core/hydrate core/loader core/src/components.d.ts core/api.txt
|
||||
|
||||
@@ -3,9 +3,9 @@ description: 'Build Ionic React Router'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.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
|
||||
|
||||
16
.github/workflows/actions/build-react/action.yml
vendored
@@ -3,35 +3,35 @@ description: 'Build Ionic React'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.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
|
||||
|
||||
@@ -3,9 +3,9 @@ description: 'Builds Ionic Vue Router'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.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
|
||||
|
||||
14
.github/workflows/actions/build-vue/action.yml
vendored
@@ -3,31 +3,31 @@ description: 'Build Ionic Vue'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.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
|
||||
|
||||
@@ -10,10 +10,10 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/download-artifact@v7
|
||||
- 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
|
||||
|
||||
@@ -8,53 +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@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ inputs.node-version }}
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
scope: '@ionic'
|
||||
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 }}
|
||||
|
||||
@@ -6,9 +6,9 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.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 }}
|
||||
|
||||
@@ -3,16 +3,16 @@ description: 'Test Core Clean Build'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.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"
|
||||
|
||||
@@ -3,21 +3,21 @@ description: 'Test Core Lint'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.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
|
||||
|
||||
@@ -13,19 +13,19 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.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@v6
|
||||
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
|
||||
|
||||
@@ -6,14 +6,14 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.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
|
||||
|
||||
@@ -6,9 +6,9 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.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 }}
|
||||
|
||||
@@ -6,9 +6,9 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.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 }}
|
||||
|
||||
@@ -6,9 +6,9 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.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 }}
|
||||
|
||||
@@ -7,13 +7,13 @@ on:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24.x
|
||||
- uses: actions/download-artifact@v7
|
||||
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.
|
||||
|
||||
@@ -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@v6
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.name }}
|
||||
path: ${{ inputs.output }}
|
||||
|
||||
2
.github/workflows/assign-issues.yml
vendored
@@ -13,6 +13,6 @@ jobs:
|
||||
- name: 'Auto-assign issue'
|
||||
uses: pozil/auto-assign-issue@39c06395cbac76e79afc4ad4e5c5c6db6ecfdd2e # v2.2.0
|
||||
with:
|
||||
assignees: brandyscarney, thetaPC, ShaneK
|
||||
assignees: brandyscarney, ShaneK
|
||||
numOfAssignee: 1
|
||||
allowSelfAssign: false
|
||||
|
||||
30
.github/workflows/build.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
build-core:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/workflows/actions/build-vue
|
||||
|
||||
build-vue-router:
|
||||
needs: [build-vue]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/workflows/actions/build-angular
|
||||
|
||||
build-angular-server:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/workflows/actions/build-react
|
||||
|
||||
build-react-router:
|
||||
needs: [build-react]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/workflows/actions/test-react-e2e
|
||||
with:
|
||||
app: ${{ matrix.apps }}
|
||||
|
||||
6
.github/workflows/codeql-analysis.yml
vendored
@@ -14,8 +14,8 @@ jobs:
|
||||
permissions:
|
||||
security-events: write
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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
|
||||
|
||||
2
.github/workflows/conventional-commit.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
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:
|
||||
|
||||
11
.github/workflows/dev-build.yml
vendored
@@ -1,11 +1,7 @@
|
||||
name: 'Ionic Dev Build'
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
create-dev-hash:
|
||||
@@ -13,7 +9,7 @@ jobs:
|
||||
outputs:
|
||||
dev-hash: ${{ steps.create-dev-hash.outputs.DEV_HASH }}
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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
|
||||
@@ -29,12 +25,13 @@ jobs:
|
||||
release-ionic:
|
||||
needs: [create-dev-hash]
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
uses: ./.github/workflows/release-ionic.yml
|
||||
with:
|
||||
tag: dev
|
||||
version: ${{ needs.create-dev-hash.outputs.dev-hash }}
|
||||
secrets:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
get-build:
|
||||
name: Get your dev build!
|
||||
|
||||
2
.github/workflows/label.yml
vendored
@@ -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
|
||||
|
||||
15
.github/workflows/nightly.yml
vendored
@@ -1,11 +1,10 @@
|
||||
name: 'Ionic Nightly Build'
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
schedule:
|
||||
# Run every Monday-Friday
|
||||
# at 6:00 UTC (6:00 am UTC)
|
||||
- cron: '00 06 * * 1-5'
|
||||
|
||||
jobs:
|
||||
create-nightly-hash:
|
||||
@@ -13,7 +12,7 @@ jobs:
|
||||
outputs:
|
||||
nightly-hash: ${{ steps.create-nightly-hash.outputs.NIGHTLY_HASH }}
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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
|
||||
@@ -31,10 +30,10 @@ jobs:
|
||||
release-ionic:
|
||||
needs: [create-nightly-hash]
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
uses: ./.github/workflows/release-ionic.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
tag: nightly
|
||||
version: ${{ needs.create-nightly-hash.outputs.nightly-hash }}
|
||||
secrets:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
47
.github/workflows/release-ionic.yml
vendored
@@ -14,23 +14,23 @@ 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: ./.github/actions/publish-npm
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/workflows/actions/publish-npm
|
||||
with:
|
||||
scope: '@ionic/core'
|
||||
tag: ${{ inputs.tag }}
|
||||
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,33 +48,34 @@ jobs:
|
||||
needs: [release-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/checkout@v4
|
||||
- name: Restore @ionic/docs built cache
|
||||
uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-docs
|
||||
path: ./packages/docs
|
||||
filename: DocsBuild.zip
|
||||
- uses: ./.github/actions/publish-npm
|
||||
- uses: ./.github/workflows/actions/publish-npm
|
||||
with:
|
||||
scope: '@ionic/docs'
|
||||
tag: ${{ inputs.tag }}
|
||||
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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/checkout@v4
|
||||
- name: Restore @ionic/core built cache
|
||||
uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- uses: ./.github/actions/publish-npm
|
||||
- uses: ./.github/workflows/actions/publish-npm
|
||||
with:
|
||||
scope: '@ionic/angular'
|
||||
tag: ${{ inputs.tag }}
|
||||
@@ -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,20 +95,21 @@ jobs:
|
||||
needs: [release-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/checkout@v4
|
||||
- name: Restore @ionic/core built cache
|
||||
uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- uses: ./.github/actions/publish-npm
|
||||
- uses: ./.github/workflows/actions/publish-npm
|
||||
with:
|
||||
scope: '@ionic/react'
|
||||
tag: ${{ inputs.tag }}
|
||||
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,20 +121,21 @@ jobs:
|
||||
needs: [release-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/checkout@v4
|
||||
- name: Restore @ionic/core built cache
|
||||
uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- uses: ./.github/actions/publish-npm
|
||||
- uses: ./.github/workflows/actions/publish-npm
|
||||
with:
|
||||
scope: '@ionic/vue'
|
||||
tag: ${{ inputs.tag }}
|
||||
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,14 +147,14 @@ jobs:
|
||||
needs: [release-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/checkout@v4
|
||||
- name: Restore @ionic/core built cache
|
||||
uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- uses: ./.github/actions/publish-npm
|
||||
- uses: ./.github/workflows/actions/publish-npm
|
||||
with:
|
||||
scope: '@ionic/angular-server'
|
||||
tag: ${{ inputs.tag }}
|
||||
@@ -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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/checkout@v4
|
||||
- name: Restore @ionic/core built cache
|
||||
uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
@@ -176,19 +181,20 @@ jobs:
|
||||
name: ionic-react
|
||||
path: ./packages/react
|
||||
filename: ReactBuild.zip
|
||||
- uses: ./.github/actions/publish-npm
|
||||
- uses: ./.github/workflows/actions/publish-npm
|
||||
with:
|
||||
scope: '@ionic/react-router'
|
||||
tag: ${{ inputs.tag }}
|
||||
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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/checkout@v4
|
||||
- name: Restore @ionic/core built cache
|
||||
uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
@@ -201,10 +207,11 @@ jobs:
|
||||
name: ionic-vue
|
||||
path: ./packages/vue
|
||||
filename: VueBuild.zip
|
||||
- uses: ./.github/actions/publish-npm
|
||||
- uses: ./.github/workflows/actions/publish-npm
|
||||
with:
|
||||
scope: '@ionic/vue-router'
|
||||
tag: ${{ inputs.tag }}
|
||||
version: ${{ inputs.version }}
|
||||
preid: ${{ inputs.preid }}
|
||||
working-directory: 'packages/vue-router'
|
||||
token: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
81
.github/workflows/release-orchestrator.yml
vendored
@@ -1,81 +0,0 @@
|
||||
name: 'Release - Ionic Framework'
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Run every Monday-Friday
|
||||
# at 6:00 UTC (6:00 am UTC)
|
||||
- cron: '00 06 * * 1-5'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
release-type:
|
||||
description: 'Which Ionic release workflow should run?'
|
||||
required: true
|
||||
type: choice
|
||||
default: dev
|
||||
options:
|
||||
- dev
|
||||
- production
|
||||
version:
|
||||
description: 'Which version should be published? (Only for production releases)'
|
||||
required: false
|
||||
type: choice
|
||||
options:
|
||||
- patch
|
||||
- minor
|
||||
- major
|
||||
- prepatch
|
||||
- preminor
|
||||
- premajor
|
||||
- prerelease
|
||||
tag:
|
||||
description: 'Which npm tag should this be published to? (Only for production releases)'
|
||||
required: false
|
||||
type: choice
|
||||
default: latest
|
||||
options:
|
||||
- latest
|
||||
- next
|
||||
preid:
|
||||
description: 'Which prerelease identifier should be used? (Only for production releases)'
|
||||
required: false
|
||||
type: choice
|
||||
default: ''
|
||||
options:
|
||||
- ''
|
||||
- alpha
|
||||
- beta
|
||||
- rc
|
||||
- next
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
run-nightly:
|
||||
if: ${{ github.event_name == 'schedule' }}
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
uses: ./.github/workflows/nightly.yml
|
||||
secrets: inherit
|
||||
|
||||
run-dev:
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && inputs.release-type == 'dev' }}
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
uses: ./.github/workflows/dev-build.yml
|
||||
secrets: inherit
|
||||
|
||||
run-production:
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && inputs.release-type == 'production' }}
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
uses: ./.github/workflows/release.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
version: ${{ inputs.version }}
|
||||
tag: ${{ inputs.tag }}
|
||||
preid: ${{ inputs.preid }}
|
||||
69
.github/workflows/release.yml
vendored
@@ -1,64 +1,54 @@
|
||||
name: 'Ionic Production Release'
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Which version should be published?'
|
||||
required: true
|
||||
type: string
|
||||
type: choice
|
||||
description: Which version should be published?
|
||||
options:
|
||||
- patch
|
||||
- minor
|
||||
- major
|
||||
- prepatch
|
||||
- preminor
|
||||
- premajor
|
||||
- prerelease
|
||||
tag:
|
||||
description: 'Which npm tag should this be published to?'
|
||||
required: true
|
||||
type: string
|
||||
type: choice
|
||||
description: Which npm tag should this be published to?
|
||||
options:
|
||||
- latest
|
||||
- next
|
||||
preid:
|
||||
description: 'Which prerelease identifier should be used? This is only needed when version is "prepatch", "preminor", "premajor", or "prerelease".'
|
||||
required: false
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
type: choice
|
||||
description: Which prerelease identifier should be used? This is only needed when version is "prepatch", "preminor", "premajor", or "prerelease".
|
||||
options:
|
||||
- ''
|
||||
- alpha
|
||||
- beta
|
||||
- rc
|
||||
- next
|
||||
|
||||
jobs:
|
||||
validate_version:
|
||||
name: ✅ Validate Version Input
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 🔎 Ensure version is allowed
|
||||
env:
|
||||
VERSION: ${{ inputs.version }}
|
||||
run: |
|
||||
case "$VERSION" in
|
||||
patch|minor|major|prepatch|preminor|premajor|prerelease)
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "::error::Invalid version input: '$VERSION'. Allowed values: patch, minor, major, prepatch, preminor, premajor, prerelease."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shell: bash
|
||||
|
||||
release-ionic:
|
||||
needs: [validate_version]
|
||||
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
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.IONITRON_TOKEN }}
|
||||
fetch-depth: 0
|
||||
@@ -85,11 +75,8 @@ jobs:
|
||||
# possible for them to push at the same time.
|
||||
needs: [finalize-release]
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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
|
||||
|
||||
62
.github/workflows/stencil-nightly.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
build-core-with-stencil-nightly:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/workflows/actions/build-vue
|
||||
|
||||
build-vue-router:
|
||||
needs: [build-vue]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/workflows/actions/build-react
|
||||
|
||||
build-react-router:
|
||||
needs: [build-react]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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, 'failure') }}
|
||||
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}}
|
||||
|
||||
6
.github/workflows/update-screenshots.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
build-core:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- uses: actions/checkout@v4
|
||||
# Normally, we could just push with the
|
||||
# default GITHUB_TOKEN, but that will
|
||||
# not cause the build workflow
|
||||
|
||||
1
.gitignore
vendored
@@ -23,7 +23,6 @@ temp/
|
||||
core/theme-builder/
|
||||
core/test-components/
|
||||
core/css/
|
||||
core/themes/
|
||||
$RECYCLE.BIN/
|
||||
|
||||
.DS_Store
|
||||
|
||||
109
BREAKING.md
@@ -18,7 +18,6 @@ This is a comprehensive list of the breaking changes introduced in the major ver
|
||||
- [Button](#version-9x-button)
|
||||
- [Card](#version-9x-card)
|
||||
- [Chip](#version-9x-chip)
|
||||
- [Grid](#version-9x-grid)
|
||||
|
||||
<h2 id="version-9x-components">Components</h2>
|
||||
|
||||
@@ -33,111 +32,3 @@ This is a comprehensive list of the breaking changes introduced in the major ver
|
||||
<h4 id="version-9x-chip">Chip</h4>
|
||||
|
||||
- The `border-radius` of the `ios` and `md` chip now defaults to `10px` and `8px`, respectively, instead of `16px` in accordance with the iOS and Material Design 3 guidelines. To revert to the previous appearance, set the `shape` to `"round"`, or override the `--border-radius` CSS variable to specify a different value.
|
||||
|
||||
<h4 id="version-9x-grid">Grid</h4>
|
||||
|
||||
- The properties `pull` and `push` have been deprecated and no longer work. A similar look can be achieved with the newly added property `order`.
|
||||
|
||||
<h4 id="version-9x-radio-group">Radio Group</h4>
|
||||
|
||||
- Converted `ion-radio-group` to use [Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM).<br/>
|
||||
If you were targeting the internals of `ion-radio-group` in your CSS, you will need to target the `supporting-text`, `helper-text` or `error-text` [Shadow Parts](https://ionicframework.com/docs/theming/css-shadow-parts) instead, or use the provided CSS Variables.<br/>
|
||||
Additionally, the `radio-group-wrapper` div element has been removed, causing slotted elements to be direct children of the `ion-radio-group`.
|
||||
|
||||
<h5>Example 1: Swap two columns</h5>
|
||||
|
||||
**Version up to 8.x**
|
||||
```html
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col push="4">1</ion-col>
|
||||
<ion-col pull="4">2</ion-col>
|
||||
<ion-col>3</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
```
|
||||
**Version 9.x+**
|
||||
```html
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col order="2">1</ion-col>
|
||||
<ion-col order="1">2</ion-col>
|
||||
<ion-col order="3">3</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
```
|
||||
|
||||
<h5>Example 2: Reorder columns with specific sizes</h5>
|
||||
To reorder two columns where column 1 has `size="9" push="3"` and column 2 has `size="3" pull="9"`:
|
||||
|
||||
**Version up to 8.x**
|
||||
```html
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col push="3">1</ion-col>
|
||||
<ion-col pull="9">2</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
```
|
||||
**Version 9.x+**
|
||||
```html
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col order="2">1</ion-col>
|
||||
<ion-col size="3" order="1">2</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
```
|
||||
<h5>Example 3: Push</h5>
|
||||
```html
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col size="auto" push="1">
|
||||
<div>ion-col push 1</div>
|
||||
</ion-col>
|
||||
<ion-col size="auto" push="1">
|
||||
<div>ion-col push 1</div>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
```
|
||||
**Version 9.x+**
|
||||
```html
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col size="auto" offset="1">
|
||||
<div>ion-col size="auto" offset="1"</div>
|
||||
</ion-col>
|
||||
<ion-col size="auto">
|
||||
<div>ion-col size="auto"</div>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
```
|
||||
|
||||
<h5>Example 4: Push and Pull</h5>
|
||||
```html
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col size="3" size-md="6" push="9" push-md="6">
|
||||
<div>ion-col size="3" size-md="6" push="9" push-md="6"</div>
|
||||
</ion-col>
|
||||
<ion-col size="9" size-md="6" pull="3" pull-md="6">
|
||||
<div>ion-col size="9" size-md="6" pull="3" pull-md="6"</div>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
```
|
||||
**Version 9.x+**
|
||||
```html
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col size="auto" order="2" order-md="2">
|
||||
<div>ion-col size="auto" order="2" order-md="2"</div>
|
||||
</ion-col>
|
||||
<ion-col size="auto" order="1" order-md="1">
|
||||
<div>ion-col size="auto" order="1" order-md="1"</div>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
```
|
||||
186
CHANGELOG.md
@@ -3,192 +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.13](https://github.com/ionic-team/ionic-framework/compare/v8.7.12...v8.7.13) (2025-12-13)
|
||||
|
||||
**Note:** Version bump only for package ionic-framework
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [8.7.12](https://github.com/ionic-team/ionic-framework/compare/v8.7.11...v8.7.12) (2025-12-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **modal:** allow interaction with parent content through sheet modals in child routes ([#30839](https://github.com/ionic-team/ionic-framework/issues/30839)) ([b9e3cf0](https://github.com/ionic-team/ionic-framework/commit/b9e3cf0f5aae79a1f27a07b102c77e51f24825f4)), closes [#30700](https://github.com/ionic-team/ionic-framework/issues/30700)
|
||||
* **modal:** prevent browser hang when using ModalController in Angular ([#30845](https://github.com/ionic-team/ionic-framework/issues/30845)) ([b164516](https://github.com/ionic-team/ionic-framework/commit/b1645168a7fb9378dc39a081c207b2de0e180089))
|
||||
* **popover:** recalculate the content dimensions after the header has fully loaded ([#30853](https://github.com/ionic-team/ionic-framework/issues/30853)) ([99dcf38](https://github.com/ionic-team/ionic-framework/commit/99dcf3810a0c32416996d1e992ddf63359965cfc))
|
||||
* **select, action-sheet:** use radio role for options ([#30769](https://github.com/ionic-team/ionic-framework/issues/30769)) ([1c89cf0](https://github.com/ionic-team/ionic-framework/commit/1c89cf06ac959f9c9a35a66f811227c244d3198b))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [8.7.11](https://github.com/ionic-team/ionic-framework/compare/v8.7.10...v8.7.11) (2025-11-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **datetime:** ensure datetime is shown when intersection observer fails to report visibility ([#30793](https://github.com/ionic-team/ionic-framework/issues/30793)) ([9d781db](https://github.com/ionic-team/ionic-framework/commit/9d781db662d213090d0b7198d0cdc5abb16fed1b)), closes [#30706](https://github.com/ionic-team/ionic-framework/issues/30706)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [8.7.10](https://github.com/ionic-team/ionic-framework/compare/v8.7.9...v8.7.10) (2025-11-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **checkbox, toggle, radio-group:** improve screen reader announcement timing for validation errors ([#30714](https://github.com/ionic-team/ionic-framework/issues/30714)) ([92db364](https://github.com/ionic-team/ionic-framework/commit/92db36489cca944caf1593dbd518a1f025a171a2))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [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)
|
||||
|
||||
|
||||
|
||||
@@ -3,190 +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.13](https://github.com/ionic-team/ionic-framework/compare/v8.7.12...v8.7.13) (2025-12-13)
|
||||
|
||||
**Note:** Version bump only for package @ionic/core
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [8.7.12](https://github.com/ionic-team/ionic-framework/compare/v8.7.11...v8.7.12) (2025-12-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **modal:** allow interaction with parent content through sheet modals in child routes ([#30839](https://github.com/ionic-team/ionic-framework/issues/30839)) ([b9e3cf0](https://github.com/ionic-team/ionic-framework/commit/b9e3cf0f5aae79a1f27a07b102c77e51f24825f4)), closes [#30700](https://github.com/ionic-team/ionic-framework/issues/30700)
|
||||
* **modal:** prevent browser hang when using ModalController in Angular ([#30845](https://github.com/ionic-team/ionic-framework/issues/30845)) ([b164516](https://github.com/ionic-team/ionic-framework/commit/b1645168a7fb9378dc39a081c207b2de0e180089))
|
||||
* **popover:** recalculate the content dimensions after the header has fully loaded ([#30853](https://github.com/ionic-team/ionic-framework/issues/30853)) ([99dcf38](https://github.com/ionic-team/ionic-framework/commit/99dcf3810a0c32416996d1e992ddf63359965cfc))
|
||||
* **select, action-sheet:** use radio role for options ([#30769](https://github.com/ionic-team/ionic-framework/issues/30769)) ([1c89cf0](https://github.com/ionic-team/ionic-framework/commit/1c89cf06ac959f9c9a35a66f811227c244d3198b))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [8.7.11](https://github.com/ionic-team/ionic-framework/compare/v8.7.10...v8.7.11) (2025-11-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **datetime:** ensure datetime is shown when intersection observer fails to report visibility ([#30793](https://github.com/ionic-team/ionic-framework/issues/30793)) ([9d781db](https://github.com/ionic-team/ionic-framework/commit/9d781db662d213090d0b7198d0cdc5abb16fed1b)), closes [#30706](https://github.com/ionic-team/ionic-framework/issues/30706)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [8.7.10](https://github.com/ionic-team/ionic-framework/compare/v8.7.9...v8.7.10) (2025-11-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **checkbox, toggle, radio-group:** improve screen reader announcement timing for validation errors ([#30714](https://github.com/ionic-team/ionic-framework/issues/30714)) ([92db364](https://github.com/ionic-team/ionic-framework/commit/92db36489cca944caf1593dbd518a1f025a171a2))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [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)
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Get Playwright
|
||||
FROM mcr.microsoft.com/playwright:v1.56.1
|
||||
FROM mcr.microsoft.com/playwright:v1.54.1
|
||||
|
||||
# Set the working directory
|
||||
WORKDIR /ionic
|
||||
|
||||
37
core/api.txt
@@ -596,17 +596,23 @@ ion-checkbox,part,supporting-text
|
||||
ion-chip,shadow
|
||||
ion-chip,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||
ion-chip,prop,disabled,boolean,false,false,false
|
||||
ion-chip,prop,fill,"outline" | "solid" | undefined,undefined,false,false
|
||||
ion-chip,prop,hue,"bold" | "subtle" | undefined,undefined,false,false
|
||||
ion-chip,prop,hue,"bold" | "subtle" | undefined,'subtle',false,false
|
||||
ion-chip,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-chip,prop,outline,boolean,false,false,false
|
||||
ion-chip,prop,shape,"rectangular" | "round" | "soft" | undefined,undefined,false,false
|
||||
ion-chip,prop,size,"large" | "small" | undefined,undefined,false,false
|
||||
ion-chip,css-prop,--border-radius
|
||||
ion-chip,css-prop,--color
|
||||
ion-chip,css-prop,--focus-ring-color
|
||||
ion-chip,css-prop,--focus-ring-style
|
||||
ion-chip,css-prop,--focus-ring-width
|
||||
ion-chip,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-chip,css-prop,--background,ionic
|
||||
ion-chip,css-prop,--background,ios
|
||||
ion-chip,css-prop,--background,md
|
||||
ion-chip,css-prop,--border-radius,ionic
|
||||
ion-chip,css-prop,--border-radius,ios
|
||||
ion-chip,css-prop,--border-radius,md
|
||||
ion-chip,css-prop,--color,ionic
|
||||
ion-chip,css-prop,--color,ios
|
||||
ion-chip,css-prop,--color,md
|
||||
ion-chip,css-prop,--focus-ring-color,ionic
|
||||
ion-chip,css-prop,--focus-ring-width,ionic
|
||||
|
||||
ion-col,shadow
|
||||
ion-col,prop,mode,"ios" | "md",undefined,false,false
|
||||
@@ -616,12 +622,6 @@ ion-col,prop,offsetMd,string | undefined,undefined,false,false
|
||||
ion-col,prop,offsetSm,string | undefined,undefined,false,false
|
||||
ion-col,prop,offsetXl,string | undefined,undefined,false,false
|
||||
ion-col,prop,offsetXs,string | undefined,undefined,false,false
|
||||
ion-col,prop,order,string | undefined,undefined,false,false
|
||||
ion-col,prop,orderLg,string | undefined,undefined,false,false
|
||||
ion-col,prop,orderMd,string | undefined,undefined,false,false
|
||||
ion-col,prop,orderSm,string | undefined,undefined,false,false
|
||||
ion-col,prop,orderXl,string | undefined,undefined,false,false
|
||||
ion-col,prop,orderXs,string | undefined,undefined,false,false
|
||||
ion-col,prop,pull,string | undefined,undefined,false,false
|
||||
ion-col,prop,pullLg,string | undefined,undefined,false,false
|
||||
ion-col,prop,pullMd,string | undefined,undefined,false,false
|
||||
@@ -641,7 +641,6 @@ ion-col,prop,sizeSm,string | undefined,undefined,false,false
|
||||
ion-col,prop,sizeXl,string | undefined,undefined,false,false
|
||||
ion-col,prop,sizeXs,string | undefined,undefined,false,false
|
||||
ion-col,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-col,css-prop,--col-unit-size
|
||||
ion-col,css-prop,--ion-grid-column-padding
|
||||
ion-col,css-prop,--ion-grid-column-padding-lg
|
||||
ion-col,css-prop,--ion-grid-column-padding-md
|
||||
@@ -920,7 +919,6 @@ ion-infinite-scroll,none
|
||||
ion-infinite-scroll,prop,disabled,boolean,false,false,false
|
||||
ion-infinite-scroll,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-infinite-scroll,prop,position,"bottom" | "top",'bottom',false,false
|
||||
ion-infinite-scroll,prop,preserveRerenderScrollPosition,boolean,false,false,false
|
||||
ion-infinite-scroll,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-infinite-scroll,prop,threshold,string,'15%',false,false
|
||||
ion-infinite-scroll,method,complete,complete() => Promise<void>
|
||||
@@ -1839,7 +1837,7 @@ ion-radio,part,container
|
||||
ion-radio,part,label
|
||||
ion-radio,part,mark
|
||||
|
||||
ion-radio-group,shadow
|
||||
ion-radio-group,none
|
||||
ion-radio-group,prop,allowEmptySelection,boolean,false,false,false
|
||||
ion-radio-group,prop,compareWith,((currentValue: any, compareValue: any) => boolean) | null | string | undefined,undefined,false,false
|
||||
ion-radio-group,prop,errorText,string | undefined,undefined,false,false
|
||||
@@ -1849,9 +1847,6 @@ ion-radio-group,prop,name,string,this.inputId,false,false
|
||||
ion-radio-group,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-radio-group,prop,value,any,undefined,false,false
|
||||
ion-radio-group,event,ionChange,RadioGroupChangeEventDetail<any>,true
|
||||
ion-radio-group,part,error-text
|
||||
ion-radio-group,part,helper-text
|
||||
ion-radio-group,part,supporting-text
|
||||
|
||||
ion-range,shadow
|
||||
ion-range,prop,activeBarStart,number | undefined,undefined,false,false
|
||||
@@ -1954,9 +1949,6 @@ ion-reorder-group,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-reorder-group,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-reorder-group,method,complete,complete(listOrReorder?: boolean | any[]) => Promise<any>
|
||||
ion-reorder-group,event,ionItemReorder,ItemReorderEventDetail,true
|
||||
ion-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,mode,"ios" | "md",undefined,false,false
|
||||
@@ -2010,7 +2002,6 @@ ion-router-outlet,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-row,shadow
|
||||
ion-row,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-row,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-row,css-prop,--ion-grid-gap
|
||||
|
||||
ion-searchbar,scoped
|
||||
ion-searchbar,prop,animated,boolean,false,false,false
|
||||
|
||||
4202
core/package-lock.json
generated
@@ -1,10 +1,7 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "8.7.13",
|
||||
"version": "8.6.5",
|
||||
"description": "Base components for Ionic",
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"keywords": [
|
||||
"ionic",
|
||||
"framework",
|
||||
@@ -35,20 +32,20 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@phosphor-icons/core": "^2.1.1",
|
||||
"@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",
|
||||
"@capacitor/core": "^8.0.0",
|
||||
"@capacitor/haptics": "^8.0.0",
|
||||
"@capacitor/keyboard": "^8.0.0",
|
||||
"@capacitor/status-bar": "^8.0.0",
|
||||
"@axe-core/playwright": "^4.10.2",
|
||||
"@capacitor/core": "^7.0.0",
|
||||
"@capacitor/haptics": "^7.0.0",
|
||||
"@capacitor/keyboard": "^7.0.0",
|
||||
"@capacitor/status-bar": "^7.0.0",
|
||||
"@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.54.1",
|
||||
"@rollup/plugin-node-resolve": "^8.4.0",
|
||||
"@rollup/plugin-virtual": "^2.0.3",
|
||||
"@stencil/angular-output-target": "^0.10.0",
|
||||
@@ -62,7 +59,6 @@
|
||||
"chalk": "^5.3.0",
|
||||
"clean-css-cli": "^5.6.1",
|
||||
"domino": "^2.1.6",
|
||||
"esbuild": "^0.27.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-custom-rules": "file:custom-rules",
|
||||
@@ -70,22 +66,21 @@
|
||||
"fs-extra": "^9.0.1",
|
||||
"jest": "^29.7.0",
|
||||
"jest-cli": "^29.7.0",
|
||||
"outsystems-design-tokens": "^1.3.4",
|
||||
"playwright-core": "^1.56.1",
|
||||
"outsystems-design-tokens": "^1.2.6",
|
||||
"prettier": "^2.8.8",
|
||||
"rollup": "^2.26.4",
|
||||
"sass": "^1.33.0",
|
||||
"serve": "^14.0.1",
|
||||
"style-dictionary": "^4.1.3",
|
||||
"stylelint": "^13.13.1",
|
||||
"stylelint-order": "^4.1.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm run clean && npm run build.css && npm run build.themes && stencil build --es5 --docs-json dist/docs.json",
|
||||
"build": "npm run clean && npm run build.css && stencil build --es5 --docs-json dist/docs.json",
|
||||
"build.css": "npm run css.sass && npm run css.minify",
|
||||
"build.debug": "npm run clean && stencil build --debug",
|
||||
"build.docs.json": "stencil build --docs-json dist/docs.json",
|
||||
"build.tokens": "npx build.tokens --dest src/foundations/ --root=false --scss=true --scss-file=ionic.vars.scss --scss-prefix=ion --utilities=false && npm run prettier.tokens",
|
||||
"build.themes": "esbuild src/themes/*/*.tokens.ts --bundle --format=esm --platform=browser --target=es2017 --outdir=themes --outbase=src/themes && esbuild src/utils/theme.ts --bundle --format=esm --platform=browser --target=es2017 --outfile=themes/utils/theme.js",
|
||||
"build.tokens": "npx build.tokens --config scripts/tokens/index.js && npm run prettier.tokens",
|
||||
"clean": "node scripts/clean.js",
|
||||
"css.minify": "cleancss -O2 -o ./css/ionic.bundle.css ./css/ionic.bundle.css",
|
||||
"css.sass": "sass --embed-sources --style compressed src/css:./css",
|
||||
@@ -99,7 +94,7 @@
|
||||
"prerender.e2e": "node scripts/testing/prerender.js",
|
||||
"prettier": "prettier \"./src/**/*.{html,ts,tsx,js,jsx,scss}\"",
|
||||
"prettier.tokens": "prettier \"./src/foundations/*.{scss, html}\" --write --cache",
|
||||
"start": "npm run build.css && npm run build.themes && stencil build --dev --watch --serve",
|
||||
"start": "npm run build.css && stencil build --dev --watch --serve",
|
||||
"test": "npm run test.spec && npm run test.e2e",
|
||||
"test.spec": "stencil test --spec --max-workers=2",
|
||||
"test.e2e": "npx playwright test",
|
||||
|
||||
@@ -4,8 +4,7 @@ const path = require('path');
|
||||
|
||||
const cleanDirs = [
|
||||
'dist',
|
||||
'css',
|
||||
'themes'
|
||||
'css'
|
||||
];
|
||||
|
||||
cleanDirs.forEach(dir => {
|
||||
|
||||
@@ -1,67 +1,42 @@
|
||||
/**
|
||||
* This script is loaded in testing environments to set up the
|
||||
* document based on URL parameters.
|
||||
*
|
||||
* Test pages (e.g., `chip/test/basic/index.html`) are set to use
|
||||
* URL query parameters.
|
||||
*
|
||||
* Playwright test environments (e.g., `chip/test/basic/chip.e2e.ts`)
|
||||
* are set based on whether `setContent` or `goto` has been used:
|
||||
* - `setContent` uses URL hash parameters. Tests will break if
|
||||
* query parameters are used.
|
||||
* - `goto` uses URL query parameters.
|
||||
*
|
||||
* The following URL parameters are supported:
|
||||
* - `rtl`: Set to `true` to enable right-to-left directionality.
|
||||
* - `ionic:_testing`: Set to `true` to identify testing environments.
|
||||
* - `ionic:theme`: Set to `ionic`, `ios`, or `md` to load a specific
|
||||
* theme. Defaults to `md`.
|
||||
* - `palette`: Set to `light`, `dark`, `high-contrast`, or
|
||||
* `high-contrast-dark` to load a specific palette. Defaults to `light`.
|
||||
*/
|
||||
|
||||
const DEFAULT_THEME = 'md';
|
||||
const DEFAULT_PALETTE = 'light';
|
||||
|
||||
(function() {
|
||||
|
||||
/**
|
||||
* The `rtl` param is used to set the directionality of the
|
||||
* document. This can be `true` or `false`.
|
||||
*/
|
||||
const isRTL = window.location.search.indexOf('rtl=true') > -1 || window.location.hash.indexOf('rtl=true') > -1;
|
||||
|
||||
if (isRTL) {
|
||||
if (window.location.search.indexOf('rtl=true') > -1) {
|
||||
document.documentElement.setAttribute('dir', 'rtl');
|
||||
}
|
||||
|
||||
/**
|
||||
* The `ionic:_testing` param is used to identify testing
|
||||
* environments.
|
||||
*/
|
||||
const isTestEnv = window.location.search.indexOf('ionic:_testing=true') > -1 || window.location.hash.indexOf('ionic:_testing=true') > -1;
|
||||
|
||||
if (isTestEnv) {
|
||||
if (window.location.search.indexOf('ionic:_testing=true') > -1) {
|
||||
const style = document.createElement('style');
|
||||
style.innerHTML = `
|
||||
* {
|
||||
caret-color: transparent !important;
|
||||
}
|
||||
`;
|
||||
* {
|
||||
caret-color: transparent !important;
|
||||
}`;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
/**
|
||||
* The `theme` param is used to load a specific theme.
|
||||
* This can be `ionic`, `ios`, or `md`. Default to `md` for tests.
|
||||
* The term `palette` is used to as a param to match the
|
||||
* Ionic docs, plus here is already a `ionic:theme` query being
|
||||
* used for `md`, `ios`, and `ionic` themes.
|
||||
*/
|
||||
const themeQuery = window.location.search.match(/ionic:theme=([a-z0-9]+)/i);
|
||||
const themeHash = window.location.hash.match(/ionic:theme=([a-z0-9]+)/i);
|
||||
const themeAttr = document.documentElement.getAttribute('theme');
|
||||
const themeName = themeQuery?.[1] || themeHash?.[1] || themeAttr || DEFAULT_THEME;
|
||||
const palette = window.location.search.match(/palette=([a-z]+)/);
|
||||
if (palette && palette[1] !== 'light') {
|
||||
const linkTag = document.createElement('link');
|
||||
linkTag.setAttribute('rel', 'stylesheet');
|
||||
linkTag.setAttribute('type', 'text/css');
|
||||
linkTag.setAttribute('href', `/css/palettes/${palette[1]}.always.css`);
|
||||
document.head.appendChild(linkTag);
|
||||
}
|
||||
|
||||
/**
|
||||
* The `ionic` theme uses a different stylesheet than the `iOS` and `md` themes.
|
||||
* This is to ensure that the `ionic` theme is loaded when the `ionic:theme=ionic`
|
||||
* or when the HTML tag has the `theme="ionic"` attribute. This is useful for
|
||||
* the snapshot tests, where the `ionic` theme is not loaded by default.
|
||||
*/
|
||||
const themeQuery = window.location.search.match(/ionic:theme=([a-z]+)/);
|
||||
const themeAttr = document.documentElement.getAttribute('theme');
|
||||
|
||||
// TODO(): Remove this when the tokens are working for all components
|
||||
// and the themes all use the same bundle
|
||||
if ((themeQuery && themeQuery[1] === 'ionic') || themeAttr === 'ionic') {
|
||||
const ionicThemeLinkTag = document.querySelector('link[href*="css/ionic/bundle.ionic.css"]');
|
||||
|
||||
@@ -79,130 +54,6 @@ const DEFAULT_PALETTE = 'light';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `palette` param is used to load a specific palette
|
||||
* for the theme.
|
||||
* The dark class will load the dark palette automatically
|
||||
* if no palette is specified through the URL.
|
||||
*
|
||||
* Values can be `light`, `dark`, `high-contrast`,
|
||||
* or `high-contrast-dark`. Default to `light` for tests.
|
||||
*/
|
||||
const validPalettes = ['light', 'dark', 'high-contrast', 'high-contrast-dark'];
|
||||
|
||||
const configDarkMode = window.Ionic?.config?.customTheme?.palette?.dark?.enabled === 'always' ? 'dark' : null;
|
||||
const configHighContrastMode = window.Ionic?.config?.customTheme?.palette?.highContrast?.enabled === 'always' ? 'high-contrast' : null;
|
||||
const configHighContrastDarkMode = window.Ionic?.config?.customTheme?.palette?.highContrastDark?.enabled === 'always' ? 'high-contrast-dark' : null;
|
||||
/**
|
||||
* Ensure window.Ionic.config is defined before importing 'testing/scripts'
|
||||
* in the test HTML to properly initialize the palette configuration below.
|
||||
*
|
||||
* Example:
|
||||
* <script>
|
||||
* window.Ionic = { config: { customTheme: { palette: { ... } } } };
|
||||
* </script>
|
||||
* <script src="testing/scripts.js"></script>
|
||||
*/
|
||||
const configPalette = configDarkMode || configHighContrastMode || configHighContrastDarkMode;
|
||||
const paletteQuery = window.location.search.match(/palette=([a-z-]+)/);
|
||||
const paletteHash = window.location.hash.match(/palette=([a-z-]+)/);
|
||||
const darkClass = document.body?.classList.contains('ion-palette-dark') ? 'dark' : null;
|
||||
const highContrastClass = document.body?.classList.contains('ion-palette-high-contrast') ? 'high-contrast' : null;
|
||||
const highContrastDarkClass = darkClass && highContrastClass ? 'high-contrast-dark' : null;
|
||||
const paletteClass = highContrastDarkClass || highContrastClass || darkClass;
|
||||
|
||||
let paletteName = configPalette || paletteQuery?.[1] || paletteHash?.[1] || paletteClass || DEFAULT_PALETTE;
|
||||
|
||||
if (!validPalettes.includes(paletteName)) {
|
||||
console.warn(`Invalid palette name: '${paletteName}'. Falling back to 'light' palette.`);
|
||||
paletteName = DEFAULT_PALETTE;
|
||||
}
|
||||
|
||||
// Load theme tokens if the theme is valid
|
||||
const validThemes = ['ionic', 'ios', 'md'];
|
||||
if (themeName && validThemes.includes(themeName)) {
|
||||
loadThemeTokens(themeName, paletteName);
|
||||
} else if(themeName) {
|
||||
console.warn(
|
||||
`Unsupported theme "${themeName}". Supported themes are: ${validThemes.join(', ')}. Defaulting to ${DEFAULT_THEME}.`
|
||||
);
|
||||
}
|
||||
|
||||
async function loadThemeTokens(themeName, paletteName) {
|
||||
try {
|
||||
// Store existing theme set from the app initialization
|
||||
const customTheme = window.Ionic?.config?.customTheme;
|
||||
// Load the default tokens for the theme
|
||||
const defaultTokens = await import(`/themes/${themeName}/default.tokens.js`);
|
||||
let theme = defaultTokens.defaultTheme;
|
||||
|
||||
// Merge with existing theme to preserve any customizations
|
||||
if (customTheme) {
|
||||
theme = {
|
||||
...theme,
|
||||
...customTheme,
|
||||
palette: {
|
||||
...theme.palette,
|
||||
...customTheme.palette,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// If a specific palette is requested, modify the palette structure
|
||||
// to set the enabled property to 'always'
|
||||
// TODO(FW-4004): Implement dark palette
|
||||
if (paletteName === 'dark' && theme.palette?.dark) {
|
||||
theme.palette.dark.enabled = 'always';
|
||||
// TODO(FW-4005): Implement high contrast palette
|
||||
} else if (paletteName === 'high-contrast' && theme.palette?.highContrast) {
|
||||
theme.palette.highContrast.enabled = 'always';
|
||||
// TODO(FW-4005): Implement high contrast dark palette
|
||||
} else if (paletteName === 'high-contrast-dark' && theme.palette?.highContrastDark) {
|
||||
theme.palette.highContrastDark.enabled = 'always';
|
||||
}
|
||||
|
||||
if (window.Ionic?.config?.set) {
|
||||
/**
|
||||
* New Page Load after Initial App Load or Playwright Test:
|
||||
*
|
||||
* If the Config instance exists, we must use the
|
||||
* `set()` method. This ensures the internal private Map inside
|
||||
* the `Config` class is updated with the loaded theme tokens.
|
||||
* Without this, components would read 'undefined' or 'base'
|
||||
* values from the stale Map when trying to access them through
|
||||
* methods like `config.get()`.
|
||||
*/
|
||||
window.Ionic.config.set('customTheme', theme);
|
||||
} else {
|
||||
/**
|
||||
* App Initialization or Browser Refresh:
|
||||
*
|
||||
* If the Config instance doesn't exist yet,
|
||||
* we attach the theme to the global Ionic object. The `initialize()`
|
||||
* method in `ionic-global.ts` will later merge this into the new
|
||||
* `Config` instance via `config.reset()`.
|
||||
*/
|
||||
window.Ionic = window.Ionic || {};
|
||||
window.Ionic.config = window.Ionic.config || {};
|
||||
window.Ionic.config.customTheme = theme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-applying the global theme is critical for Playwright tests.
|
||||
* Even if the config is set, the CSS variables for the specific theme
|
||||
* (e.g., md or ios) must be force-injected into the document head to
|
||||
* ensure visual assertions pass correctly.
|
||||
*/
|
||||
if (window.Ionic?.config?.get && window.Ionic?.config?.set) {
|
||||
const themeModule = await import('/themes/utils/theme.js');
|
||||
themeModule.applyGlobalTheme(theme);
|
||||
themeModule.applyComponentsTheme(theme);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Failed to load theme tokens for ${themeName}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
window.Ionic = window.Ionic || {};
|
||||
window.Ionic.config = window.Ionic.config || {};
|
||||
|
||||
|
||||
201
core/scripts/tokens/index.js
Normal file
@@ -0,0 +1,201 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
// For generating Design Tokens, we use Style Dictionary for several reasons:
|
||||
// - It's prepared to easily generate tokens for multiple types of outputs (CSS, SCSS, iOS, Android, documentation, etc.).
|
||||
// - It also works very well out of the box with any kind of Design Tokens formats, like Figma Tokens, as well as APIs to adjust to more custom ones.
|
||||
// - It is probably the most well-known and widely used Design Tokens tool. It has also been regularly maintained for a long time.
|
||||
// - It can easily scale to different necessities we might have in the future.
|
||||
(async () => {
|
||||
const {
|
||||
generateShadowValue,
|
||||
generateFontSizeValue,
|
||||
generateFontFamilyValue,
|
||||
generateTypographyOutput,
|
||||
generateValue,
|
||||
generateColorUtilityClasses,
|
||||
generateDefaultSpaceUtilityClasses,
|
||||
generateSpaceUtilityClasses,
|
||||
removeConsecutiveRepeatedWords,
|
||||
setPrefixValue,
|
||||
generateRadiusUtilityClasses,
|
||||
generateBorderUtilityClasses,
|
||||
generateFontUtilityClasses,
|
||||
generateShadowUtilityClasses,
|
||||
generateUtilityClasses
|
||||
} = require('./utils.js');
|
||||
|
||||
const StyleDictionary = (await import('style-dictionary')).default;
|
||||
|
||||
// Set the prefix for variables and classes
|
||||
setPrefixValue('ion');
|
||||
|
||||
// Register a custom file header
|
||||
StyleDictionary.registerFileHeader({
|
||||
name: 'custom-header',
|
||||
fileHeader: async (defaultMessages = []) => {
|
||||
return [...defaultMessages, 'Do not edit directly, this file was auto-generated.'];
|
||||
},
|
||||
});
|
||||
|
||||
// SCSS variables format
|
||||
StyleDictionary.registerFormat({
|
||||
name: 'scssVariablesFormat',
|
||||
format: async function ({ dictionary, file }) {
|
||||
|
||||
console.log('Generating SCSS variables...');
|
||||
|
||||
const primitiveProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'primitives');
|
||||
const scaleProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'scale');
|
||||
const borderProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'border');
|
||||
const semanticsProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'semantics');
|
||||
const nonPrimitiveScaleBorderSemanticsProperties = dictionary.allTokens.filter(
|
||||
(prop) => !['primitives', 'scale', 'border', 'semantics'].includes(prop.path[0])
|
||||
);
|
||||
const typographyProperties = nonPrimitiveScaleBorderSemanticsProperties.filter((prop) => prop.$type === 'typography');
|
||||
const otherProperties = nonPrimitiveScaleBorderSemanticsProperties.filter((prop) => prop.$type !== 'typography');
|
||||
|
||||
// Order: primitives → semantics → scale → border → other → typography
|
||||
const sortedProperties = [
|
||||
...primitiveProperties,
|
||||
...semanticsProperties,
|
||||
...scaleProperties,
|
||||
...borderProperties,
|
||||
...otherProperties,
|
||||
...typographyProperties
|
||||
];
|
||||
|
||||
const prefixedVariables = sortedProperties.map((prop) => {
|
||||
// Remove consecutive repeated words from the token name, like border-border-color
|
||||
const propName = removeConsecutiveRepeatedWords(prop.name);
|
||||
|
||||
switch (prop.$type) {
|
||||
case 'boxShadow':
|
||||
return generateShadowValue(prop, propName);
|
||||
case 'fontFamilies':
|
||||
return generateFontFamilyValue(prop, propName, 'scss');
|
||||
case 'fontSizes':
|
||||
return generateFontSizeValue(prop, propName, 'scss');
|
||||
case 'typography':
|
||||
return generateTypographyOutput(prop, propName, true);
|
||||
default:
|
||||
return generateValue(prop, propName);
|
||||
}
|
||||
});
|
||||
|
||||
const fileHeader = await file.options.fileHeader();
|
||||
|
||||
return [
|
||||
`/*\n${fileHeader.join('\n')}\n*/`,
|
||||
'@use "../themes/functions.sizes" as font;\n',
|
||||
prefixedVariables.join('\n') + '\n',
|
||||
].join('\n');
|
||||
},
|
||||
});
|
||||
|
||||
// Create utility-classes
|
||||
StyleDictionary.registerFormat({
|
||||
name: 'cssUtilityClassesFormat',
|
||||
format: async function ({ dictionary, file }) {
|
||||
|
||||
console.log('Generating Utility-Classes...');
|
||||
|
||||
// Arrays to store specific utility classes
|
||||
const typographyUtilityClasses = [];
|
||||
const otherUtilityClasses = [];
|
||||
|
||||
// Generate utility classes for each token
|
||||
dictionary.allTokens.map((prop) => {
|
||||
|
||||
const tokenCategory = prop.attributes.category;
|
||||
|
||||
if (prop.$type === 'fontFamilies' || tokenCategory === 'scale' || tokenCategory === 'backdrop') {
|
||||
// Not creating for the tokens below, as they make no sense to exist as utility-classes.
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove consecutive repeated words from the token name, like border-border-color
|
||||
const propName = removeConsecutiveRepeatedWords(prop.name);
|
||||
|
||||
if (prop.$type === 'typography') {
|
||||
// Typography tokens are handled differently, as each might have a different tokenType
|
||||
return typographyUtilityClasses.push(generateTypographyOutput(prop, propName, false));
|
||||
|
||||
} else if (tokenCategory.startsWith('round') || tokenCategory.startsWith('rectangular') || tokenCategory.startsWith('soft')) {
|
||||
// Generate utility classes for border-radius shape tokens, as they have their own token json file, based on primitive tokens
|
||||
return otherUtilityClasses.push(generateRadiusUtilityClasses(propName));
|
||||
}
|
||||
|
||||
let utilityClass = '';
|
||||
switch (tokenCategory) {
|
||||
case 'color':
|
||||
case 'primitives':
|
||||
case 'semantics':
|
||||
case 'text':
|
||||
case 'bg':
|
||||
case 'icon':
|
||||
case 'state':
|
||||
utilityClass = generateColorUtilityClasses(prop, propName);
|
||||
break;
|
||||
case 'border':
|
||||
utilityClass = generateBorderUtilityClasses(prop, propName);
|
||||
break;
|
||||
case 'font':
|
||||
utilityClass = generateFontUtilityClasses(prop, propName);
|
||||
break;
|
||||
case 'space':
|
||||
utilityClass = generateSpaceUtilityClasses(prop, propName);
|
||||
break;
|
||||
case 'shadow':
|
||||
case 'elevation':
|
||||
utilityClass = generateShadowUtilityClasses(propName);
|
||||
break;
|
||||
default:
|
||||
utilityClass = generateUtilityClasses(tokenCategory, propName);
|
||||
}
|
||||
|
||||
return otherUtilityClasses.push(utilityClass);
|
||||
});
|
||||
|
||||
const defaultSpaceUtilityClasses = generateDefaultSpaceUtilityClasses();
|
||||
otherUtilityClasses.push(defaultSpaceUtilityClasses);
|
||||
|
||||
// Concatenate typography utility classes at the beginning
|
||||
const finalOutput = typographyUtilityClasses.concat(otherUtilityClasses).join('\n');
|
||||
|
||||
const fileHeader = await file.options.fileHeader();
|
||||
|
||||
return [
|
||||
`/*\n${fileHeader.join('\n')}\n*/`,
|
||||
'@import "./ionic.vars";\n@import "../themes/mixins";\n',
|
||||
finalOutput,
|
||||
].join('\n');
|
||||
},
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
// APPLY THE CONFIGURATION
|
||||
module.exports = {
|
||||
source: ["node_modules/outsystems-design-tokens/tokens/**/*.json"],
|
||||
platforms: {
|
||||
scss: {
|
||||
transformGroup: "scss",
|
||||
buildPath: './src/foundations/',
|
||||
files: [
|
||||
{
|
||||
destination: "ionic.vars.scss",
|
||||
format: "scssVariablesFormat",
|
||||
options: {
|
||||
fileHeader: `custom-header`,
|
||||
},
|
||||
},
|
||||
{
|
||||
destination: "ionic.utility.scss",
|
||||
format: "cssUtilityClassesFormat",
|
||||
options: {
|
||||
fileHeader: `custom-header`
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
335
core/scripts/tokens/utils.js
Normal file
@@ -0,0 +1,335 @@
|
||||
let variablesPrefix; // Variable that holds the prefix used on all css and scss variables generated
|
||||
|
||||
// Set the variable prefix value
|
||||
function setPrefixValue(prefix) {
|
||||
variablesPrefix = prefix;
|
||||
return variablesPrefix;
|
||||
}
|
||||
|
||||
// Generates a valid rgba() color
|
||||
function getRgbaValue(propValue) {
|
||||
// Check if its rgba color
|
||||
const isRgba = hexToRgba(propValue);
|
||||
// If it is, then compose rgba() color, otherwise use the normal color
|
||||
if (isRgba !== null) {
|
||||
return (propValue = `rgba(${isRgba.r}, ${isRgba.g}, ${isRgba.b},${isRgba.a})`);
|
||||
} else {
|
||||
return propValue;
|
||||
}
|
||||
}
|
||||
|
||||
// Translates an hex color value to rgb
|
||||
function hexToRgb(hex) {
|
||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
return result
|
||||
? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16),
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
// Translates an hex color value to rgba
|
||||
function hexToRgba(hex) {
|
||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
return result
|
||||
? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16),
|
||||
a: Math.round((parseInt(result[4], 16) * 100) / 255) / 100,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
// Utility function to remove consecutive repeated words
|
||||
function removeConsecutiveRepeatedWords(str) {
|
||||
return str.replace(/(\b\w+\b)(-\1)+/g, '$1');
|
||||
}
|
||||
|
||||
// Generates a reference variable for an alias token type
|
||||
// (e.g., $ion-border-default: var(--ion-border-default, #d5d5d5) → $ion-border-default: var(--ion-border-default, $ion-primitives-neutral-400))
|
||||
function getAliasReferenceVariable(prop) {
|
||||
if (typeof prop.$value === 'string' && prop.$value.startsWith('{') && prop.$value.endsWith('}')) {
|
||||
// Remove curly braces and replace dots with dashes
|
||||
let ref = prop.$value.slice(1, -1).replace(/\./g, '-');
|
||||
// Remove consecutive repeated words (e.g., border-border-radius-0 → border-radius-0)
|
||||
ref = removeConsecutiveRepeatedWords(ref);
|
||||
return `$${variablesPrefix}-${ref}`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Generates a valid box-shadow value from a shadow Design Token structure
|
||||
function generateShadowValue(prop, propName) {
|
||||
const cssShadow = prop.$value.map(shadow => {
|
||||
// Assuming shadow is an object with properties like offsetX, offsetY, blurRadius, spreadRadius, color
|
||||
const color = getRgbaValue(shadow.color);
|
||||
return `${shadow.x}px ${shadow.y}px ${shadow.blur}px ${shadow.spread}px ${color}`;
|
||||
}).join(', ');
|
||||
|
||||
return `$${variablesPrefix}-${propName}: var(--${variablesPrefix}-${propName}, ${cssShadow});`;
|
||||
}
|
||||
|
||||
// Generates a valid font-size value from a font-size Design Token structure, while transforming the pixels to rem
|
||||
function generateFontSizeValue(prop, propName, variableType = 'css') {
|
||||
return variableType === 'scss'
|
||||
? `$${variablesPrefix}-${propName}: var(--${variablesPrefix}-${propName}, font.px-to-rem(${parseInt(
|
||||
prop.$value
|
||||
)}));`
|
||||
: `--${propName}: #{font.px-to-rem(${parseInt(prop.$value)})};`;
|
||||
}
|
||||
|
||||
// Generates a valid font-family value from a font-family Design Token structure
|
||||
function generateFontFamilyValue(prop, propName, variableType = 'css') {
|
||||
// Remove the last word from the token, as it contains the name of the font, which we don't want to be included on the generated variables
|
||||
const _propName = propName.split('-').slice(0, -1).join('-');
|
||||
|
||||
return variableType === 'scss'
|
||||
? `$${variablesPrefix}-${_propName}: var(--${variablesPrefix}-${_propName}, "${prop.$value}", sans-serif);`
|
||||
: `--${variablesPrefix}-${_propName}: "${prop.$value}", sans-serif;`;
|
||||
}
|
||||
|
||||
// Generates a final value, based if the Design Token is of type color or not
|
||||
function generateValue(prop, propName) {
|
||||
// Use the original value to detect aliases
|
||||
const aliasVar = getAliasReferenceVariable({ $value: prop.original.$value });
|
||||
|
||||
// Always generate the main variable
|
||||
let mainValue;
|
||||
if (aliasVar) {
|
||||
mainValue = `$${variablesPrefix}-${propName}: var(--${variablesPrefix}-${propName}, ${aliasVar});`;
|
||||
} else {
|
||||
mainValue = `$${variablesPrefix}-${propName}: var(--${variablesPrefix}-${propName}, ${prop.$value});`;
|
||||
}
|
||||
|
||||
// Always generate the -rgb variable if it's a color
|
||||
const rgb = hexToRgb(prop.$value);
|
||||
let rgbDeclaration = '';
|
||||
if (rgb) {
|
||||
rgbDeclaration = `\n$${variablesPrefix}-${propName}-rgb: var(--${variablesPrefix}-${propName}-rgb, ${rgb.r}, ${rgb.g}, ${rgb.b});`;
|
||||
}
|
||||
|
||||
return `${mainValue}${rgbDeclaration}`;
|
||||
}
|
||||
|
||||
// Generates a typography based css utility-class or scss variable from a typography token structure
|
||||
function generateTypographyOutput(prop, propName, isVariable) {
|
||||
const typography = prop.original.$value;
|
||||
|
||||
// Extract the part after the last dot and trim any extraneous characters
|
||||
const extractLastPart = (str) => str.split('.').pop().replace(/[^\w-]/g, '');
|
||||
|
||||
const _initialWrapper = isVariable ? ': (' : ` {`;
|
||||
const _endWrapper = isVariable ? ')' : `}`;
|
||||
const _prefix = isVariable ? '$' : `.`;
|
||||
const _endChar = isVariable ? ',' : ';';
|
||||
|
||||
// This exact format is needed so that it compiles the tokens with the expected lint rules
|
||||
return `
|
||||
${_prefix}${variablesPrefix}-${propName}${_initialWrapper}
|
||||
font-size: $${variablesPrefix}-font-size-${extractLastPart(typography.fontSize)}${_endChar}
|
||||
font-style: ${prop.attributes.item?.toLowerCase() === 'italic' ? 'italic' : 'normal'}${_endChar}
|
||||
font-weight: $${variablesPrefix}-font-weight-${extractLastPart(typography.fontWeight)}${_endChar}
|
||||
letter-spacing: $${variablesPrefix}-font-letter-spacing-${extractLastPart(typography.letterSpacing) || 0}${_endChar}
|
||||
line-height: $${variablesPrefix}-font-line-height-${extractLastPart(typography.lineHeight)}${_endChar}
|
||||
text-transform: ${typography.textCase}${_endChar}
|
||||
text-decoration: ${typography.textDecoration}${_endChar}
|
||||
${_endWrapper};
|
||||
`;
|
||||
}
|
||||
|
||||
// Generates a color based css utility-class from a color Design Token structure
|
||||
function generateColorUtilityClasses(prop, className) {
|
||||
const isBg = className.includes('bg');
|
||||
const cssProp = isBg ? 'background-color' : 'color';
|
||||
return `.${variablesPrefix}-${className} {
|
||||
--${cssProp}: $${variablesPrefix}-${prop.name};
|
||||
${cssProp}: $${variablesPrefix}-${prop.name};
|
||||
}`;
|
||||
}
|
||||
|
||||
// Generates margin and padding utility classes to match the token-agnostic
|
||||
// utilities provided by the Ionic Framework
|
||||
function generateDefaultSpaceUtilityClasses() {
|
||||
const zeroMarginPaddingToken = 'space-0';
|
||||
const defaultMarginPaddingToken = 'space-400';
|
||||
|
||||
const marginPaddingTemplate = (type) => `
|
||||
.${variablesPrefix}-no-${type} {
|
||||
--${type}-top: #{$${variablesPrefix}-${zeroMarginPaddingToken}};
|
||||
--${type}-end: #{$${variablesPrefix}-${zeroMarginPaddingToken}};
|
||||
--${type}-bottom: #{$${variablesPrefix}-${zeroMarginPaddingToken}};
|
||||
--${type}-start: #{$${variablesPrefix}-${zeroMarginPaddingToken}};
|
||||
|
||||
@include ${type}($${variablesPrefix}-${zeroMarginPaddingToken});
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type} {
|
||||
--${type}-top: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
--${type}-end: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
--${type}-bottom: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
--${type}-start: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}($${variablesPrefix}-${defaultMarginPaddingToken});
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-top {
|
||||
--${type}-top: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}($${variablesPrefix}-${defaultMarginPaddingToken}, null, null, null);
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-end {
|
||||
--${type}-end: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}(null, $${variablesPrefix}-${defaultMarginPaddingToken}, null, null);
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-bottom {
|
||||
--${type}-bottom: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}(null, null, $${variablesPrefix}-${defaultMarginPaddingToken}, null);
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-start {
|
||||
--${type}-start: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}(null, null, null, $${variablesPrefix}-${defaultMarginPaddingToken});
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-vertical {
|
||||
--${type}-top: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
--${type}-bottom: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}($${variablesPrefix}-${defaultMarginPaddingToken}, null, $${variablesPrefix}-${defaultMarginPaddingToken}, null);
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-horizontal {
|
||||
--${type}-start: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
--${type}-end: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
||||
|
||||
@include ${type}(null, $${variablesPrefix}-${defaultMarginPaddingToken}, null, $${variablesPrefix}-${defaultMarginPaddingToken});
|
||||
};
|
||||
`;
|
||||
|
||||
return `${marginPaddingTemplate('margin')}\n${marginPaddingTemplate('padding')}`;
|
||||
}
|
||||
|
||||
// Generates a margin or padding based css utility-class from a space Design Token structure
|
||||
function generateSpaceUtilityClasses(prop, className) {
|
||||
// This exact format is needed so that it compiles the tokens with the expected lint rules
|
||||
// It will generate classes for margin and padding, for equal sizing on all side and each direction
|
||||
const marginPaddingTemplate = (type) => `
|
||||
.${variablesPrefix}-${type}-${className} {
|
||||
--${type}-top: #{$${variablesPrefix}-${prop.name}};
|
||||
--${type}-end: #{$${variablesPrefix}-${prop.name}};
|
||||
--${type}-bottom: #{$${variablesPrefix}-${prop.name}};
|
||||
--${type}-start: #{$${variablesPrefix}-${prop.name}};
|
||||
|
||||
@include ${type}($${variablesPrefix}-${prop.name});
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-top-${className} {
|
||||
--${type}-top: #{$${variablesPrefix}-${prop.name}};
|
||||
|
||||
@include ${type}($${variablesPrefix}-${prop.name}, null, null, null);
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-end-${className} {
|
||||
--${type}-end: #{$${variablesPrefix}-${prop.name}};
|
||||
|
||||
@include ${type}(null, $${variablesPrefix}-${prop.name}, null, null);
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-bottom-${className} {
|
||||
--${type}-bottom: #{$${variablesPrefix}-${prop.name}};
|
||||
|
||||
@include ${type}(null, null, $${variablesPrefix}-${prop.name}, null);
|
||||
};
|
||||
|
||||
.${variablesPrefix}-${type}-start-${className} {
|
||||
--${type}-start: #{$${variablesPrefix}-${prop.name}};
|
||||
|
||||
@include ${type}(null, null, null, $${variablesPrefix}-${prop.name});
|
||||
};
|
||||
`;
|
||||
|
||||
// Add gap utility classes for gap tokens
|
||||
const generateGapUtilityClasses = () =>`
|
||||
.${variablesPrefix}-gap-${prop.name} {
|
||||
gap: #{$${variablesPrefix}-${prop.name}};
|
||||
};
|
||||
`;
|
||||
|
||||
return `${generateGapUtilityClasses()}\n${marginPaddingTemplate('margin')}\n${marginPaddingTemplate('padding')}`;
|
||||
}
|
||||
|
||||
// Generates a valid box-shadow value from a shadow Design Token structure
|
||||
function generateRadiusUtilityClasses(propName) {
|
||||
return `.${variablesPrefix}-${propName} {
|
||||
--border-radius: $${variablesPrefix}-${propName};
|
||||
border-radius: $${variablesPrefix}-${propName};
|
||||
}`;
|
||||
}
|
||||
|
||||
// Generates a border based css utility-class from a font Design Token structure
|
||||
function generateBorderUtilityClasses(prop, propName) {
|
||||
let attribute;
|
||||
|
||||
switch (prop.attributes.type) {
|
||||
case 'border-radius':
|
||||
case 'border-style':
|
||||
attribute = prop.attributes.type;
|
||||
break;
|
||||
case 'border-size':
|
||||
attribute = 'border-width';
|
||||
break;
|
||||
default:
|
||||
attribute = 'border-color';
|
||||
}
|
||||
return `.${variablesPrefix}-${propName} {
|
||||
--${attribute}: $${variablesPrefix}-${propName};
|
||||
${attribute}: $${variablesPrefix}-${propName};
|
||||
}`;
|
||||
}
|
||||
|
||||
// Generates a font based css utility-class from a font Design Token structure
|
||||
function generateFontUtilityClasses(prop, propName) {
|
||||
return `.${variablesPrefix}-${propName} {\n ${prop.attributes.type}: $${variablesPrefix}-${propName};\n}`;
|
||||
}
|
||||
|
||||
// Generates a valid box-shadow value from a shadow Design Token structure
|
||||
function generateShadowUtilityClasses(propName) {
|
||||
return `.${variablesPrefix}-${propName} {
|
||||
--box-shadow: $${variablesPrefix}-${propName};
|
||||
box-shadow: $${variablesPrefix}-${propName};
|
||||
}`;
|
||||
}
|
||||
|
||||
// Generates a utility class for a given token category and name
|
||||
function generateUtilityClasses(tokenCategory, propName){
|
||||
return `.${variablesPrefix}-${propName} {\n ${tokenCategory}: $${variablesPrefix}-${propName};\n}`;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getRgbaValue,
|
||||
hexToRgb,
|
||||
generateShadowValue,
|
||||
generateFontSizeValue,
|
||||
generateFontFamilyValue,
|
||||
generateTypographyOutput,
|
||||
generateValue,
|
||||
getAliasReferenceVariable,
|
||||
setPrefixValue,
|
||||
generateRadiusUtilityClasses,
|
||||
generateColorUtilityClasses,
|
||||
generateDefaultSpaceUtilityClasses,
|
||||
generateSpaceUtilityClasses,
|
||||
removeConsecutiveRepeatedWords,
|
||||
generateBorderUtilityClasses,
|
||||
generateFontUtilityClasses,
|
||||
generateShadowUtilityClasses,
|
||||
generateUtilityClasses
|
||||
};
|
||||
142
core/src/components.d.ts
vendored
@@ -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";
|
||||
@@ -872,11 +872,8 @@ export namespace Components {
|
||||
*/
|
||||
"disabled": boolean;
|
||||
/**
|
||||
* The fill for the chip. Set to `"outline"` for a chip with a border and background. Set to `"solid"` for a chip with a background. Defaults to `"solid"`.
|
||||
*/
|
||||
"fill"?: 'outline' | 'solid';
|
||||
/**
|
||||
* Set to `"bold"` for a chip with vibrant, bold colors or to `"subtle"` for a chip with muted, subtle colors. Defaults to `"subtle"`.
|
||||
* Set to `"bold"` for a chip with vibrant, bold colors or to `"subtle"` for a chip with muted, subtle colors. Only applies to the `ionic` theme.
|
||||
* @default 'subtle'
|
||||
*/
|
||||
"hue"?: 'bold' | 'subtle';
|
||||
/**
|
||||
@@ -885,18 +882,21 @@ export namespace Components {
|
||||
"mode"?: "ios" | "md";
|
||||
/**
|
||||
* Display an outline style button.
|
||||
* @deprecated - Use fill="outline" instead
|
||||
* @default false
|
||||
*/
|
||||
"outline": boolean;
|
||||
/**
|
||||
* Set to `"soft"` for a chip with slightly rounded corners, `"round"` for a chip with fully rounded corners, or `"rectangular"` for a chip without rounded corners. Defaults to `"round"`.
|
||||
* Set to `"soft"` for a chip with slightly rounded corners, `"round"` for a chip with fully rounded corners, or `"rectangular"` for a chip without rounded corners. Defaults to `"round"` for the `"ionic"` theme and `"soft"` for all other themes.
|
||||
*/
|
||||
"shape"?: 'soft' | 'round' | 'rectangular';
|
||||
/**
|
||||
* Set to `"small"` for a chip with less height and padding. Defaults to `"large"`.
|
||||
* Set to `"small"` for a chip with less height and padding. Defaults to `"large"` for the ionic theme, and undefined for all other themes.
|
||||
*/
|
||||
"size"?: 'small' | 'large';
|
||||
/**
|
||||
* The theme determines the visual appearance of the component.
|
||||
*/
|
||||
"theme"?: "ios" | "md" | "ionic";
|
||||
}
|
||||
interface IonCol {
|
||||
/**
|
||||
@@ -927,88 +927,52 @@ export namespace Components {
|
||||
* The amount to offset the column for xs screens, in terms of how many columns it should shift to the end of the total available.
|
||||
*/
|
||||
"offsetXs"?: string;
|
||||
/**
|
||||
* The order of the column, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"order"?: string;
|
||||
/**
|
||||
* The order of the column for lg screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderLg"?: string;
|
||||
/**
|
||||
* The order of the column for md screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderMd"?: string;
|
||||
/**
|
||||
* The order of the column for sm screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderSm"?: string;
|
||||
/**
|
||||
* The order of the column for xl screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderXl"?: string;
|
||||
/**
|
||||
* The order of the column for xs screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderXs"?: string;
|
||||
/**
|
||||
* The amount to pull the column, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pull"?: string;
|
||||
/**
|
||||
* The amount to pull the column for lg screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullLg"?: string;
|
||||
/**
|
||||
* The amount to pull the column for md screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullMd"?: string;
|
||||
/**
|
||||
* The amount to pull the column for sm screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullSm"?: string;
|
||||
/**
|
||||
* The amount to pull the column for xl screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullXl"?: string;
|
||||
/**
|
||||
* The amount to pull the column for xs screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullXs"?: string;
|
||||
/**
|
||||
* The amount to push the column, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"push"?: string;
|
||||
/**
|
||||
* The amount to push the column for lg screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushLg"?: string;
|
||||
/**
|
||||
* The amount to push the column for md screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushMd"?: string;
|
||||
/**
|
||||
* The amount to push the column for sm screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushSm"?: string;
|
||||
/**
|
||||
* The amount to push the column for xl screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushXl"?: string;
|
||||
/**
|
||||
* The amount to push the column for xs screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushXs"?: string;
|
||||
/**
|
||||
@@ -1071,10 +1035,6 @@ export namespace Components {
|
||||
* The mode determines the platform behaviors of the component.
|
||||
*/
|
||||
"mode"?: "ios" | "md";
|
||||
/**
|
||||
* Recalculate content dimensions. Called by overlays (e.g., popover) when sibling elements like headers or footers have finished rendering and their heights are available, ensuring accurate offset-top calculations.
|
||||
*/
|
||||
"recalculateDimensions": () => Promise<void>;
|
||||
/**
|
||||
* Scroll by a specified X/Y distance in the component.
|
||||
* @param x The amount to scroll by on the horizontal axis.
|
||||
@@ -1545,11 +1505,6 @@ export namespace Components {
|
||||
* @default 'bottom'
|
||||
*/
|
||||
"position": 'top' | 'bottom';
|
||||
/**
|
||||
* If `true`, the infinite scroll will preserve the scroll position when the content is re-rendered. This is useful when the content is re-rendered with new keys, and the scroll position should be preserved.
|
||||
* @default false
|
||||
*/
|
||||
"preserveRerenderScrollPosition": boolean;
|
||||
/**
|
||||
* The theme determines the visual appearance of the component.
|
||||
*/
|
||||
@@ -3271,7 +3226,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>;
|
||||
@@ -5473,9 +5428,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;
|
||||
@@ -6846,11 +6798,8 @@ declare namespace LocalJSX {
|
||||
*/
|
||||
"disabled"?: boolean;
|
||||
/**
|
||||
* The fill for the chip. Set to `"outline"` for a chip with a border and background. Set to `"solid"` for a chip with a background. Defaults to `"solid"`.
|
||||
*/
|
||||
"fill"?: 'outline' | 'solid';
|
||||
/**
|
||||
* Set to `"bold"` for a chip with vibrant, bold colors or to `"subtle"` for a chip with muted, subtle colors. Defaults to `"subtle"`.
|
||||
* Set to `"bold"` for a chip with vibrant, bold colors or to `"subtle"` for a chip with muted, subtle colors. Only applies to the `ionic` theme.
|
||||
* @default 'subtle'
|
||||
*/
|
||||
"hue"?: 'bold' | 'subtle';
|
||||
/**
|
||||
@@ -6859,18 +6808,21 @@ declare namespace LocalJSX {
|
||||
"mode"?: "ios" | "md";
|
||||
/**
|
||||
* Display an outline style button.
|
||||
* @deprecated - Use fill="outline" instead
|
||||
* @default false
|
||||
*/
|
||||
"outline"?: boolean;
|
||||
/**
|
||||
* Set to `"soft"` for a chip with slightly rounded corners, `"round"` for a chip with fully rounded corners, or `"rectangular"` for a chip without rounded corners. Defaults to `"round"`.
|
||||
* Set to `"soft"` for a chip with slightly rounded corners, `"round"` for a chip with fully rounded corners, or `"rectangular"` for a chip without rounded corners. Defaults to `"round"` for the `"ionic"` theme and `"soft"` for all other themes.
|
||||
*/
|
||||
"shape"?: 'soft' | 'round' | 'rectangular';
|
||||
/**
|
||||
* Set to `"small"` for a chip with less height and padding. Defaults to `"large"`.
|
||||
* Set to `"small"` for a chip with less height and padding. Defaults to `"large"` for the ionic theme, and undefined for all other themes.
|
||||
*/
|
||||
"size"?: 'small' | 'large';
|
||||
/**
|
||||
* The theme determines the visual appearance of the component.
|
||||
*/
|
||||
"theme"?: "ios" | "md" | "ionic";
|
||||
}
|
||||
interface IonCol {
|
||||
/**
|
||||
@@ -6901,88 +6853,52 @@ declare namespace LocalJSX {
|
||||
* The amount to offset the column for xs screens, in terms of how many columns it should shift to the end of the total available.
|
||||
*/
|
||||
"offsetXs"?: string;
|
||||
/**
|
||||
* The order of the column, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"order"?: string;
|
||||
/**
|
||||
* The order of the column for lg screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderLg"?: string;
|
||||
/**
|
||||
* The order of the column for md screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderMd"?: string;
|
||||
/**
|
||||
* The order of the column for sm screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderSm"?: string;
|
||||
/**
|
||||
* The order of the column for xl screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderXl"?: string;
|
||||
/**
|
||||
* The order of the column for xs screens, in terms of where the column should position itself in the columns renderer. If no value is passed, the column order implicit value will be the order in the html structure.
|
||||
*/
|
||||
"orderXs"?: string;
|
||||
/**
|
||||
* The amount to pull the column, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pull"?: string;
|
||||
/**
|
||||
* The amount to pull the column for lg screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullLg"?: string;
|
||||
/**
|
||||
* The amount to pull the column for md screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullMd"?: string;
|
||||
/**
|
||||
* The amount to pull the column for sm screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullSm"?: string;
|
||||
/**
|
||||
* The amount to pull the column for xl screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullXl"?: string;
|
||||
/**
|
||||
* The amount to pull the column for xs screens, in terms of how many columns it should shift to the start of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pullXs"?: string;
|
||||
/**
|
||||
* The amount to push the column, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"push"?: string;
|
||||
/**
|
||||
* The amount to push the column for lg screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushLg"?: string;
|
||||
/**
|
||||
* The amount to push the column for md screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushMd"?: string;
|
||||
/**
|
||||
* The amount to push the column for sm screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushSm"?: string;
|
||||
/**
|
||||
* The amount to push the column for xl screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushXl"?: string;
|
||||
/**
|
||||
* The amount to push the column for xs screens, in terms of how many columns it should shift to the end of the total available.
|
||||
* @deprecated Use the combination of `size` and `order` properties to achieve the same effect.
|
||||
*/
|
||||
"pushXs"?: string;
|
||||
/**
|
||||
@@ -7520,11 +7436,6 @@ declare namespace LocalJSX {
|
||||
* @default 'bottom'
|
||||
*/
|
||||
"position"?: 'top' | 'bottom';
|
||||
/**
|
||||
* If `true`, the infinite scroll will preserve the scroll position when the content is re-rendered. This is useful when the content is re-rendered with new keys, and the scroll position should be preserved.
|
||||
* @default false
|
||||
*/
|
||||
"preserveRerenderScrollPosition"?: boolean;
|
||||
/**
|
||||
* The theme determines the visual appearance of the component.
|
||||
*/
|
||||
@@ -9249,22 +9160,9 @@ declare namespace LocalJSX {
|
||||
*/
|
||||
"mode"?: "ios" | "md";
|
||||
/**
|
||||
* 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;
|
||||
/**
|
||||
* The theme determines the visual appearance of the component.
|
||||
*/
|
||||
|
||||
@@ -19,19 +19,19 @@
|
||||
}
|
||||
|
||||
:host(.accordion-group-expand-inset.accordion-group-shape-round) {
|
||||
--border-radius: #{globals.$ion-round-xl};
|
||||
--border-radius: #{globals.$ion-border-radius-400};
|
||||
|
||||
@include globals.border-radius(globals.$ion-round-xl);
|
||||
@include globals.border-radius(globals.$ion-border-radius-400);
|
||||
}
|
||||
|
||||
:host(.accordion-group-expand-inset.accordion-group-shape-soft) {
|
||||
--border-radius: #{globals.$ion-soft-xl};
|
||||
--border-radius: #{globals.$ion-border-radius-200};
|
||||
|
||||
@include globals.border-radius(globals.$ion-soft-xl);
|
||||
@include globals.border-radius(globals.$ion-border-radius-200);
|
||||
}
|
||||
|
||||
:host(.accordion-group-expand-inset.accordion-group-shape-rectangular) {
|
||||
--border-radius: #{globals.$ion-rectangular-xl};
|
||||
--border-radius: #{globals.$ion-border-radius-0};
|
||||
|
||||
@include globals.border-radius(globals.$ion-rectangular-xl);
|
||||
@include globals.border-radius(globals.$ion-border-radius-0);
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ config, screens
|
||||
`
|
||||
<style>
|
||||
/* Background styles to show the border radius */
|
||||
.ionic {
|
||||
--ion-background-color: #ccc7c7;
|
||||
:root {
|
||||
--background: #ccc7c7;
|
||||
}
|
||||
</style>
|
||||
<ion-accordion-group>
|
||||
@@ -47,8 +47,8 @@ configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ config, screens
|
||||
`
|
||||
<style>
|
||||
/* Background styles to show the border radius */
|
||||
.ionic {
|
||||
--ion-background-color: #ccc7c7;
|
||||
:root {
|
||||
--background: #ccc7c7;
|
||||
}
|
||||
</style>
|
||||
<ion-accordion-group value="first">
|
||||
@@ -87,8 +87,8 @@ configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ config, screens
|
||||
`
|
||||
<style>
|
||||
/* Background styles to show the border radius */
|
||||
.ionic {
|
||||
--ion-background-color: #ccc7c7;
|
||||
:root {
|
||||
--background: #ccc7c7;
|
||||
}
|
||||
</style>
|
||||
<ion-accordion-group expand="inset">
|
||||
@@ -125,8 +125,8 @@ configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ config, screens
|
||||
`
|
||||
<style>
|
||||
/* Background styles to show the border radius */
|
||||
.ionic {
|
||||
--ion-background-color: #ccc7c7;
|
||||
:root {
|
||||
--background: #ccc7c7;
|
||||
}
|
||||
</style>
|
||||
<ion-accordion-group value="first" expand="inset">
|
||||
|
||||
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@@ -9,8 +9,8 @@ configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ config, screens
|
||||
`
|
||||
<style>
|
||||
/* Background styles to show the border radius */
|
||||
.ionic {
|
||||
--ion-background-color: #222;
|
||||
:root {
|
||||
--background: #222;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
@@ -59,7 +59,7 @@
|
||||
// --------------------------------------------------
|
||||
|
||||
#content-wrapper {
|
||||
@include globals.padding(globals.$ion-space-300, globals.$ion-space-400);
|
||||
@include globals.padding(null, globals.$ion-space-400, globals.$ion-space-300, globals.$ion-space-400);
|
||||
@include globals.typography(globals.$ion-body-md-regular);
|
||||
|
||||
color: globals.$ion-text-default;
|
||||
|
||||
@@ -42,40 +42,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;
|
||||
@@ -87,25 +54,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
|
||||
@@ -144,15 +92,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,16 +237,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;
|
||||
}
|
||||
|
||||
@@ -310,12 +252,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;
|
||||
@@ -336,14 +272,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;
|
||||
}
|
||||
@@ -385,19 +316,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;
|
||||
}
|
||||
@@ -419,7 +337,7 @@ export class Accordion implements ComponentInterface {
|
||||
return true;
|
||||
};
|
||||
|
||||
private updateState = async () => {
|
||||
private updateState = async (initialUpdate = false) => {
|
||||
const accordionGroup = this.accordionGroupEl;
|
||||
const accordionValue = this.value;
|
||||
|
||||
@@ -432,10 +350,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,
|
||||
@@ -485,12 +403,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
|
||||
|
||||
@@ -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({
|
||||
|
||||
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@@ -9,8 +9,8 @@ configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ config, screens
|
||||
`
|
||||
<style>
|
||||
/* Background styles to show the border radius */
|
||||
.ionic {
|
||||
--ion-background-color: #222;
|
||||
:root {
|
||||
--background: #222;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.3 KiB |