mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
Compare commits
84 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3fb09ab44 | ||
|
|
7947a26ba4 | ||
|
|
ffb056d50e | ||
|
|
2d9724947d | ||
|
|
02ef5ae179 | ||
|
|
4aab72b061 | ||
|
|
9c9e28ccc9 | ||
|
|
1c2875044a | ||
|
|
d665ace5c4 | ||
|
|
672ab80807 | ||
|
|
da3b93b4a2 | ||
|
|
5e5054d369 | ||
|
|
8f188eaae7 | ||
|
|
f6a00ea954 | ||
|
|
b083ae4e58 | ||
|
|
f7bd4c02c3 | ||
|
|
047d3c7772 | ||
|
|
4b26feaa47 | ||
|
|
e41b0e0cf2 | ||
|
|
7f61b06895 | ||
|
|
89e4bc56a1 | ||
|
|
fb96ab5a26 | ||
|
|
6f01c3b73d | ||
|
|
07d83ccd24 | ||
|
|
816096f897 | ||
|
|
615dcc0461 | ||
|
|
c2603e9cff | ||
|
|
1d983fa4b3 | ||
|
|
23b4fc5385 | ||
|
|
11425fbb35 | ||
|
|
2d70427608 | ||
|
|
bd8c3e881f | ||
|
|
0566ec0da3 | ||
|
|
b2f2a4b71b | ||
|
|
64dd070d67 | ||
|
|
928dfa52ca | ||
|
|
d0b61307c6 | ||
|
|
579d11824d | ||
|
|
7c43589b0a | ||
|
|
642255e514 | ||
|
|
2485b303da | ||
|
|
9e2373e15e | ||
|
|
e8fe117c34 | ||
|
|
811a34493d | ||
|
|
5bcb39f82b | ||
|
|
22be16f3f0 | ||
|
|
fd59acd691 | ||
|
|
b5dbb3984c | ||
|
|
794bfbbc57 | ||
|
|
351c30ce42 | ||
|
|
8605c467d1 | ||
|
|
1b0669eebe | ||
|
|
bdb268aa12 | ||
|
|
2916810a2b | ||
|
|
24659a527a | ||
|
|
a09d7d4ab6 | ||
|
|
ea34e50430 | ||
|
|
4075ea6941 | ||
|
|
2a2829c17e | ||
|
|
e001f24f2c | ||
|
|
68a7e43345 | ||
|
|
e92fecb08c | ||
|
|
a63474a621 | ||
|
|
f98151c5d1 | ||
|
|
655631ddf0 | ||
|
|
3b9b9082b8 | ||
|
|
11332e446c | ||
|
|
0774cca2cd | ||
|
|
6c366aaf87 | ||
|
|
6876fd089f | ||
|
|
22a8842ac2 | ||
|
|
2d5faa75db | ||
|
|
cab2a5103f | ||
|
|
d36050918a | ||
|
|
64f128be07 | ||
|
|
87999e3c7a | ||
|
|
bb4554211d | ||
|
|
f71109b088 | ||
|
|
44e18bd795 | ||
|
|
f4d265eb60 | ||
|
|
1e8dfb7d85 | ||
|
|
9f023c92c4 | ||
|
|
694d47b794 | ||
|
|
b87c555a6e |
@@ -1,565 +0,0 @@
|
||||
version: 2.1
|
||||
orbs:
|
||||
cypress: cypress-io/cypress@1.27.0
|
||||
|
||||
aliases:
|
||||
- &restore-cache
|
||||
keys:
|
||||
- dependency-cache-{{ checksum "package.json" }}-7
|
||||
|
||||
- &save-cache
|
||||
key: dependency-cache-{{ checksum "package.json" }}-7
|
||||
paths:
|
||||
- node_modules
|
||||
|
||||
- &restore-cache-core
|
||||
keys:
|
||||
- dependency-cache-{{ checksum "core/package.json" }}-7
|
||||
|
||||
- &save-cache-core
|
||||
key: dependency-cache-{{ checksum "core/package.json" }}-7
|
||||
paths:
|
||||
- core/node_modules
|
||||
|
||||
- &restore-cache-core-stencil
|
||||
keys:
|
||||
- stencil-cache-6
|
||||
|
||||
- &save-cache-core-stencil
|
||||
key: stencil-cache-6
|
||||
paths:
|
||||
- core/.stencil
|
||||
- core/screenshot/images
|
||||
|
||||
defaults: &defaults
|
||||
docker:
|
||||
- image: circleci/node:latest-browsers
|
||||
working_directory: /tmp/workspace
|
||||
environment:
|
||||
NODE_ENV: development
|
||||
|
||||
jobs:
|
||||
puppeteer-dependencies:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- run:
|
||||
name: Install headless Chrome dependencies
|
||||
command: |
|
||||
sudo apt-get install -yq \
|
||||
gconf-service libasound2 libatk1.0-0 libatk-bridge2.0-0 libc6 libcairo2 libcups2 libdbus-1-3 \
|
||||
libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 \
|
||||
libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 \
|
||||
libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates \
|
||||
fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget
|
||||
- run:
|
||||
name: Install Puppeteer with Chromium
|
||||
command: |
|
||||
npm i puppeteer
|
||||
|
||||
build:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache: *restore-cache
|
||||
- run: npm install --legacy-peer-deps
|
||||
- save_cache: *save-cache
|
||||
- persist_to_workspace:
|
||||
root: /tmp/workspace
|
||||
paths:
|
||||
- node_modules
|
||||
|
||||
build-core:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- restore_cache: *restore-cache-core
|
||||
- restore_cache: *restore-cache-core-stencil
|
||||
- run:
|
||||
command: npm install --legacy-peer-deps
|
||||
working_directory: /tmp/workspace/core
|
||||
- save_cache: *save-cache-core
|
||||
- run:
|
||||
command: npm run build -- --ci
|
||||
working_directory: /tmp/workspace/core
|
||||
- save_cache: *save-cache-core-stencil
|
||||
- persist_to_workspace:
|
||||
root: /tmp/workspace
|
||||
paths:
|
||||
- core/node_modules
|
||||
- core/dist
|
||||
- core/components
|
||||
- core/css
|
||||
- core/hydrate
|
||||
- core/loader
|
||||
|
||||
build-angular:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm install --legacy-peer-deps
|
||||
working_directory: /tmp/workspace/angular
|
||||
- run:
|
||||
command: sudo npm link
|
||||
working_directory: /tmp/workspace/core
|
||||
- run:
|
||||
command: sudo npm link @ionic/core
|
||||
working_directory: /tmp/workspace/angular
|
||||
- run:
|
||||
command: npm run build
|
||||
working_directory: /tmp/workspace/angular
|
||||
- persist_to_workspace:
|
||||
root: /tmp/workspace
|
||||
paths:
|
||||
- angular/node_modules
|
||||
- angular/dist
|
||||
|
||||
build-angular-server:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm install --legacy-peer-deps
|
||||
working_directory: /tmp/workspace/packages/angular-server
|
||||
- run:
|
||||
command: npm run build.prod
|
||||
working_directory: /tmp/workspace/packages/angular-server
|
||||
- persist_to_workspace:
|
||||
root: /tmp/workspace
|
||||
paths:
|
||||
- packages/angular-server/dist
|
||||
|
||||
build-react:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm install --legacy-peer-deps
|
||||
working_directory: /tmp/workspace/packages/react
|
||||
- run:
|
||||
command: sudo npm link
|
||||
working_directory: /tmp/workspace/core
|
||||
- run:
|
||||
command: sudo npm link @ionic/core
|
||||
working_directory: /tmp/workspace/packages/react
|
||||
- run:
|
||||
command: npm run build
|
||||
working_directory: /tmp/workspace/packages/react
|
||||
- persist_to_workspace:
|
||||
root: /tmp/workspace
|
||||
paths:
|
||||
- packages/react/node_modules
|
||||
- packages/react/dist
|
||||
- packages/react/css
|
||||
|
||||
build-react-router:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm install --legacy-peer-deps
|
||||
working_directory: /tmp/workspace/packages/react-router
|
||||
- run:
|
||||
command: sudo npm link
|
||||
working_directory: /tmp/workspace/core
|
||||
- run:
|
||||
command: sudo npm link @ionic/core
|
||||
working_directory: /tmp/workspace/packages/react-router
|
||||
- run:
|
||||
command: sudo npm link
|
||||
working_directory: /tmp/workspace/packages/react
|
||||
- run:
|
||||
command: sudo npm link @ionic/react
|
||||
working_directory: /tmp/workspace/packages/react-router
|
||||
- run:
|
||||
command: npm run build
|
||||
working_directory: /tmp/workspace/packages/react-router
|
||||
- persist_to_workspace:
|
||||
root: /tmp/workspace
|
||||
paths:
|
||||
- packages/react-router/node_modules
|
||||
- packages/react-router/dist
|
||||
|
||||
build-vue:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm install
|
||||
working_directory: /tmp/workspace/packages/vue
|
||||
- run:
|
||||
command: sudo npm link
|
||||
working_directory: /tmp/workspace/core
|
||||
- run:
|
||||
command: sudo npm link @ionic/core
|
||||
working_directory: /tmp/workspace/packages/vue
|
||||
- run:
|
||||
command: npm run build
|
||||
working_directory: /tmp/workspace/packages/vue
|
||||
- persist_to_workspace:
|
||||
root: /tmp/workspace
|
||||
paths:
|
||||
- packages/vue/node_modules
|
||||
- packages/vue/dist
|
||||
- packages/vue/css
|
||||
|
||||
build-vue-router:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm install
|
||||
working_directory: /tmp/workspace/packages/vue-router
|
||||
- run:
|
||||
command: sudo npm link
|
||||
working_directory: /tmp/workspace/packages/vue
|
||||
- run:
|
||||
command: sudo npm link @ionic/vue
|
||||
working_directory: /tmp/workspace/packages/vue-router
|
||||
- run:
|
||||
command: npm run build
|
||||
working_directory: /tmp/workspace/packages/vue-router
|
||||
- persist_to_workspace:
|
||||
root: /tmp/workspace
|
||||
paths:
|
||||
- packages/vue-router/dist
|
||||
|
||||
test-core-clean-build:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
name: Checking clean build
|
||||
command: git diff --exit-code
|
||||
working_directory: /tmp/workspace/core
|
||||
|
||||
test-core-lint:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm run lint
|
||||
working_directory: /tmp/workspace/core
|
||||
|
||||
test-core-e2e:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm run test.e2e -- --ci --no-build
|
||||
working_directory: /tmp/workspace/core
|
||||
|
||||
test-core-spec:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm run test.spec -- --ci
|
||||
working_directory: /tmp/workspace/core
|
||||
|
||||
test-core-treeshake:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm run test.treeshake -- --ci
|
||||
working_directory: /tmp/workspace/core
|
||||
|
||||
test-core-screenshot:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
name: Run Screenshot
|
||||
command: npx stencil test --e2e --screenshot --screenshot-connector=scripts/screenshot/ci.js --ci --no-build || true
|
||||
working_directory: /tmp/workspace/core
|
||||
|
||||
test-core-screenshot-master:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
name: Run Screenshot
|
||||
command: npx stencil test --e2e --screenshot --screenshot-connector=scripts/screenshot/ci.js --ci --update-screenshot --no-build || true
|
||||
working_directory: /tmp/workspace/core
|
||||
|
||||
test-angular-lint:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm run lint
|
||||
working_directory: /tmp/workspace/angular
|
||||
|
||||
test-react-lint:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm run lint
|
||||
working_directory: /tmp/workspace/packages/react
|
||||
|
||||
test-react-router-lint:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm run lint
|
||||
working_directory: /tmp/workspace/packages/react-router
|
||||
|
||||
test-vue-lint:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm run lint
|
||||
working_directory: /tmp/workspace/packages/vue
|
||||
|
||||
test-vue-router-lint:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm run lint
|
||||
working_directory: /tmp/workspace/packages/vue-router
|
||||
|
||||
test-react-spec:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: sudo npm link
|
||||
working_directory: /tmp/workspace/core
|
||||
- run:
|
||||
command: sudo npm link @ionic/core
|
||||
working_directory: /tmp/workspace/packages/react
|
||||
- run:
|
||||
command: npm run test.spec
|
||||
working_directory: /tmp/workspace/packages/react
|
||||
|
||||
test-react-router-spec:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: sudo npm link
|
||||
working_directory: /tmp/workspace/core
|
||||
- run:
|
||||
command: sudo npm link @ionic/core
|
||||
working_directory: /tmp/workspace/packages/react
|
||||
- run:
|
||||
command: sudo npm link
|
||||
working_directory: /tmp/workspace/packages/react
|
||||
- run:
|
||||
command: sudo npm link @ionic/react
|
||||
working_directory: /tmp/workspace/packages/react-router
|
||||
- run:
|
||||
command: npm run test.spec
|
||||
working_directory: /tmp/workspace/packages/react-router
|
||||
|
||||
install-react-test-app:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: CYPRESS_CACHE_FOLDER=/tmp/workspace/packages/react-router/test-app npm install
|
||||
working_directory: /tmp/workspace/packages/react-router/test-app
|
||||
- persist_to_workspace:
|
||||
root: /tmp/workspace
|
||||
paths:
|
||||
- packages/react-router/test-app
|
||||
|
||||
test-react-e2e:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm run sync
|
||||
working_directory: /tmp/workspace/packages/react-router/test-app
|
||||
- run:
|
||||
command: CYPRESS_CACHE_FOLDER=/tmp/workspace/packages/react-router/test-app npm run e2e
|
||||
working_directory: /tmp/workspace/packages/react-router/test-app
|
||||
|
||||
test-vue-router-spec:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: sudo npm link
|
||||
working_directory: /tmp/workspace/core
|
||||
- run:
|
||||
command: sudo npm link @ionic/core
|
||||
working_directory: /tmp/workspace/packages/vue
|
||||
- run:
|
||||
command: sudo npm link
|
||||
working_directory: /tmp/workspace/packages/vue
|
||||
- run:
|
||||
command: sudo npm link @ionic/vue
|
||||
working_directory: /tmp/workspace/packages/vue-router
|
||||
- run:
|
||||
command: npm run test.spec
|
||||
working_directory: /tmp/workspace/packages/vue-router
|
||||
|
||||
test-angular-e2e:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm install --legacy-peer-deps
|
||||
working_directory: /tmp/workspace/angular/test/test-app
|
||||
- run:
|
||||
command: npm run test
|
||||
working_directory: /tmp/workspace/angular/test/test-app
|
||||
|
||||
install-vue-test-app:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: CYPRESS_CACHE_FOLDER=/tmp/workspace/packages/vue/test-app npm install
|
||||
working_directory: /tmp/workspace/packages/vue/test-app
|
||||
- persist_to_workspace:
|
||||
root: /tmp/workspace
|
||||
paths:
|
||||
- packages/vue/test-app
|
||||
|
||||
test-vue-spec-and-e2e:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm run sync
|
||||
working_directory: /tmp/workspace/packages/vue/test-app
|
||||
- run:
|
||||
command: npm run test:unit
|
||||
working_directory: /tmp/workspace/packages/vue/test-app
|
||||
- run:
|
||||
command: CYPRESS_CACHE_FOLDER=/tmp/workspace/packages/vue/test-app npm run test:e2e
|
||||
working_directory: /tmp/workspace/packages/vue/test-app
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
build:
|
||||
jobs:
|
||||
- puppeteer-dependencies
|
||||
- build
|
||||
- build-core:
|
||||
requires: [build]
|
||||
- test-core-clean-build:
|
||||
requires: [build-core]
|
||||
- test-core-lint:
|
||||
requires: [build-core]
|
||||
- test-core-e2e:
|
||||
requires: [puppeteer-dependencies, build-core]
|
||||
- test-core-spec:
|
||||
requires: [build-core]
|
||||
# Adam requested we skip this test for now
|
||||
# since it is failing on ES5 code which
|
||||
# will be removed in Ionic Framework v6
|
||||
#- test-core-treeshake:
|
||||
# requires: [build-core]
|
||||
- test-core-screenshot:
|
||||
requires: [build-core]
|
||||
filters:
|
||||
branches:
|
||||
ignore: master
|
||||
- test-core-screenshot-master:
|
||||
requires: [build-core]
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
||||
|
||||
- build-angular:
|
||||
requires: [build-core]
|
||||
- build-angular-server:
|
||||
requires: [build-angular]
|
||||
- build-react:
|
||||
requires: [build-core]
|
||||
- build-react-router:
|
||||
requires: [build-core, build-react]
|
||||
- test-react-lint:
|
||||
requires: [build-react]
|
||||
- test-react-router-lint:
|
||||
requires: [build-react-router]
|
||||
- test-react-spec:
|
||||
requires: [build-react]
|
||||
- test-react-router-spec:
|
||||
requires: [build-react-router]
|
||||
- install-react-test-app:
|
||||
requires: [build-core]
|
||||
- test-react-e2e:
|
||||
requires: [install-react-test-app, build-react, build-react-router]
|
||||
- build-vue:
|
||||
requires: [build-core]
|
||||
- build-vue-router:
|
||||
requires: [build-vue]
|
||||
- test-vue-lint:
|
||||
requires: [build-vue]
|
||||
- test-vue-router-lint:
|
||||
requires: [build-vue-router]
|
||||
- test-vue-router-spec:
|
||||
requires: [build-vue-router]
|
||||
- install-vue-test-app:
|
||||
requires: [build-core]
|
||||
- test-vue-spec-and-e2e:
|
||||
requires: [install-vue-test-app, build-vue, build-vue-router]
|
||||
- test-angular-lint:
|
||||
requires: [build-angular]
|
||||
- test-angular-e2e:
|
||||
requires:
|
||||
- build-angular
|
||||
- build-angular-server
|
||||
20
.github/COMPONENT-GUIDE.md
vendored
20
.github/COMPONENT-GUIDE.md
vendored
@@ -356,9 +356,9 @@ ion-ripple-effect {
|
||||
|
||||
### Example Components
|
||||
|
||||
- [ion-button](https://github.com/ionic-team/ionic/tree/master/core/src/components/button)
|
||||
- [ion-back-button](https://github.com/ionic-team/ionic/tree/master/core/src/components/back-button)
|
||||
- [ion-menu-button](https://github.com/ionic-team/ionic/tree/master/core/src/components/menu-button)
|
||||
- [ion-button](https://github.com/ionic-team/ionic/tree/main/core/src/components/button)
|
||||
- [ion-back-button](https://github.com/ionic-team/ionic/tree/main/core/src/components/back-button)
|
||||
- [ion-menu-button](https://github.com/ionic-team/ionic/tree/main/core/src/components/menu-button)
|
||||
|
||||
### References
|
||||
|
||||
@@ -372,7 +372,7 @@ ion-ripple-effect {
|
||||
|
||||
#### Example Components
|
||||
|
||||
- [ion-checkbox](https://github.com/ionic-team/ionic/tree/master/core/src/components/checkbox)
|
||||
- [ion-checkbox](https://github.com/ionic-team/ionic/tree/main/core/src/components/checkbox)
|
||||
|
||||
#### VoiceOver
|
||||
|
||||
@@ -498,7 +498,7 @@ This is a compromise we have to make in order for it to work with the other scre
|
||||
|
||||
#### Example Components
|
||||
|
||||
- [ion-toggle](https://github.com/ionic-team/ionic/tree/master/core/src/components/toggle)
|
||||
- [ion-toggle](https://github.com/ionic-team/ionic/tree/main/core/src/components/toggle)
|
||||
|
||||
#### Voiceover
|
||||
|
||||
@@ -631,11 +631,11 @@ Certain components can render an `<a>` or a `<button>` depending on the presence
|
||||
|
||||
### Example Components
|
||||
|
||||
- [ion-button](https://github.com/ionic-team/ionic/tree/master/core/src/components/button)
|
||||
- [ion-card](https://github.com/ionic-team/ionic/tree/master/core/src/components/card)
|
||||
- [ion-fab-button](https://github.com/ionic-team/ionic/tree/master/core/src/components/fab-button)
|
||||
- [ion-item-option](https://github.com/ionic-team/ionic/tree/master/core/src/components/item-option)
|
||||
- [ion-item](https://github.com/ionic-team/ionic/tree/master/core/src/components/item)
|
||||
- [ion-button](https://github.com/ionic-team/ionic/tree/main/core/src/components/button)
|
||||
- [ion-card](https://github.com/ionic-team/ionic/tree/main/core/src/components/card)
|
||||
- [ion-fab-button](https://github.com/ionic-team/ionic/tree/main/core/src/components/fab-button)
|
||||
- [ion-item-option](https://github.com/ionic-team/ionic/tree/main/core/src/components/item-option)
|
||||
- [ion-item](https://github.com/ionic-team/ionic/tree/main/core/src/components/item)
|
||||
|
||||
### Component Structure
|
||||
|
||||
|
||||
64
.github/CONTRIBUTING.md
vendored
64
.github/CONTRIBUTING.md
vendored
@@ -15,6 +15,12 @@ Thanks for your interest in contributing to the Ionic Framework! :tada:
|
||||
+ [Modifying Tests](#modifying-tests)
|
||||
- [Screenshot Tests](#screenshot-tests)
|
||||
+ [Building Changes](#building-changes)
|
||||
* [Angular, React, and Vue](#angular-react-and-vue)
|
||||
+ [Modifying Files](#modifying-files)
|
||||
+ [Preview Changes](#preview-changes-1)
|
||||
+ [Lint Changes](#lint-changes-1)
|
||||
+ [Modifying Tests](#modifying-tests-1)
|
||||
+ [Building Changes](#building-changes-1)
|
||||
* [Submit Pull Request](#submit-pull-request)
|
||||
- [Commit Message Guidelines](#commit-message-guidelines)
|
||||
* [Commit Message Format](#commit-message-format)
|
||||
@@ -30,7 +36,7 @@ Thanks for your interest in contributing to the Ionic Framework! :tada:
|
||||
|
||||
## Contributing Etiquette
|
||||
|
||||
Please see our [Contributor Code of Conduct](https://github.com/ionic-team/ionic/blob/master/CODE_OF_CONDUCT.md) for information on our rules of conduct.
|
||||
Please see our [Contributor Code of Conduct](https://github.com/ionic-team/ionic/blob/main/CODE_OF_CONDUCT.md) for information on our rules of conduct.
|
||||
|
||||
|
||||
## Creating an Issue
|
||||
@@ -87,7 +93,7 @@ Without a reliable code reproduction, it is unlikely we will be able to resolve
|
||||
1. [Download the installer](https://nodejs.org/) for the LTS version of Node.js. This is the best way to also [install npm](https://blog.npmjs.org/post/85484771375/how-to-install-npm#_=_).
|
||||
2. Fork this repository.
|
||||
3. Clone your fork.
|
||||
4. Create a new branch from master for your change.
|
||||
4. Create a new branch from main for your change.
|
||||
5. Navigate into the directory of the package you wish to modify (core, angular, etc.).
|
||||
6. Run `npm install` to install dependencies for this package.
|
||||
7. Follow the steps for the specific package below.
|
||||
@@ -160,17 +166,67 @@ Without a reliable code reproduction, it is unlikely we will be able to resolve
|
||||
3. Make sure the build has finished before committing. If you made changes to the documentation, properties, methods, or anything else that requires an update to a generate file, this needs to be committed.
|
||||
4. After the changes have been pushed, publish the branch and [create a pull request](#creating-a-pull-request).
|
||||
|
||||
### Angular, React, and Vue
|
||||
|
||||
#### Modifying Files
|
||||
|
||||
1. Locate the files inside the relevant root directory:
|
||||
- Angular: `/angular/src`
|
||||
- React: `/packages/react/src`
|
||||
- Vue: `/packages/vue/src`
|
||||
2. Make your changes to the files. If the change is overly complex or out of the ordinary, add comments so we can understand the changes.
|
||||
3. Run lint on the directory and make sure there are no errors.
|
||||
4. Build the project.
|
||||
5. After the build is finished, commit the changes. Please follow the [commit message format](#commit-message-format) for every commit.
|
||||
6. [Submit a Pull Request](#submit-pull-request) of your changes.
|
||||
|
||||
|
||||
|
||||
#### Preview Changes
|
||||
|
||||
1. Run `npm run start` inside of the relevant test app directory. This will sync your previously built changes into a test Ionic app:
|
||||
- Angular: `/angular/test-app`
|
||||
- React: `/packages/react/test-app`
|
||||
- Vue: `/packages/vue/test-app`
|
||||
2. In a browser, navigate to the page you wish to test.
|
||||
3. Alternatively, create a new page if you need to test something that is not already there.
|
||||
|
||||
|
||||
#### Lint Changes
|
||||
|
||||
1. Run `npm run lint` to lint the TypeScript in the relevant directory:
|
||||
- Angular: `/angular/src`
|
||||
- React: `/packages/react/src`
|
||||
- Vue: `/packages/vue/src`
|
||||
2. If there are lint errors, run `npm run lint.fix` to automatically fix any errors. Repeat step 1 to ensure the errors have been fixed, and manually fix them if not.
|
||||
|
||||
#### Modifying Tests
|
||||
|
||||
1. Locate the test to modify inside the relevant test app directory:
|
||||
- Angular: `/angular/test-app/e2e/src`
|
||||
- React: `/packages/react/test-app/cypress/integration`
|
||||
- Vue: `/packages/vue/test-app/tests/e2e`
|
||||
2. If a test exists, modify the test by adding an example to reproduce the problem fixed or feature added.
|
||||
3. If a new test is needed, copy an existing test, rename it, and edit the content in the test file.
|
||||
4. Run `npm run test` to run your tests.
|
||||
|
||||
#### Building Changes
|
||||
|
||||
1. Once all changes have been made, run `npm run build` inside of the root directory. This will add your changes to any auto-generated files, if necessary.
|
||||
2. Review the changes and, if everything looks correct, [commit](#commit-message-format) the changes.
|
||||
3. Make sure the build has finished before committing. If you made changes to the documentation, properties, methods, or anything else that requires an update to a generate file, this needs to be committed.
|
||||
4. After the changes have been pushed, publish the branch and [create a pull request](#creating-a-pull-request).
|
||||
|
||||
### Submit Pull Request
|
||||
|
||||
1. [Create a new pull request](https://github.com/ionic-team/ionic/compare) with the `master` branch as the `base`. You may need to click on `compare across forks` to find your changes.
|
||||
1. [Create a new pull request](https://github.com/ionic-team/ionic/compare) with the `main` branch as the `base`. You may need to click on `compare across forks` to find your changes.
|
||||
2. See the [Creating a pull request from a fork](https://help.github.com/articles/creating-a-pull-request-from-a-fork/) GitHub help article for more information.
|
||||
3. Please fill out the provided Pull Request template to the best of your ability and include any issues that are related.
|
||||
|
||||
|
||||
## Commit Message Guidelines
|
||||
|
||||
We have very precise rules over how our git commit messages should be formatted. This leads to readable messages that are easy to follow when looking through the project history. We also use the git commit messages to generate our [changelog](https://github.com/ionic-team/ionic/blob/master/CHANGELOG.md). Our format closely resembles Angular's [commit message guidelines](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit).
|
||||
We have very precise rules over how our git commit messages should be formatted. This leads to readable messages that are easy to follow when looking through the project history. We also use the git commit messages to generate our [changelog](https://github.com/ionic-team/ionic/blob/main/CHANGELOG.md). Our format closely resembles Angular's [commit message guidelines](https://github.com/angular/angular/blob/main/CONTRIBUTING.md#commit).
|
||||
|
||||
### Commit Message Format
|
||||
|
||||
|
||||
62
.github/PROCESS.md
vendored
62
.github/PROCESS.md
vendored
@@ -95,81 +95,81 @@ Issues with this label are not automatically closed and locked, so we manually c
|
||||
|
||||
We have two long-living branches:
|
||||
|
||||
- `master`: completed features, bug fixes, refactors, chores
|
||||
- `main`: completed features, bug fixes, refactors, chores
|
||||
- `stable`: the latest release
|
||||
|
||||
The overall flow:
|
||||
|
||||
1. Feature, refactor, and bug fix branches are created from `master`
|
||||
1. When a feature, refactor, or fix is complete it is merged into `master`
|
||||
1. A release branch is created from `master`
|
||||
1. When the release branch is done it is merged into `master` and `stable`
|
||||
1. Feature, refactor, and bug fix branches are created from `main`
|
||||
1. When a feature, refactor, or fix is complete it is merged into `main`
|
||||
1. A release branch is created from `main`
|
||||
1. When the release branch is done it is merged into `main` and `stable`
|
||||
1. If an issue in `stable` is detected a hotfix branch is created from `stable`
|
||||
1. Once the hotfix is complete it is merged to both `master` and `stable`
|
||||
1. All branches should follow the syntax of `{type}-{details}` where `{type}` is the type of branch (`hotfix`, `release`, or one of the [commit types](https://github.com/ionic-team/ionic/blob/master/.github/CONTRIBUTING.md#commit-message-format)) and `{details}` is a few hyphen separated words explaining the branch
|
||||
1. Once the hotfix is complete it is merged to both `main` and `stable`
|
||||
1. All branches should follow the syntax of `{type}-{details}` where `{type}` is the type of branch (`hotfix`, `release`, or one of the [commit types](https://github.com/ionic-team/ionic/blob/main/.github/CONTRIBUTING.md#commit-message-format)) and `{details}` is a few hyphen separated words explaining the branch
|
||||
|
||||
### Stable and Master Branches
|
||||
### Stable and Main Branches
|
||||
|
||||
#### Stable Branch
|
||||
|
||||
Branches created from `stable`:
|
||||
|
||||
The following branch should be merged back to **both** `master` and `stable`:
|
||||
The following branch should be merged back to **both** `main` and `stable`:
|
||||
|
||||
- A `hotfix` branch (e.g. `hotfix-missing-export`): a bug fix that is fixing a regression or issue with a published release
|
||||
|
||||
A `hotfix` branch should be the **only** branch that is created from stable.
|
||||
|
||||
#### Master Branch
|
||||
#### Main Branch
|
||||
|
||||
Branches created from `master`:
|
||||
Branches created from `main`:
|
||||
|
||||
The following branches should be merged back to `master` via a pull request:
|
||||
The following branches should be merged back to `main` via a pull request:
|
||||
|
||||
1. A feature branch (e.g. `feat-desktop-support`): an addition to the API that is not a bug fix or regression fix
|
||||
1. A bug fix branch (e.g. `fix-tab-color`): a bug fix that is not fixing a regression or issue with a published release
|
||||
1. All other types listed in the [commit message types](https://github.com/ionic-team/ionic/blob/master/.github/CONTRIBUTING.md#commit-message-format): `docs`, `style`, `refactor`, `perf`, `test`, `chore`
|
||||
1. All other types listed in the [commit message types](https://github.com/ionic-team/ionic/blob/main/.github/CONTRIBUTING.md#commit-message-format): `docs`, `style`, `refactor`, `perf`, `test`, `chore`
|
||||
|
||||
The following branch should be merged back to **both** `master` and `stable`:
|
||||
The following branch should be merged back to **both** `main` and `stable`:
|
||||
|
||||
1. A `release` branch (e.g. `release-4.1.x`): contains all fixes and (optionally) features that are tested and should go into the release
|
||||
|
||||
|
||||
### Feature Branches
|
||||
|
||||
Each new feature should reside in its own branch, based on the `master` branch. When a feature is complete, it should go into a pull request that gets merged back into `master`. A pull request adding a feature should be approved by two team members. Features should never interact directly with `stable`.
|
||||
Each new feature should reside in its own branch, based on the `main` branch. When a feature is complete, it should go into a pull request that gets merged back into `main`. A pull request adding a feature should be approved by two team members. Features should never interact directly with `stable`.
|
||||
|
||||
|
||||
### Release Branches
|
||||
|
||||
Once `master` has acquired enough features for a release (or a predetermined release date is approaching), fork a release branch off of `master`. Creating this branch starts the next release cycle, so no new features can be added after this point - only bug fixes, documentation generation, and other release-oriented tasks should go in this branch.
|
||||
Once `main` has acquired enough features for a release (or a predetermined release date is approaching), fork a release branch off of `main`. Creating this branch starts the next release cycle, so no new features can be added after this point - only bug fixes, documentation generation, and other release-oriented tasks should go in this branch.
|
||||
|
||||
Once the release is ready to ship, it will get merged into `stable` and `master`, then the release branch will be deleted. It’s important to merge back into `master` because critical updates may have been added to the release branch and they need to be accessible to new features. This should be done in a pull request after review.
|
||||
Once the release is ready to ship, it will get merged into `stable` and `main`, then the release branch will be deleted. It’s important to merge back into `main` because critical updates may have been added to the release branch and they need to be accessible to new features. This should be done in a pull request after review.
|
||||
|
||||
See the [steps for releasing](#releasing) below for detailed information on how to publish a release.
|
||||
|
||||
### Version Branches
|
||||
|
||||
Once a release has shipped and the release branch has been merged into `stable` and `master` it should also be merged into its corresponding version branch. These version branches allow us to ship updates for specific versions of the framework (i.e. Lets us ship a bug fix that only affects 4.2.x).
|
||||
Once a release has shipped and the release branch has been merged into `stable` and `main` it should also be merged into its corresponding version branch. These version branches allow us to ship updates for specific versions of the framework (i.e. Lets us ship a bug fix that only affects 4.2.x).
|
||||
|
||||
Patch releases should be merged into their corresponding version branches. For example, a `release-4.1.1` branch should be merged into the `4.1.x` version branch and a `release-5.0.1` branch should be merged into the `5.0.x` version branch.
|
||||
|
||||
When releasing a major version such as `5.0.0 ` or a minor version such as `4.1.0` , the version branch will not exist. The version branch should be created once the release branch has been merged into `stable` and `master`. For example, when releasing `4.1.0`, the `release-4.1.0` release branch should be merged into `stable` and `master` and then the `4.1.x` version branch should be created off the latest `stable`.
|
||||
When releasing a major version such as `5.0.0 ` or a minor version such as `4.1.0` , the version branch will not exist. The version branch should be created once the release branch has been merged into `stable` and `main`. For example, when releasing `4.1.0`, the `release-4.1.0` release branch should be merged into `stable` and `main` and then the `4.1.x` version branch should be created off the latest `stable`.
|
||||
|
||||
|
||||
### Hotfix Branches
|
||||
|
||||
Maintenance or “hotfix” branches are used to quickly patch production releases. This is the only branch that should fork directly off of `stable`. As soon as the fix is complete, it should be merged into both `stable` and `master` (or the current release branch).
|
||||
Maintenance or “hotfix” branches are used to quickly patch production releases. This is the only branch that should fork directly off of `stable`. As soon as the fix is complete, it should be merged into both `stable` and `main` (or the current release branch).
|
||||
|
||||
|
||||
### Examples
|
||||
|
||||
#### Making a Change
|
||||
|
||||
1. Create a branch from `master`.
|
||||
1. Create a branch from `main`.
|
||||
1. Make changes. Limit your changes to a "unit of work", meaning don't include irrelevant changes that may confuse and delay the change.
|
||||
1. Push changes.
|
||||
1. Create a PR with the base of `master`.
|
||||
1. Create a PR with the base of `main`.
|
||||
1. Have someone approve your change (optional right now--at your discretion).
|
||||
|
||||
<img width="236" alt="image" src="https://user-images.githubusercontent.com/236501/47031893-913e0480-d136-11e8-9d9a-4b6297a4d7ba.png">
|
||||
@@ -182,13 +182,13 @@ Maintenance or “hotfix” branches are used to quickly patch production releas
|
||||
|
||||
<img width="192" alt="Squash and merge button" src="https://user-images.githubusercontent.com/236501/47031620-da418900-d135-11e8-91ff-e84f2478b2b3.png">
|
||||
|
||||
1. During confirmation, rewrite the commit message using our [Commit Message Format guidelines](https://github.com/ionic-team/ionic/blob/master/.github/CONTRIBUTING.md#commit-message-format). Keep the `(#1234)` at the end; it will create a link to the PR in the commit history and `CHANGELOG.md`. This is where commits on `master` become permanent.
|
||||
1. During confirmation, rewrite the commit message using our [Commit Message Format guidelines](https://github.com/ionic-team/ionic/blob/main/.github/CONTRIBUTING.md#commit-message-format). Keep the `(#1234)` at the end; it will create a link to the PR in the commit history and `CHANGELOG.md`. This is where commits on `main` become permanent.
|
||||
|
||||
<img width="672" alt="Squash and merge confirmation" src="https://user-images.githubusercontent.com/236501/47031753-31dff480-d136-11e8-9116-03934961bdc2.png">
|
||||
|
||||
1. Confirm squash and merge into `master`.
|
||||
1. Confirm squash and merge into `main`.
|
||||
|
||||
#### Updating from `master`
|
||||
#### Updating from `main`
|
||||
|
||||
1. Pull the latest changes locally.
|
||||
1. Merge the changes, fixing any conflicts.
|
||||
@@ -204,7 +204,7 @@ OR
|
||||
|
||||
#### Hotfixes
|
||||
|
||||
Hotfixes bypass `master` and should only be used for urgent fixes that can't wait for the next release to be ready.
|
||||
Hotfixes bypass `main` and should only be used for urgent fixes that can't wait for the next release to be ready.
|
||||
|
||||
1. Create a branch from `stable`.
|
||||
1. Make changes.
|
||||
@@ -215,13 +215,13 @@ Hotfixes bypass `master` and should only be used for urgent fixes that can't wai
|
||||
|
||||
<img width="192" alt="Squash and merge button" src="https://user-images.githubusercontent.com/236501/47031620-da418900-d135-11e8-91ff-e84f2478b2b3.png">
|
||||
|
||||
1. During confirmation, rewrite the commit message using our [Commit Message Format guidelines](https://github.com/ionic-team/ionic/blob/master/.github/CONTRIBUTING.md#commit-message-format). Keep the `(#1234)` at the end; it will create a link to the PR in the commit history and `CHANGELOG.md`. This is where commits on `master` become permanent.
|
||||
1. During confirmation, rewrite the commit message using our [Commit Message Format guidelines](https://github.com/ionic-team/ionic/blob/main/.github/CONTRIBUTING.md#commit-message-format). Keep the `(#1234)` at the end; it will create a link to the PR in the commit history and `CHANGELOG.md`. This is where commits on `main` become permanent.
|
||||
|
||||
<img width="672" alt="Squash and merge confirmation" src="https://user-images.githubusercontent.com/236501/47031753-31dff480-d136-11e8-9116-03934961bdc2.png">
|
||||
|
||||
1. Confirm squash and merge into `stable`.
|
||||
1. CI builds `stable`, performing the release.
|
||||
1. Create a PR to merge `stable` into `master`.
|
||||
1. Create a PR to merge `stable` into `main`.
|
||||
1. Click **Merge pull request**. Use the dropdown to select this option if necessary.
|
||||
|
||||
<img width="191" alt="Merge pull request button" src="https://user-images.githubusercontent.com/236501/47032669-8be1b980-d138-11e8-9a90-d1518c223184.png">
|
||||
@@ -229,7 +229,7 @@ Hotfixes bypass `master` and should only be used for urgent fixes that can't wai
|
||||
|
||||
## Releasing
|
||||
|
||||
1. Create the release branch from `master`, for example: `release-4.5.0`.
|
||||
1. Create the release branch from `main`, for example: `release-4.5.0`.
|
||||
|
||||
1. For major or minor releases, create a version branch based off the latest version branch. For example, if releasing 4.5.0, create a branch called `4.5.x` based off `4.4.x`.
|
||||
|
||||
@@ -244,7 +244,7 @@ Hotfixes bypass `master` and should only be used for urgent fixes that can't wai
|
||||
1. Run `npm run release.prepare`
|
||||
- Select the version based on the type of commits and the [Ionic Versioning](https://ionicframework.com/docs/intro/versioning)
|
||||
- After the process completes, verify the version number in all packages (`core`, `docs`, `angular`)
|
||||
- Verify the changelog commits are accurate and follow the [proper format]((https://github.com/ionic-team/ionic/blob/master/.github/CONTRIBUTING.md#commit-message-format))
|
||||
- Verify the changelog commits are accurate and follow the [proper format]((https://github.com/ionic-team/ionic/blob/main/.github/CONTRIBUTING.md#commit-message-format))
|
||||
- For major or minor releases, ensure that the version number has an associated title (for example: `4.5.0 Boron`)
|
||||
- Commit these changes with the version number as the message, e.g. `git commit -m "4.5.0"`
|
||||
|
||||
@@ -258,4 +258,4 @@ Hotfixes bypass `master` and should only be used for urgent fixes that can't wai
|
||||
|
||||
1. Rewrite the commit message to `merge release-[VERSION]` with the proper release branch. For example, if this release is for `4.5.0`, the message would be `merge release-4.5.0`.
|
||||
|
||||
1. Submit a pull request from the release branch into `master`. Merge this pull request using the same commit format in the last step, to ensure any changes made on the release branch get added to future releases.
|
||||
1. Submit a pull request from the release branch into `main`. Merge this pull request using the same commit format in the last step, to ensure any changes made on the release branch get added to future releases.
|
||||
|
||||
3
.github/ionic-issue-bot.yml
vendored
3
.github/ionic-issue-bot.yml
vendored
@@ -41,8 +41,7 @@ closeAndLock:
|
||||
- label: "ionitron: support"
|
||||
message: >
|
||||
Thanks for the issue! This issue appears to be a support request. We use this issue tracker exclusively for
|
||||
bug reports and feature requests. Please use our [forum](https://forum.ionicframework.com) or our
|
||||
[slack channel](https://ionicworldwide.herokuapp.com/) for questions about the framework.
|
||||
bug reports and feature requests. Please use our [forum](https://forum.ionicframework.com) for questions about the framework.
|
||||
|
||||
|
||||
Thank you for using Ionic!
|
||||
|
||||
22
.github/workflows/actions/build-angular-server/action.yml
vendored
Normal file
22
.github/workflows/actions/build-angular-server/action.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: 'Build Ionic Angular Server'
|
||||
description: 'Build Ionic Angular Server'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15.x
|
||||
|
||||
- name: Install Angular Server Dependencies
|
||||
run: npm install --legacy-peer-deps
|
||||
shell: bash
|
||||
working-directory: ./packages/angular-server
|
||||
- name: Build
|
||||
run: npm run build.prod
|
||||
shell: bash
|
||||
working-directory: ./packages/angular-server
|
||||
- uses: ./.github/workflows/actions/upload-archive
|
||||
with:
|
||||
name: ionic-angular-server
|
||||
output: packages/angular-server/AngularServerBuild.zip
|
||||
paths: packages/angular-server/dist
|
||||
53
.github/workflows/actions/build-angular/action.yml
vendored
Normal file
53
.github/workflows/actions/build-angular/action.yml
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
name: 'Build Ionic Angular'
|
||||
description: 'Build Ionic Angular'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
path: ./core/node_modules
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('./core/package-lock.json')}}-v1
|
||||
- name: Cache Angular Node Modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: angular-node-modules
|
||||
with:
|
||||
path: ./angular/node_modules
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('./angular/package-lock.json')}}-v1
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- name: Install Angular Dependencies
|
||||
run: npm install
|
||||
shell: bash
|
||||
working-directory: ./angular
|
||||
- name: Link @ionic/core
|
||||
run: npm link
|
||||
shell: bash
|
||||
working-directory: ./core
|
||||
- name: Link @ionic/core in @ionic/angular
|
||||
run: npm link @ionic/core
|
||||
shell: bash
|
||||
working-directory: ./angular
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
shell: bash
|
||||
working-directory: ./angular
|
||||
- name: Build
|
||||
run: npm run build
|
||||
shell: bash
|
||||
working-directory: ./angular
|
||||
- uses: ./.github/workflows/actions/upload-archive
|
||||
with:
|
||||
name: ionic-angular
|
||||
output: ./angular/AngularBuild.zip
|
||||
paths: ./angular/dist
|
||||
30
.github/workflows/actions/build-core/action.yml
vendored
Normal file
30
.github/workflows/actions/build-core/action.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
name: 'Build Ionic Core'
|
||||
description: 'Build Ionic Core'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15.x
|
||||
|
||||
- name: Cache Node Modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
path: ./core/node_modules
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('./core/package-lock.json') }}-v1
|
||||
- name: Install Dependencies
|
||||
run: npm install
|
||||
working-directory: ./core
|
||||
shell: bash
|
||||
- name: Build Core
|
||||
run: npm run build -- --ci
|
||||
working-directory: ./core
|
||||
shell: bash
|
||||
- uses: ./.github/workflows/actions/upload-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
output: core/CoreBuild.zip
|
||||
paths: core/dist core/components core/css core/hydrate core/loader
|
||||
51
.github/workflows/actions/build-react-router/action.yml
vendored
Normal file
51
.github/workflows/actions/build-react-router/action.yml
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
name: 'Build Ionic React Router'
|
||||
description: 'Build Ionic React Router'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
path: ./core/node_modules
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('./core/package-lock.json') }}-v1
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-react
|
||||
path: ./packages/react
|
||||
filename: ReactBuild.zip
|
||||
- name: Install Dependencies
|
||||
run: npm install --legacy-peer-deps
|
||||
shell: bash
|
||||
working-directory: ./packages/react-router
|
||||
- name: Sync
|
||||
run: npm run sync
|
||||
shell: bash
|
||||
working-directory: ./packages/react-router
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
shell: bash
|
||||
working-directory: ./packages/react-router
|
||||
- name: Build
|
||||
run: npm run build
|
||||
shell: bash
|
||||
working-directory: ./packages/react-router
|
||||
- name: Test Spec
|
||||
run: npm run test.spec
|
||||
shell: bash
|
||||
working-directory: ./packages/react-router
|
||||
- uses: ./.github/workflows/actions/upload-archive
|
||||
with:
|
||||
name: ionic-react-router
|
||||
output: packages/react-router/ReactRouterBuild.zip
|
||||
paths: packages/react-router/dist
|
||||
46
.github/workflows/actions/build-react/action.yml
vendored
Normal file
46
.github/workflows/actions/build-react/action.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: 'Build Ionic React'
|
||||
description: 'Build Ionic React'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
path: ./core/node_modules
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('./core/package-lock.json') }}-v1
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- name: Install React Dependencies
|
||||
run: npm install --legacy-peer-deps
|
||||
shell: bash
|
||||
working-directory: ./packages/react
|
||||
- name: Sync
|
||||
run: npm run sync
|
||||
shell: bash
|
||||
working-directory: ./packages/react
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
shell: bash
|
||||
working-directory: ./packages/react
|
||||
- name: Build
|
||||
run: npm run build
|
||||
shell: bash
|
||||
working-directory: ./packages/react
|
||||
- name: Test Spec
|
||||
run: npm run test.spec
|
||||
shell: bash
|
||||
working-directory: ./packages/react
|
||||
- uses: ./.github/workflows/actions/upload-archive
|
||||
with:
|
||||
name: ionic-react
|
||||
output: packages/react/ReactBuild.zip
|
||||
paths: packages/react/dist packages/react/css
|
||||
51
.github/workflows/actions/build-vue-router/action.yml
vendored
Normal file
51
.github/workflows/actions/build-vue-router/action.yml
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
name: 'Build Ionic Vue Router'
|
||||
description: 'Builds Ionic Vue Router'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
path: ./core/node_modules
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('./core/package-lock.json') }}-v1
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-vue
|
||||
path: ./packages/vue
|
||||
filename: VueBuild.zip
|
||||
- name: Install Vue Router Dependencies
|
||||
run: npm install
|
||||
shell: bash
|
||||
working-directory: ./packages/vue-router
|
||||
- name: Sync
|
||||
run: npm run sync
|
||||
shell: bash
|
||||
working-directory: ./packages/vue-router
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
shell: bash
|
||||
working-directory: ./packages/vue-router
|
||||
- name: Build
|
||||
run: npm run build
|
||||
shell: bash
|
||||
working-directory: ./packages/vue-router
|
||||
- name: Test Spec
|
||||
run: npm run test.spec
|
||||
shell: bash
|
||||
working-directory: ./packages/vue-router
|
||||
- uses: ./.github/workflows/actions/upload-archive
|
||||
with:
|
||||
name: ionic-vue-router
|
||||
output: ./packages/vue-router/VueRouterBuild.zip
|
||||
paths: packages/vue-router/dist
|
||||
42
.github/workflows/actions/build-vue/action.yml
vendored
Normal file
42
.github/workflows/actions/build-vue/action.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
name: 'Build Ionic Vue'
|
||||
description: 'Build Ionic Vue'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
path: ./core/node_modules
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('./core/package-lock.json') }}-v1
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- name: Install Vue Dependencies
|
||||
run: npm install
|
||||
shell: bash
|
||||
working-directory: ./packages/vue
|
||||
- name: Sync
|
||||
run: npm run sync
|
||||
shell: bash
|
||||
working-directory: ./packages/vue
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
shell: bash
|
||||
working-directory: ./packages/vue
|
||||
- name: Build
|
||||
run: npm run build
|
||||
shell: bash
|
||||
working-directory: ./packages/vue
|
||||
- uses: ./.github/workflows/actions/upload-archive
|
||||
with:
|
||||
name: ionic-vue
|
||||
output: packages/vue/VueBuild.zip
|
||||
paths: packages/vue/dist packages/vue/css
|
||||
19
.github/workflows/actions/download-archive/action.yml
vendored
Normal file
19
.github/workflows/actions/download-archive/action.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: 'Ionic Framework Archive Download'
|
||||
description: 'Downloads and decompresses an archive from a previous job'
|
||||
inputs:
|
||||
path:
|
||||
description: 'Input archive name'
|
||||
filename:
|
||||
description: 'Input file name'
|
||||
name:
|
||||
description: 'Archive name'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: ${{ inputs.name }}
|
||||
path: ${{ inputs.path }}
|
||||
- name: Exract Archive
|
||||
run: unzip -q -o ${{ inputs.path }}/${{ inputs.filename }}
|
||||
shell: bash
|
||||
39
.github/workflows/actions/test-angular-e2e/action.yml
vendored
Normal file
39
.github/workflows/actions/test-angular-e2e/action.yml
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
name: 'Test Angular E2E'
|
||||
description: 'Test Angular E2E'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
path: ./core/node_modules
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('./core/package-lock.json') }}-v1
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-angular
|
||||
path: ./angular
|
||||
filename: AngularBuild.zip
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-angular-server
|
||||
path: ./packages/angular-server
|
||||
filename: AngularServerBuild.zip
|
||||
- name: Install Dependencies
|
||||
run: npm install --legacy-peer-deps
|
||||
shell: bash
|
||||
working-directory: ./angular/test/test-app
|
||||
- name: Run Tests
|
||||
run: npm run test
|
||||
shell: bash
|
||||
working-directory: ./angular/test/test-app
|
||||
18
.github/workflows/actions/test-core-clean-build/action.yml
vendored
Normal file
18
.github/workflows/actions/test-core-clean-build/action.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
name: 'Test Core Clean Build'
|
||||
description: 'Test Core Clean Build'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15.x
|
||||
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- name: Check Diff
|
||||
run: git diff --exit-code
|
||||
shell: bash
|
||||
working-directory: ./core
|
||||
25
.github/workflows/actions/test-core-e2e/action.yml
vendored
Normal file
25
.github/workflows/actions/test-core-e2e/action.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: 'Test Core E2E'
|
||||
description: 'Test Core E2E'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
path: ./core/node_modules
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('./core/package-lock.json') }}-v1
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- name: Test
|
||||
run: npm run test.e2e -- --ci --no-build
|
||||
shell: bash
|
||||
working-directory: ./core
|
||||
20
.github/workflows/actions/test-core-lint/action.yml
vendored
Normal file
20
.github/workflows/actions/test-core-lint/action.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
name: 'Test Core Lint'
|
||||
description: 'Test Core Lint'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
path: ./core/node_modules
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('./core/package-lock.json') }}-v1
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
shell: bash
|
||||
working-directory: ./core
|
||||
33
.github/workflows/actions/test-core-screenshot-main/action.yml
vendored
Normal file
33
.github/workflows/actions/test-core-screenshot-main/action.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
name: 'Test Core Screenshot Main'
|
||||
description: 'Test Core Screenshot Main'
|
||||
inputs:
|
||||
access-key-id:
|
||||
description: 'AWS_ACCESS_KEY_ID'
|
||||
secret-access-key:
|
||||
description: 'AWS_SECRET_ACCESS_KEY'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
path: ./core/node_modules
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('./core/package-lock.json') }}-v1
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- name: Test
|
||||
run: npx stencil test --e2e --screenshot --screenshot-connector=scripts/screenshot/ci.js --ci --update-screenshot --no-build || true
|
||||
shell: bash
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ inputs.access-key-id }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ inputs.secret-access-key }}
|
||||
working-directory: ./core
|
||||
33
.github/workflows/actions/test-core-screenshot/action.yml
vendored
Normal file
33
.github/workflows/actions/test-core-screenshot/action.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
name: 'Test Core Screenshot'
|
||||
description: 'Test Core Screenshot'
|
||||
inputs:
|
||||
access-key-id:
|
||||
description: 'AWS_ACCESS_KEY_ID'
|
||||
secret-access-key:
|
||||
description: 'AWS_SECRET_ACCESS_KEY'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
path: ./core/node_modules
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('./core/package-lock.json') }}-v1
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- name: Test
|
||||
run: npx stencil test --e2e --screenshot --screenshot-connector=scripts/screenshot/ci.js --ci --no-build || true
|
||||
shell: bash
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ inputs.access-key-id }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ inputs.secret-access-key }}
|
||||
working-directory: ./core
|
||||
25
.github/workflows/actions/test-core-spec/action.yml
vendored
Normal file
25
.github/workflows/actions/test-core-spec/action.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: 'Test Core Spec'
|
||||
description: 'Test Core Spec'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
path: ./core/node_modules
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('./core/package-lock.json') }}-v1
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- name: Test
|
||||
run: npm run test.spec -- --ci
|
||||
shell: bash
|
||||
working-directory: ./core
|
||||
37
.github/workflows/actions/test-react-e2e/action.yml
vendored
Normal file
37
.github/workflows/actions/test-react-e2e/action.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
name: 'Test React E2E'
|
||||
description: 'Test React E2E'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
path: ./core/node_modules
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('./core/package-lock.json') }}-v1
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-react
|
||||
path: ./packages/react
|
||||
filename: ReactBuild.zip
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-react-router
|
||||
path: ./packages/react-router
|
||||
filename: ReactRouterBuild.zip
|
||||
- uses: cypress-io/github-action@v2
|
||||
with:
|
||||
browser: chrome
|
||||
headless: true
|
||||
start: npm run start.ci
|
||||
working-directory: ./packages/react/test-app
|
||||
37
.github/workflows/actions/test-react-router-e2e/action.yml
vendored
Normal file
37
.github/workflows/actions/test-react-router-e2e/action.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
name: 'Test React Router E2E'
|
||||
description: 'Test React Router '
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
path: ./core/node_modules
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('./core/package-lock.json') }}-v1
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-react
|
||||
path: ./packages/react
|
||||
filename: ReactBuild.zip
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-react-router
|
||||
path: ./packages/react-router
|
||||
filename: ReactRouterBuild.zip
|
||||
- uses: cypress-io/github-action@v2
|
||||
with:
|
||||
browser: chrome
|
||||
headless: true
|
||||
start: npm run start.ci
|
||||
working-directory: ./packages/react-router/test-app
|
||||
47
.github/workflows/actions/test-vue-e2e/action.yml
vendored
Normal file
47
.github/workflows/actions/test-vue-e2e/action.yml
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
name: 'Test Vue E2E'
|
||||
description: 'Test Vue E2E'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15.x
|
||||
|
||||
- name: Cache Core Node Modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: core-node-modules
|
||||
with:
|
||||
path: ./core/node_modules
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('./core/package-lock.json') }}-v1
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-vue
|
||||
path: ./packages/vue
|
||||
filename: VueBuild.zip
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-vue-router
|
||||
path: ./packages/vue-router
|
||||
filename: VueRouterBuild.zip
|
||||
- name: Install Dependencies
|
||||
run: npm install
|
||||
shell: bash
|
||||
working-directory: ./packages/vue/test-app
|
||||
- name: Sync
|
||||
run: npm run sync
|
||||
shell: bash
|
||||
working-directory: ./packages/vue/test-app
|
||||
- name: Run Spec Tests
|
||||
run: npm run test:unit
|
||||
shell: bash
|
||||
working-directory: ./packages/vue/test-app
|
||||
- name: Run E2E Tests
|
||||
run: npm run test:e2e
|
||||
shell: bash
|
||||
working-directory: ./packages/vue/test-app
|
||||
19
.github/workflows/actions/upload-archive/action.yml
vendored
Normal file
19
.github/workflows/actions/upload-archive/action.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: 'Ionic Framework Archive Upload'
|
||||
description: 'Compresses and uploads an archive to be reused across jobs'
|
||||
inputs:
|
||||
paths:
|
||||
description: 'Paths to files or directories to archive'
|
||||
output:
|
||||
description: 'Output file name'
|
||||
name:
|
||||
description: 'Archive name'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Create Archive
|
||||
run: zip -q -r ${{ inputs.output }} ${{ inputs.paths }}
|
||||
shell: bash
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ inputs.name }}
|
||||
path: ${{ inputs.output }}
|
||||
132
.github/workflows/build.yml
vendored
Normal file
132
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
name: 'Ionic Framework Build'
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ '**' ]
|
||||
|
||||
jobs:
|
||||
build-core:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/workflows/actions/build-core
|
||||
|
||||
test-core-clean-build:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/workflows/actions/test-core-clean-build
|
||||
|
||||
test-core-lint:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/workflows/actions/test-core-lint
|
||||
|
||||
test-core-spec:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/workflows/actions/test-core-spec
|
||||
|
||||
test-core-e2e:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/workflows/actions/test-core-e2e
|
||||
|
||||
test-core-screenshot:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref != 'refs/heads/main' && !github.event.pull_request.head.repo.fork
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/workflows/actions/test-core-screenshot
|
||||
with:
|
||||
access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
|
||||
test-core-screenshot-main:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/main'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/workflows/actions/test-core-screenshot-main
|
||||
with:
|
||||
access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
|
||||
build-vue:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/workflows/actions/build-vue
|
||||
|
||||
build-vue-router:
|
||||
needs: [build-vue]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/workflows/actions/build-vue-router
|
||||
|
||||
test-vue-e2e:
|
||||
needs: [build-vue, build-vue-router]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/workflows/actions/test-vue-e2e
|
||||
|
||||
build-angular:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/workflows/actions/build-angular
|
||||
|
||||
build-angular-server:
|
||||
needs: [build-angular]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/workflows/actions/build-angular-server
|
||||
|
||||
test-angular-e2e:
|
||||
needs: [build-angular, build-angular-server]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/workflows/actions/test-angular-e2e
|
||||
|
||||
build-react:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/workflows/actions/build-react
|
||||
|
||||
build-react-router:
|
||||
needs: [build-react]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/workflows/actions/build-react-router
|
||||
|
||||
test-react-router-e2e:
|
||||
needs: [build-react, build-react-router]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/workflows/actions/test-react-router-e2e
|
||||
|
||||
test-react-e2e:
|
||||
needs: [build-react, build-react-router]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/workflows/actions/test-react-e2e
|
||||
18
.github/workflows/dev-build.yml
vendored
Normal file
18
.github/workflows/dev-build.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
name: 'Ionic Dev Build'
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
dev-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 15.x
|
||||
- name: Create Dev Build
|
||||
run: npm run release.dev -- --skip-prompt
|
||||
shell: bash
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
@@ -44,7 +44,7 @@ async function askNpmTag(version) {
|
||||
type: 'list',
|
||||
name: 'npmTag',
|
||||
message: 'Select npm tag or specify a new tag',
|
||||
choices: ['latest', 'next', 'v4-lts']
|
||||
choices: ['latest', 'next', 'v4-lts', 'v5-lts']
|
||||
.concat([
|
||||
new inquirer.Separator(),
|
||||
{
|
||||
|
||||
@@ -127,7 +127,7 @@ async function publishGithub(version, gitTag, changelog, npmTag) {
|
||||
let branch = await execa.stdout('git', ['symbolic-ref', '--short', 'HEAD']);
|
||||
|
||||
if (!branch) {
|
||||
branch = 'master';
|
||||
branch = 'main';
|
||||
}
|
||||
|
||||
await octokit.repos.createRelease({
|
||||
|
||||
96
CHANGELOG.md
96
CHANGELOG.md
@@ -1,3 +1,99 @@
|
||||
## [5.9.4](https://github.com/ionic-team/ionic/compare/v5.9.3...v5.9.4) (2022-04-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **core:** inherit aria attributes on host elements ([#25156](https://github.com/ionic-team/ionic/issues/25156)) ([#25169](https://github.com/ionic-team/ionic/issues/25169)) ([ffb056d](https://github.com/ionic-team/ionic/commit/ffb056d50e126a1b89f5133de1e7516d0c29a61a))
|
||||
|
||||
|
||||
|
||||
## [5.9.3](https://github.com/ionic-team/ionic/compare/v5.9.2...v5.9.3) (2021-12-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **vue:** improve query params handling in tabs ([#24355](https://github.com/ionic-team/ionic/issues/24355)) ([1c28750](https://github.com/ionic-team/ionic/commit/1c2875044ad4d93fdca866017159a89f4dc8872d)), closes [#24353](https://github.com/ionic-team/ionic/issues/24353)
|
||||
* **vue:** tabs no longer get unmounted when navigating back to a tabs context ([#24337](https://github.com/ionic-team/ionic/issues/24337)) ([4aab72b](https://github.com/ionic-team/ionic/commit/4aab72b06159729d2dcd18b2ef0b76f693e5a74e)), closes [#24332](https://github.com/ionic-team/ionic/issues/24332)
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **content:** remove global click listener to improve interaction performance ([#24360](https://github.com/ionic-team/ionic/issues/24360)) ([9c9e28c](https://github.com/ionic-team/ionic/commit/9c9e28ccc9f899c403c757d911ac02d9099415af)), closes [#24359](https://github.com/ionic-team/ionic/issues/24359)
|
||||
|
||||
|
||||
|
||||
## [5.9.2](https://github.com/ionic-team/ionic/compare/v5.9.1...v5.9.2) (2021-12-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** improve typing when compiling with legacy View Engine ([#24221](https://github.com/ionic-team/ionic/issues/24221)) ([816096f](https://github.com/ionic-team/ionic/commit/816096f89747e943a4a273175d384189f25e4628))
|
||||
* **content:** ensure fixed slot renders on top of content in iOS ([#24300](https://github.com/ionic-team/ionic/issues/24300)) ([e41b0e0](https://github.com/ionic-team/ionic/commit/e41b0e0cf2a794972d7f4d8943a0bec3d1e08016)), closes [#24286](https://github.com/ionic-team/ionic-framework/issues/24286)
|
||||
* **popover:** improve scrolling in popover when using header and footer ([#24294](https://github.com/ionic-team/ionic/issues/24294)) ([f6a00ea](https://github.com/ionic-team/ionic/commit/f6a00ea9544aa70620b5f8f65a7702fa3bedd974))
|
||||
* **react:** present and dismiss hooks return promises ([#24299](https://github.com/ionic-team/ionic/issues/24299)) ([4b26fea](https://github.com/ionic-team/ionic/commit/4b26feaa47efed4806aba565a52554db232b99e2)), closes [#24293](https://github.com/ionic-team/ionic-framework/issues/24293)
|
||||
* **react:** properly check for custom elements to avoid errors in unit tests ([#24156](https://github.com/ionic-team/ionic/issues/24156)) ([8f188ea](https://github.com/ionic-team/ionic/commit/8f188eaae7422c9e81053868b9dd93b4ac738e98)), closes [#24149](https://github.com/ionic-team/ionic/issues/24149)
|
||||
* **router:** popping route now accounts for route params ([#24315](https://github.com/ionic-team/ionic/issues/24315)) ([5e5054d](https://github.com/ionic-team/ionic/commit/5e5054d369ad68c9ac43e12439d71fb42d6ca26b)), closes [#24223](https://github.com/ionic-team/ionic-framework/issues/24223)
|
||||
* **slides:** update swiper instance after initialization ([#24257](https://github.com/ionic-team/ionic/issues/24257)) ([89e4bc5](https://github.com/ionic-team/ionic/commit/89e4bc56a1c3cd4fb26fc5514f38c6a01f047297)), closes [#19638](https://github.com/ionic-team/ionic-framework/issues/19638)
|
||||
* **vue:** ionic lifecycle hooks now run when using vue 3.2 setup syntax ([#24253](https://github.com/ionic-team/ionic/issues/24253)) ([fb96ab5](https://github.com/ionic-team/ionic/commit/fb96ab5a26d87818a8b64ee82df0020355054183)), closes [#23824](https://github.com/ionic-team/ionic/issues/23824)
|
||||
* **vue:** switching between tabs preserves query string ([#24297](https://github.com/ionic-team/ionic/issues/24297)) ([047d3c7](https://github.com/ionic-team/ionic/commit/047d3c77729db08e4fd84f426f6c5c2af0eacc52)), closes [#23699](https://github.com/ionic-team/ionic/issues/23699)
|
||||
|
||||
|
||||
|
||||
## [5.9.1](https://github.com/ionic-team/ionic/compare/v5.9.0...v5.9.1) (2021-11-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** build is now in correct directory ([#24236](https://github.com/ionic-team/ionic/issues/24236)) ([1d983fa](https://github.com/ionic-team/ionic/commit/1d983fa4b3ef0457dc192f376e380c77b611d058))
|
||||
|
||||
|
||||
|
||||
# [5.9.0](https://github.com/ionic-team/ionic/compare/v5.8.5...v5.9.0) (2021-11-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **action-sheet:** safe area is now accounted for in MD mode ([#24176](https://github.com/ionic-team/ionic/issues/24176)) ([642255e](https://github.com/ionic-team/ionic/commit/642255e514fd67238d9bd8ea90781111687c6d03)), closes [#24175](https://github.com/ionic-team/ionic/issues/24175)
|
||||
* **input:** date type in ion-input now aligns correctly on iOS 15 ([#24217](https://github.com/ionic-team/ionic/issues/24217)) ([0566ec0](https://github.com/ionic-team/ionic/commit/0566ec0da3b8a66a1a1ebb1b235e7297ec483c79))
|
||||
* **vue:** canGoBack method now works correctly ([#24188](https://github.com/ionic-team/ionic/issues/24188)) ([7c43589](https://github.com/ionic-team/ionic/commit/7c43589b0a486f71ee2ae5a4cdcd73071fcd31b9)), closes [#24109](https://github.com/ionic-team/ionic/issues/24109)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **slides:** add support for Swiper 7 ([#24190](https://github.com/ionic-team/ionic/issues/24190)) ([d0b6130](https://github.com/ionic-team/ionic/commit/d0b61307c6b7ff1589646c43f989260b59db1473))
|
||||
|
||||
|
||||
|
||||
## [5.8.5](https://github.com/ionic-team/ionic/compare/v5.8.4...v5.8.5) (2021-10-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **menu:** added focus trapping, improved compatibility with screen readers ([#24076](https://github.com/ionic-team/ionic/issues/24076)) ([bdb268a](https://github.com/ionic-team/ionic/commit/bdb268aa12c5bf411c96529672486d35e018cefa))
|
||||
* **vue:** back button now selects correct route when navigating from view multiple times ([#24060](https://github.com/ionic-team/ionic/issues/24060)) ([a09d7d4](https://github.com/ionic-team/ionic/commit/a09d7d4ab6dd0d90204015eaaf232ed190753c56)), closes [#23987](https://github.com/ionic-team/ionic/issues/23987)
|
||||
* **vue:** mount correct views when navigating ([#24056](https://github.com/ionic-team/ionic/issues/24056)) ([24659a5](https://github.com/ionic-team/ionic/commit/24659a527abe0c70df7e8ae6da3dcb4017bf500c)), closes [#23914](https://github.com/ionic-team/ionic/issues/23914)
|
||||
|
||||
|
||||
|
||||
## [5.8.4](https://github.com/ionic-team/ionic/compare/v5.8.3...v5.8.4) (2021-10-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** setup config properly ([#24054](https://github.com/ionic-team/ionic/issues/24054)) ([e001f24](https://github.com/ionic-team/ionic/commit/e001f24f2ca99abbc98b923dd1a132cc83b3b23f)), closes [#24051](https://github.com/ionic-team/ionic/issues/24051) [#24052](https://github.com/ionic-team/ionic/issues/24052)
|
||||
* **back-button:** pass aria-label to native element ([#24027](https://github.com/ionic-team/ionic/issues/24027)) ([68a7e43](https://github.com/ionic-team/ionic/commit/68a7e43345a0261fdeed6054198c5a22fbbcb584))
|
||||
|
||||
|
||||
|
||||
## [5.8.3](https://github.com/ionic-team/ionic/compare/v5.8.2...v5.8.3) (2021-10-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **react:** overlay hooks dismiss method now works ([#24038](https://github.com/ionic-team/ionic/issues/24038)) ([655631d](https://github.com/ionic-team/ionic/commit/655631ddf059ce58066d5384d0ae186d7abc09a9)), closes [#24030](https://github.com/ionic-team/ionic/issues/24030)
|
||||
|
||||
|
||||
|
||||
## [5.8.2](https://github.com/ionic-team/ionic/compare/v5.8.1...v5.8.2) (2021-10-06)
|
||||
|
||||
|
||||
|
||||
@@ -30,11 +30,11 @@ an [issue](https://github.com/ionic-team/ionic/issues/new) on this repository.
|
||||
### Contributing
|
||||
|
||||
Thanks for your interest in contributing! Read up on our guidelines for
|
||||
[contributing](https://github.com/ionic-team/ionic/blob/master/.github/CONTRIBUTING.md)
|
||||
[contributing](https://github.com/ionic-team/ionic/blob/main/.github/CONTRIBUTING.md)
|
||||
and then look through our issues with a [help wanted](https://github.com/ionic-team/ionic/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)
|
||||
label.
|
||||
|
||||
Please note that this project is released with a [Contributor Code of Conduct](https://github.com/ionic-team/ionic/blob/master/CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms.
|
||||
Please note that this project is released with a [Contributor Code of Conduct](https://github.com/ionic-team/ionic/blob/main/CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms.
|
||||
|
||||
|
||||
### Examples
|
||||
|
||||
@@ -137,7 +137,7 @@ The back button is no longer added by default to a navigation bar. It should be
|
||||
</ion-toolbar>
|
||||
```
|
||||
|
||||
See the [back button documentation](https://github.com/ionic-team/ionic/blob/master/core/src/components/back-button) for more usage examples.
|
||||
See the [back button documentation](https://github.com/ionic-team/ionic/blob/main/core/src/components/back-button) for more usage examples.
|
||||
|
||||
## Button
|
||||
|
||||
@@ -507,7 +507,7 @@ _In the following examples, `{breakpoint}` refers to the optional screen breakpo
|
||||
- `push-{breakpoint}-{value}` attributes have been renamed to `push-{breakpoint}=“{value}”`
|
||||
- `pull-{breakpoint}-{value}` attributes have been renamed to `pull-{breakpoint}=“{value}”`
|
||||
|
||||
Customizing the padding and width of a grid should now be done with CSS variables. For more information, see [Grid Layout](https://github.com/ionic-team/ionic-docs/blob/master/src/pages/layout/grid.md).
|
||||
Customizing the padding and width of a grid should now be done with CSS variables. For more information, see [Grid Layout](https://github.com/ionic-team/ionic-docs/blob/main/src/pages/layout/grid.md).
|
||||
|
||||
## Icon
|
||||
|
||||
@@ -1689,7 +1689,7 @@ The tab attribute defines the route to be shown upon clicking on this tab.
|
||||
</ion-tabs>
|
||||
```
|
||||
|
||||
See more usage examples in the [Tabs](https://github.com/ionic-team/ionic/blob/master/core/src/components/tabs) documentation.
|
||||
See more usage examples in the [Tabs](https://github.com/ionic-team/ionic/blob/main/core/src/components/tabs) documentation.
|
||||
|
||||
|
||||
## Text / Typography
|
||||
|
||||
@@ -16,11 +16,11 @@ Ionic Angular specific building blocks on top of [@ionic/core](https://www.npmjs
|
||||
|
||||
## License
|
||||
|
||||
* [MIT](https://raw.githubusercontent.com/ionic-team/ionic/master/LICENSE)
|
||||
* [MIT](https://raw.githubusercontent.com/ionic-team/ionic/main/LICENSE)
|
||||
|
||||
## Testing ng-add in ionic
|
||||
|
||||
1. Pull the latest from master
|
||||
1. Pull the latest from `main`
|
||||
2. Build ionic/angular: `npm run build`
|
||||
3. Run `npm link` from `ionic/angular/dist` directory
|
||||
4. Create a blank angular project
|
||||
|
||||
18
angular/package-lock.json
generated
18
angular/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "5.8.2",
|
||||
"version": "5.9.4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/angular",
|
||||
"version": "5.8.2",
|
||||
"version": "5.9.4",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/core": "5.8.1",
|
||||
"@ionic/core": "5.9.3",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -204,9 +204,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "5.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.8.1.tgz",
|
||||
"integrity": "sha512-twAPHhrGMYvHW0NgebMBfN70xDUkFxW+Zcxeus7jrhuJh1uWp/3MwawLi4InCwpyuFQiBo8yAaqC1hB1wTZmLA==",
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.9.3.tgz",
|
||||
"integrity": "sha512-WM50vVxAAw+MQYqWXKUK4usBgkr7iQ9UWSb6t59mG4ZSy/fPAb7ZIdAjxY0U5i1ykk6A7Ur4B9ZJMpC/a7nnug==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.4.0",
|
||||
"ionicons": "^5.5.3",
|
||||
@@ -5156,9 +5156,9 @@
|
||||
}
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "5.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.8.1.tgz",
|
||||
"integrity": "sha512-twAPHhrGMYvHW0NgebMBfN70xDUkFxW+Zcxeus7jrhuJh1uWp/3MwawLi4InCwpyuFQiBo8yAaqC1hB1wTZmLA==",
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.9.3.tgz",
|
||||
"integrity": "sha512-WM50vVxAAw+MQYqWXKUK4usBgkr7iQ9UWSb6t59mG4ZSy/fPAb7ZIdAjxY0U5i1ykk6A7Ur4B9ZJMpC/a7nnug==",
|
||||
"requires": {
|
||||
"@stencil/core": "^2.4.0",
|
||||
"ionicons": "^5.5.3",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "5.8.2",
|
||||
"version": "5.9.4",
|
||||
"description": "Angular specific wrappers for @ionic/core",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -42,7 +42,7 @@
|
||||
"validate": "npm i && npm run lint && npm run test && npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ionic/core": "5.8.2",
|
||||
"@ionic/core": "5.9.4",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { NgZone } from '@angular/core';
|
||||
import { initialize } from '@ionic/core';
|
||||
import { setupConfig } from '@ionic/core';
|
||||
import { applyPolyfills, defineCustomElements } from '@ionic/core/loader';
|
||||
|
||||
import { Config } from './providers/config';
|
||||
@@ -11,7 +11,7 @@ export const appInitialize = (config: Config, doc: Document, zone: NgZone) => {
|
||||
const win: IonicWindow | undefined = doc.defaultView as any;
|
||||
if (win && typeof (window as any) !== 'undefined') {
|
||||
|
||||
initialize({
|
||||
setupConfig({
|
||||
...config,
|
||||
_zoneGate: (h: any) => zone.run(h)
|
||||
});
|
||||
|
||||
@@ -86,11 +86,11 @@ export class ValueAccessor implements ControlValueAccessor, AfterViewInit, OnDes
|
||||
*/
|
||||
const formControl = ngControl.control;
|
||||
if (formControl) {
|
||||
const methodsToPatch = ['markAsTouched', 'markAllAsTouched', 'markAsUntouched', 'markAsDirty', 'markAsPristine'];
|
||||
const methodsToPatch = ['markAsTouched', 'markAllAsTouched', 'markAsUntouched', 'markAsDirty', 'markAsPristine'] as const;
|
||||
methodsToPatch.forEach(method => {
|
||||
if (formControl[method]) {
|
||||
const oldFn = formControl[method].bind(formControl);
|
||||
formControl[method] = (...params) => {
|
||||
formControl[method] = (...params: any[]) => {
|
||||
oldFn(...params);
|
||||
setIonicClasses(this.el);
|
||||
};
|
||||
|
||||
@@ -305,7 +305,7 @@ export class StackController {
|
||||
|
||||
const cleanupAsync = (activeRoute: RouteView, views: RouteView[], viewsSnapshot: RouteView[], location: Location) => {
|
||||
if (typeof (requestAnimationFrame as any) === 'function') {
|
||||
return new Promise<any>(resolve => {
|
||||
return new Promise<void>(resolve => {
|
||||
requestAnimationFrame(() => {
|
||||
cleanup(activeRoute, views, viewsSnapshot, location);
|
||||
resolve();
|
||||
|
||||
@@ -43,7 +43,7 @@ export * from './types/ionic-lifecycle-hooks';
|
||||
export { IonicModule } from './ionic-module';
|
||||
|
||||
// UTILS
|
||||
export { IonicSafeString, getPlatforms, isPlatform, createAnimation, IonicSwiper } from '@ionic/core';
|
||||
export { IonicSafeString, getPlatforms, isPlatform, createAnimation, IonicSwiper, IonicSlides } from '@ionic/core';
|
||||
|
||||
// CORE TYPES
|
||||
export {
|
||||
|
||||
@@ -35,7 +35,7 @@ Additionally, within this package is a `dist/ionic.js` file and accompanying `di
|
||||
|
||||
## Framework Bindings
|
||||
|
||||
The `@ionic/core` package can by used in simple HTML, or by vanilla JavaScript without any framework at all. Ionic also has packages that make it easier to integrate Ionic into a framework's traditional ecosystem and patterns. (However, at the lowest-level framework bindings are still just using Ionic Core and Web Components).
|
||||
The `@ionic/core` package can be used in simple HTML, or by vanilla JavaScript without any framework at all. Ionic also has packages that make it easier to integrate Ionic into a framework's traditional ecosystem and patterns. (However, at the lowest-level framework bindings are still just using Ionic Core and Web Components).
|
||||
|
||||
* [@ionic/angular](https://www.npmjs.com/package/@ionic/angular)
|
||||
|
||||
|
||||
4
core/package-lock.json
generated
4
core/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "5.8.2",
|
||||
"version": "5.9.4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/core",
|
||||
"version": "5.8.2",
|
||||
"version": "5.9.4",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.4.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "5.8.2",
|
||||
"version": "5.9.4",
|
||||
"description": "Base components for Ionic",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
|
||||
4
core/src/components.d.ts
vendored
4
core/src/components.d.ts
vendored
@@ -176,7 +176,7 @@ export namespace Components {
|
||||
*/
|
||||
"disabled": boolean;
|
||||
/**
|
||||
* The icon name to use for the back button.
|
||||
* The built-in named SVG icon name or the exact `src` of an SVG file to use for the back button.
|
||||
*/
|
||||
"icon"?: string | null;
|
||||
/**
|
||||
@@ -3511,7 +3511,7 @@ declare namespace LocalJSX {
|
||||
*/
|
||||
"disabled"?: boolean;
|
||||
/**
|
||||
* The icon name to use for the back button.
|
||||
* The built-in named SVG icon name or the exact `src` of an SVG file to use for the back button.
|
||||
*/
|
||||
"icon"?: string | null;
|
||||
/**
|
||||
|
||||
@@ -22,11 +22,6 @@
|
||||
text-align: $action-sheet-ios-text-align;
|
||||
}
|
||||
|
||||
.action-sheet-wrapper {
|
||||
@include margin(var(--ion-safe-area-top, 0), auto, var(--ion-safe-area-bottom, 0), auto);
|
||||
}
|
||||
|
||||
|
||||
// iOS Action Sheet Container
|
||||
// ---------------------------------------------------
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
|
||||
.action-sheet-wrapper {
|
||||
@include position(null, 0, 0, 0);
|
||||
@include margin(auto);
|
||||
@include margin(var(--ion-safe-area-top, 0), auto, var(--ion-safe-area-bottom, 0), auto);
|
||||
@include transform(translate3d(0, 100%, 0));
|
||||
|
||||
display: block;
|
||||
|
||||
@@ -2,8 +2,9 @@ import { Component, ComponentInterface, Element, Host, Prop, h } from '@stencil/
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { AnimationBuilder, Color } from '../../interface';
|
||||
import { ButtonInterface } from '../../utils/element-interface';
|
||||
import type { AnimationBuilder, Color } from '../../interface';
|
||||
import type { ButtonInterface } from '../../utils/element-interface';
|
||||
import { inheritAriaAttributes } from '../../utils/helpers';
|
||||
import { createColorClasses, hostContext, openURL } from '../../utils/theme';
|
||||
|
||||
/**
|
||||
@@ -22,6 +23,7 @@ import { createColorClasses, hostContext, openURL } from '../../utils/theme';
|
||||
shadow: true
|
||||
})
|
||||
export class BackButton implements ComponentInterface, ButtonInterface {
|
||||
private inheritedAttributes: { [k: string]: any } = {};
|
||||
|
||||
@Element() el!: HTMLElement;
|
||||
|
||||
@@ -43,7 +45,8 @@ export class BackButton implements ComponentInterface, ButtonInterface {
|
||||
@Prop({ reflect: true }) disabled = false;
|
||||
|
||||
/**
|
||||
* The icon name to use for the back button.
|
||||
* The built-in named SVG icon name or the exact `src` of an SVG file
|
||||
* to use for the back button.
|
||||
*/
|
||||
@Prop() icon?: string | null;
|
||||
|
||||
@@ -64,6 +67,8 @@ export class BackButton implements ComponentInterface, ButtonInterface {
|
||||
@Prop() routerAnimation: AnimationBuilder | undefined;
|
||||
|
||||
componentWillLoad() {
|
||||
this.inheritedAttributes = inheritAriaAttributes(this.el);
|
||||
|
||||
if (this.defaultHref === undefined) {
|
||||
this.defaultHref = config.get('backButtonDefaultHref');
|
||||
}
|
||||
@@ -115,9 +120,10 @@ export class BackButton implements ComponentInterface, ButtonInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { color, defaultHref, disabled, type, hasIconOnly, backButtonIcon, backButtonText } = this;
|
||||
const { color, defaultHref, disabled, type, hasIconOnly, backButtonIcon, backButtonText, inheritedAttributes } = this;
|
||||
const showBackButton = defaultHref !== undefined;
|
||||
const mode = getIonMode(this);
|
||||
const ariaLabel = inheritedAttributes['aria-label'] || backButtonText || 'back';
|
||||
|
||||
return (
|
||||
<Host
|
||||
@@ -139,7 +145,7 @@ export class BackButton implements ComponentInterface, ButtonInterface {
|
||||
disabled={disabled}
|
||||
class="button-native"
|
||||
part="native"
|
||||
aria-label={backButtonText || 'back'}
|
||||
aria-label={ariaLabel}
|
||||
>
|
||||
<span class="button-inner">
|
||||
{backButtonIcon && <ion-icon part="icon" icon={backButtonIcon} aria-hidden="true" lazy={false}></ion-icon>}
|
||||
|
||||
@@ -315,7 +315,7 @@ export default defineComponent({
|
||||
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` | `undefined` |
|
||||
| `defaultHref` | `default-href` | The url to navigate back to by default when there is no history. | `string \| undefined` | `undefined` |
|
||||
| `disabled` | `disabled` | If `true`, the user cannot interact with the button. | `boolean` | `false` |
|
||||
| `icon` | `icon` | The icon name to use for the back button. | `null \| string \| undefined` | `undefined` |
|
||||
| `icon` | `icon` | The built-in named SVG icon name or the exact `src` of an SVG file to use for the back button. | `null \| string \| undefined` | `undefined` |
|
||||
| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` |
|
||||
| `routerAnimation` | -- | When using a router, it specifies the transition animation when navigating to another page. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` |
|
||||
| `text` | `text` | The text to display in the back button. | `null \| string \| undefined` | `undefined` |
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
<ion-content>
|
||||
<h3>Default</h3>
|
||||
<p>
|
||||
<ion-back-button></ion-back-button>
|
||||
<ion-back-button text="Back"></ion-back-button>
|
||||
<ion-back-button aria-label="back button"></ion-back-button>
|
||||
<ion-back-button text="Back" aria-label="back button"></ion-back-button>
|
||||
<ion-back-button icon="add"></ion-back-button>
|
||||
<ion-back-button disabled text="Text Only" icon=""></ion-back-button>
|
||||
<ion-back-button icon="heart" text="Love" color="danger"></ion-back-button>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Prop, h } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { AnimationBuilder, Color, RouterDirection } from '../../interface';
|
||||
import { AnchorInterface, ButtonInterface } from '../../utils/element-interface';
|
||||
import { hasShadowDom, inheritAttributes } from '../../utils/helpers';
|
||||
import type { AnimationBuilder, Color, RouterDirection } from '../../interface';
|
||||
import type { AnchorInterface, ButtonInterface } from '../../utils/element-interface';
|
||||
import { hasShadowDom, inheritAriaAttributes } from '../../utils/helpers';
|
||||
import { createColorClasses, hostContext, openURL } from '../../utils/theme';
|
||||
|
||||
/**
|
||||
@@ -135,7 +135,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
|
||||
this.inToolbar = !!this.el.closest('ion-buttons');
|
||||
this.inListHeader = !!this.el.closest('ion-list-header');
|
||||
this.inItem = !!this.el.closest('ion-item') || !!this.el.closest('ion-item-divider');
|
||||
this.inheritedAttributes = inheritAttributes(this.el, ['aria-label']);
|
||||
this.inheritedAttributes = inheritAriaAttributes(this.el);
|
||||
}
|
||||
|
||||
private get hasIconOnly() {
|
||||
|
||||
@@ -140,10 +140,37 @@
|
||||
}
|
||||
|
||||
:host(.content-sizing) {
|
||||
display: flex;
|
||||
|
||||
flex-direction: column;
|
||||
|
||||
/**
|
||||
* This resolves a sizing issue in popovers where extra long content
|
||||
* would overflow the popover's height, preventing scrolling. It's a
|
||||
* quirk of flexbox that forces the content to shrink to fit.
|
||||
*
|
||||
* overflow: hidden can't be used here because it prevents the visual
|
||||
* effect from showing on translucent headers.
|
||||
*/
|
||||
min-height: 0;
|
||||
|
||||
contain: none;
|
||||
}
|
||||
:host(.content-sizing) .inner-scroll {
|
||||
position: relative;
|
||||
|
||||
/**
|
||||
* Because the outer content has display: flex here (to help enable
|
||||
* scrolling in a popover), offsetting via `top` (such as when using
|
||||
* a translucent header) creates white space under the content. Use
|
||||
* a negative margin instead to keep the bottom in place. (A similar
|
||||
* thing happens with `bottom` and footers.)
|
||||
*/
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
|
||||
margin-top: calc(var(--offset-top) * -1);
|
||||
margin-bottom: calc(var(--offset-bottom) * -1);
|
||||
}
|
||||
|
||||
.transition-effect {
|
||||
@@ -199,4 +226,15 @@
|
||||
|
||||
::slotted([slot="fixed"]) {
|
||||
position: absolute;
|
||||
|
||||
/**
|
||||
* When presenting ion-content inside of an ion-modal, the .inner-scroll
|
||||
* element is composited. In WebKit, the fixed content is not composited
|
||||
* causing it to appear under the main scrollable content as a result.
|
||||
* The fixed content is correctly composited in other browsers. Adding
|
||||
* the translateZ forces the fixed content to be composited so it correctly
|
||||
* shows on top of the scrollable content. Setting a negative z-index will
|
||||
* still allow the fixed content to appear under the scroll content if specified.
|
||||
*/
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
@@ -119,14 +119,6 @@ export class Content implements ComponentInterface {
|
||||
this.resize();
|
||||
}
|
||||
|
||||
@Listen('click', { capture: true })
|
||||
onClick(ev: Event) {
|
||||
if (this.isScrolling) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
private shouldForceOverscroll() {
|
||||
const { forceOverscroll } = this;
|
||||
const mode = getIonMode(this);
|
||||
@@ -374,10 +366,17 @@ const getPageElement = (el: HTMLElement) => {
|
||||
if (tabs) {
|
||||
return tabs;
|
||||
}
|
||||
const page = el.closest('ion-app,ion-page,.ion-page,page-inner');
|
||||
|
||||
/**
|
||||
* If we're in a popover, we need to use its wrapper so we can account for space
|
||||
* between the popover and the edges of the screen. But if the popover contains
|
||||
* its own page element, we should use that instead.
|
||||
*/
|
||||
const page = el.closest('ion-app, ion-page, .ion-page, page-inner, .popover-content');
|
||||
if (page) {
|
||||
return page;
|
||||
}
|
||||
|
||||
return getParentElement(el);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Component, ComponentInterface, Element, Host, Prop, h, writeTask } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { inheritAttributes } from '../../utils/helpers';
|
||||
import { inheritAriaAttributes } from '../../utils/helpers';
|
||||
import { hostContext } from '../../utils/theme';
|
||||
|
||||
import { cloneElement, createHeaderIndex, handleContentScroll, handleToolbarIntersection, setHeaderActive, setToolbarBackgroundOpacity } from './header.utils';
|
||||
|
||||
@@ -45,7 +46,7 @@ export class Header implements ComponentInterface {
|
||||
@Prop() translucent = false;
|
||||
|
||||
componentWillLoad() {
|
||||
this.inheritedAttributes = inheritAttributes(this.el, ['role']);
|
||||
this.inheritedAttributes = inheritAriaAttributes(this.el);
|
||||
}
|
||||
|
||||
async componentDidLoad() {
|
||||
@@ -154,9 +155,12 @@ export class Header implements ComponentInterface {
|
||||
const mode = getIonMode(this);
|
||||
const collapse = this.collapse || 'none';
|
||||
|
||||
// banner role must be at top level, so remove role if inside a menu
|
||||
const roleType = hostContext('ion-menu', this.el) ? 'none' : 'banner';
|
||||
|
||||
return (
|
||||
<Host
|
||||
role="banner"
|
||||
role={roleType}
|
||||
class={{
|
||||
[mode]: true,
|
||||
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
|
||||
The `ion-infinite-scroll-content` component is the default child used by the `ion-infinite-scroll`. It displays an infinite scroll spinner that looks best based on the platform and changes the look depending on the infinite scroll's state. The default spinner can be changed and text can be added by setting the `loadingSpinner` and `loadingText` properties.
|
||||
|
||||
## React
|
||||
|
||||
The `ion-infinite-scroll-content` component is not supported in React.
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
@@ -39,6 +35,25 @@ The `ion-infinite-scroll-content` component is not supported in React.
|
||||
```
|
||||
|
||||
|
||||
### React
|
||||
|
||||
```tsx
|
||||
import React from 'react';
|
||||
import { IonContent, IonInfiniteScroll, IonInfiniteScrollContent } from '@ionic/react';
|
||||
|
||||
export const InfiniteScrollExample: React.FC = () => (
|
||||
<IonContent>
|
||||
<IonInfiniteScroll>
|
||||
<IonInfiniteScrollContent
|
||||
loadingSpinner="bubbles"
|
||||
loadingText="Loading more data...">
|
||||
</IonInfiniteScrollContent>
|
||||
</IonInfiniteScroll>
|
||||
</IonContent>
|
||||
);
|
||||
```
|
||||
|
||||
|
||||
### Stencil
|
||||
|
||||
```tsx
|
||||
|
||||
15
core/src/components/infinite-scroll-content/usage/react.md
Normal file
15
core/src/components/infinite-scroll-content/usage/react.md
Normal file
@@ -0,0 +1,15 @@
|
||||
```tsx
|
||||
import React from 'react';
|
||||
import { IonContent, IonInfiniteScroll, IonInfiniteScrollContent } from '@ionic/react';
|
||||
|
||||
export const InfiniteScrollExample: React.FC = () => (
|
||||
<IonContent>
|
||||
<IonInfiniteScroll>
|
||||
<IonInfiniteScrollContent
|
||||
loadingSpinner="bubbles"
|
||||
loadingText="Loading more data...">
|
||||
</IonInfiniteScrollContent>
|
||||
</IonInfiniteScroll>
|
||||
</IonContent>
|
||||
);
|
||||
```
|
||||
@@ -111,6 +111,104 @@ function toggleInfiniteScroll() {
|
||||
```
|
||||
|
||||
|
||||
### React
|
||||
|
||||
```tsx
|
||||
import {
|
||||
IonButton,
|
||||
IonContent,
|
||||
IonHeader,
|
||||
IonInfiniteScroll,
|
||||
IonInfiniteScrollContent,
|
||||
IonItem,
|
||||
IonLabel,
|
||||
IonList,
|
||||
IonPage,
|
||||
IonTitle,
|
||||
IonToolbar,
|
||||
useIonViewWillEnter
|
||||
} from '@ionic/react';
|
||||
import { useState } from 'react';
|
||||
|
||||
const InfiniteScrollExample: React.FC = () => {
|
||||
const [data, setData] = useState<string[]>([]);
|
||||
const [isInfiniteDisabled, setInfiniteDisabled] = useState(false);
|
||||
|
||||
const pushData = () => {
|
||||
const max = data.length + 20;
|
||||
const min = max - 20;
|
||||
const newData = [];
|
||||
for (let i = min; i < max; i++) {
|
||||
newData.push('Item' + i);
|
||||
}
|
||||
|
||||
setData([
|
||||
...data,
|
||||
...newData
|
||||
]);
|
||||
}
|
||||
const loadData = (ev: any) => {
|
||||
setTimeout(() => {
|
||||
pushData();
|
||||
console.log('Loaded data');
|
||||
ev.target.complete();
|
||||
if (data.length == 1000) {
|
||||
setInfiniteDisabled(true);
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
useIonViewWillEnter(() => {
|
||||
pushData();
|
||||
});
|
||||
|
||||
return (
|
||||
<IonPage>
|
||||
<IonHeader>
|
||||
<IonToolbar>
|
||||
<IonTitle>Blank</IonTitle>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
<IonContent fullscreen>
|
||||
<IonHeader collapse="condense">
|
||||
<IonToolbar>
|
||||
<IonTitle size="large">Blank</IonTitle>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
|
||||
<IonButton onClick={() => setInfiniteDisabled(!isInfiniteDisabled)} expand="block">
|
||||
Toggle Infinite Scroll
|
||||
</IonButton>
|
||||
|
||||
<IonList>
|
||||
{data.map((item, index) => {
|
||||
return (
|
||||
<IonItem key={index}>
|
||||
<IonLabel>{item}</IonLabel>
|
||||
</IonItem>
|
||||
)
|
||||
})}
|
||||
</IonList>
|
||||
|
||||
<IonInfiniteScroll
|
||||
onIonInfinite={loadData}
|
||||
threshold="100px"
|
||||
disabled={isInfiniteDisabled}
|
||||
>
|
||||
<IonInfiniteScrollContent
|
||||
loadingSpinner="bubbles"
|
||||
loadingText="Loading more data..."
|
||||
></IonInfiniteScrollContent>
|
||||
</IonInfiniteScroll>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default InfiniteScrollExample;
|
||||
```
|
||||
|
||||
|
||||
### Stencil
|
||||
|
||||
```tsx
|
||||
|
||||
94
core/src/components/infinite-scroll/usage/react.md
Normal file
94
core/src/components/infinite-scroll/usage/react.md
Normal file
@@ -0,0 +1,94 @@
|
||||
```tsx
|
||||
import {
|
||||
IonButton,
|
||||
IonContent,
|
||||
IonHeader,
|
||||
IonInfiniteScroll,
|
||||
IonInfiniteScrollContent,
|
||||
IonItem,
|
||||
IonLabel,
|
||||
IonList,
|
||||
IonPage,
|
||||
IonTitle,
|
||||
IonToolbar,
|
||||
useIonViewWillEnter
|
||||
} from '@ionic/react';
|
||||
import { useState } from 'react';
|
||||
|
||||
const InfiniteScrollExample: React.FC = () => {
|
||||
const [data, setData] = useState<string[]>([]);
|
||||
const [isInfiniteDisabled, setInfiniteDisabled] = useState(false);
|
||||
|
||||
const pushData = () => {
|
||||
const max = data.length + 20;
|
||||
const min = max - 20;
|
||||
const newData = [];
|
||||
for (let i = min; i < max; i++) {
|
||||
newData.push('Item' + i);
|
||||
}
|
||||
|
||||
setData([
|
||||
...data,
|
||||
...newData
|
||||
]);
|
||||
}
|
||||
const loadData = (ev: any) => {
|
||||
setTimeout(() => {
|
||||
pushData();
|
||||
console.log('Loaded data');
|
||||
ev.target.complete();
|
||||
if (data.length == 1000) {
|
||||
setInfiniteDisabled(true);
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
useIonViewWillEnter(() => {
|
||||
pushData();
|
||||
});
|
||||
|
||||
return (
|
||||
<IonPage>
|
||||
<IonHeader>
|
||||
<IonToolbar>
|
||||
<IonTitle>Blank</IonTitle>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
<IonContent fullscreen>
|
||||
<IonHeader collapse="condense">
|
||||
<IonToolbar>
|
||||
<IonTitle size="large">Blank</IonTitle>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
|
||||
<IonButton onClick={() => setInfiniteDisabled(!isInfiniteDisabled)} expand="block">
|
||||
Toggle Infinite Scroll
|
||||
</IonButton>
|
||||
|
||||
<IonList>
|
||||
{data.map((item, index) => {
|
||||
return (
|
||||
<IonItem key={index}>
|
||||
<IonLabel>{item}</IonLabel>
|
||||
</IonItem>
|
||||
)
|
||||
})}
|
||||
</IonList>
|
||||
|
||||
<IonInfiniteScroll
|
||||
onIonInfinite={loadData}
|
||||
threshold="100px"
|
||||
disabled={isInfiniteDisabled}
|
||||
>
|
||||
<IonInfiniteScrollContent
|
||||
loadingSpinner="bubbles"
|
||||
loadingText="Loading more data..."
|
||||
></IonInfiniteScrollContent>
|
||||
</IonInfiniteScroll>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default InfiniteScrollExample;
|
||||
```
|
||||
@@ -1,8 +1,14 @@
|
||||
import { Build, Component, ComponentInterface, Element, Event, EventEmitter, Host, Method, Prop, State, Watch, h } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { AutocompleteTypes, Color, InputChangeEventDetail, StyleEventDetail, TextFieldTypes } from '../../interface';
|
||||
import { debounceEvent, findItemLabel, inheritAttributes } from '../../utils/helpers';
|
||||
import type {
|
||||
AutocompleteTypes,
|
||||
Color,
|
||||
InputChangeEventDetail,
|
||||
StyleEventDetail,
|
||||
TextFieldTypes,
|
||||
} from '../../interface';
|
||||
import { debounceEvent, findItemLabel, inheritAriaAttributes, inheritAttributes } from '../../utils/helpers';
|
||||
import { createColorClasses } from '../../utils/theme';
|
||||
|
||||
/**
|
||||
@@ -234,7 +240,10 @@ export class Input implements ComponentInterface {
|
||||
}
|
||||
|
||||
componentWillLoad() {
|
||||
this.inheritedAttributes = inheritAttributes(this.el, ['aria-label', 'tabindex', 'title']);
|
||||
this.inheritedAttributes = {
|
||||
...inheritAriaAttributes(this.el),
|
||||
...inheritAttributes(this.el, ['tabindex', 'title']),
|
||||
};
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
|
||||
@@ -35,6 +35,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
@Element() el!: HTMLIonItemElement;
|
||||
|
||||
@State() multipleInputs = false;
|
||||
@State() focusable = true;
|
||||
|
||||
/**
|
||||
* The color to use from your application's color palette.
|
||||
@@ -173,7 +174,10 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
raf(() => this.setMultipleInputs());
|
||||
raf(() => {
|
||||
this.setMultipleInputs();
|
||||
this.focusable = this.isFocusable();
|
||||
});
|
||||
}
|
||||
|
||||
// If the item contains multiple clickable elements and/or inputs, then the item
|
||||
@@ -217,6 +221,11 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
return (this.isClickable() || this.hasCover());
|
||||
}
|
||||
|
||||
private isFocusable(): boolean {
|
||||
const focusableChild = this.el.querySelector('.ion-focusable');
|
||||
return (this.canActivate() || focusableChild !== null);
|
||||
}
|
||||
|
||||
private getFirstInput(): HTMLIonInputElement | HTMLIonTextareaElement {
|
||||
const inputs = this.el.querySelectorAll('ion-input, ion-textarea') as NodeListOf<HTMLIonInputElement | HTMLIonTextareaElement>;
|
||||
return inputs[0];
|
||||
@@ -289,7 +298,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
'in-list': hostContext('ion-list', this.el),
|
||||
'item-multiple-inputs': this.multipleInputs,
|
||||
'ion-activatable': canActivate,
|
||||
'ion-focusable': true,
|
||||
'ion-focusable': this.focusable
|
||||
})
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -2,9 +2,9 @@ import { Component, ComponentInterface, Element, Host, Listen, Prop, State, h }
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { Color } from '../../interface';
|
||||
import { ButtonInterface } from '../../utils/element-interface';
|
||||
import { inheritAttributes } from '../../utils/helpers';
|
||||
import type { Color } from '../../interface';
|
||||
import type { ButtonInterface } from '../../utils/element-interface';
|
||||
import { inheritAriaAttributes } from '../../utils/helpers';
|
||||
import { menuController } from '../../utils/menu-controller';
|
||||
import { createColorClasses, hostContext } from '../../utils/theme';
|
||||
import { updateVisibility } from '../menu-toggle/menu-toggle-util';
|
||||
@@ -58,7 +58,7 @@ export class MenuButton implements ComponentInterface, ButtonInterface {
|
||||
@Prop() type: 'submit' | 'reset' | 'button' = 'button';
|
||||
|
||||
componentWillLoad() {
|
||||
this.inheritedAttributes = inheritAttributes(this.el, ['aria-label']);
|
||||
this.inheritedAttributes = inheritAriaAttributes(this.el);
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
|
||||
@@ -5,13 +5,14 @@ import { getIonMode } from '../../global/ionic-global';
|
||||
import { Animation, Gesture, GestureDetail, MenuChangeEventDetail, MenuI, Side } from '../../interface';
|
||||
import { getTimeGivenProgression } from '../../utils/animation/cubic-bezier';
|
||||
import { GESTURE_CONTROLLER } from '../../utils/gesture';
|
||||
import { assert, clamp, isEndSide as isEnd } from '../../utils/helpers';
|
||||
import { assert, clamp, inheritAriaAttributes, isEndSide as isEnd } from '../../utils/helpers';
|
||||
import { menuController } from '../../utils/menu-controller';
|
||||
|
||||
const iosEasing = 'cubic-bezier(0.32,0.72,0,1)';
|
||||
const mdEasing = 'cubic-bezier(0.0,0.0,0.2,1)';
|
||||
const iosEasingReverse = 'cubic-bezier(1, 0, 0.68, 0.28)';
|
||||
const mdEasingReverse = 'cubic-bezier(0.4, 0, 0.6, 1)';
|
||||
const focusableQueryString = '[tabindex]:not([tabindex^="-"]), input:not([type=hidden]):not([tabindex^="-"]), textarea:not([tabindex^="-"]), button:not([tabindex^="-"]), select:not([tabindex^="-"]), .ion-focusable:not([tabindex^="-"])';
|
||||
|
||||
/**
|
||||
* @part container - The container for the menu content.
|
||||
@@ -39,6 +40,11 @@ export class Menu implements ComponentInterface, MenuI {
|
||||
backdropEl?: HTMLElement;
|
||||
menuInnerEl?: HTMLElement;
|
||||
contentEl?: HTMLElement;
|
||||
lastFocus?: HTMLElement;
|
||||
|
||||
private inheritedAttributes: { [k: string]: any } = {};
|
||||
|
||||
private handleFocus = (ev: Event) => this.trapKeyboardFocus(ev, document);
|
||||
|
||||
@Element() el!: HTMLIonMenuElement;
|
||||
|
||||
@@ -159,6 +165,7 @@ export class Menu implements ComponentInterface, MenuI {
|
||||
|
||||
const el = this.el;
|
||||
const parent = el.parentNode as any;
|
||||
|
||||
if (this.contentId === undefined) {
|
||||
console.warn(`[DEPRECATED][ion-menu] Using the [main] attribute is deprecated, please use the "contentId" property instead:
|
||||
BEFORE:
|
||||
@@ -205,6 +212,10 @@ AFTER:
|
||||
this.updateState();
|
||||
}
|
||||
|
||||
componentWillLoad() {
|
||||
this.inheritedAttributes = inheritAriaAttributes(this.el);
|
||||
}
|
||||
|
||||
async componentDidLoad() {
|
||||
this.ionMenuChange.emit({ disabled: this.disabled, open: this._isOpen });
|
||||
this.updateState();
|
||||
@@ -246,6 +257,13 @@ AFTER:
|
||||
}
|
||||
}
|
||||
|
||||
@Listen('keydown')
|
||||
onKeydown(ev: KeyboardEvent) {
|
||||
if (ev.key === 'Escape') {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` is the menu is open.
|
||||
*/
|
||||
@@ -301,6 +319,65 @@ AFTER:
|
||||
return menuController._setOpen(this, shouldOpen, animated);
|
||||
}
|
||||
|
||||
private focusFirstDescendant() {
|
||||
const { el } = this;
|
||||
const firstInput = el.querySelector(focusableQueryString) as HTMLElement | null;
|
||||
|
||||
if (firstInput) {
|
||||
firstInput.focus();
|
||||
} else {
|
||||
el.focus();
|
||||
}
|
||||
}
|
||||
|
||||
private focusLastDescendant() {
|
||||
const { el } = this;
|
||||
const inputs = Array.from(el.querySelectorAll<HTMLElement>(focusableQueryString));
|
||||
const lastInput = inputs.length > 0 ? inputs[inputs.length - 1] : null;
|
||||
|
||||
if (lastInput) {
|
||||
lastInput.focus();
|
||||
} else {
|
||||
el.focus();
|
||||
}
|
||||
}
|
||||
|
||||
private trapKeyboardFocus(ev: Event, doc: Document) {
|
||||
const target = ev.target as HTMLElement | null;
|
||||
if (!target) { return; }
|
||||
|
||||
/**
|
||||
* If the target is inside the menu contents, let the browser
|
||||
* focus as normal and keep a log of the last focused element.
|
||||
*/
|
||||
if (this.el.contains(target)) {
|
||||
this.lastFocus = target;
|
||||
} else {
|
||||
/**
|
||||
* Otherwise, we are about to have focus go out of the menu.
|
||||
* Wrap the focus to either the first or last element.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Once we call `focusFirstDescendant`, another focus event
|
||||
* will fire, which will cause `lastFocus` to be updated
|
||||
* before we can run the code after that. We cache the value
|
||||
* here to avoid that.
|
||||
*/
|
||||
this.focusFirstDescendant();
|
||||
|
||||
/**
|
||||
* If the cached last focused element is the same as the now-
|
||||
* active element, that means the user was on the first element
|
||||
* already and pressed Shift + Tab, so we need to wrap to the
|
||||
* last descendant.
|
||||
*/
|
||||
if (this.lastFocus === doc.activeElement) {
|
||||
this.focusLastDescendant();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async _setOpen(shouldOpen: boolean, animated = true): Promise<boolean> {
|
||||
// If the menu is disabled or it is currently being animated, let's do nothing
|
||||
if (!this._isActive() || this.isAnimating || shouldOpen === this._isOpen) {
|
||||
@@ -479,6 +556,16 @@ AFTER:
|
||||
// this places the menu into the correct location before it animates in
|
||||
// this css class doesn't actually kick off any animations
|
||||
this.el.classList.add(SHOW_MENU);
|
||||
|
||||
/**
|
||||
* We add a tabindex here so that focus trapping
|
||||
* still works even if the menu does not have
|
||||
* any focusable elements slotted inside. The
|
||||
* focus trapping utility will fallback to focusing
|
||||
* the menu so focus does not leave when the menu
|
||||
* is open.
|
||||
*/
|
||||
this.el.setAttribute('tabindex', '0');
|
||||
if (this.backdropEl) {
|
||||
this.backdropEl.classList.add(SHOW_BACKDROP);
|
||||
}
|
||||
@@ -505,19 +592,51 @@ AFTER:
|
||||
}
|
||||
|
||||
if (isOpen) {
|
||||
// add css class
|
||||
// add css class and hide content behind menu from screen readers
|
||||
if (this.contentEl) {
|
||||
this.contentEl.classList.add(MENU_CONTENT_OPEN);
|
||||
|
||||
/**
|
||||
* When the menu is open and overlaying the main
|
||||
* content, the main content should not be announced
|
||||
* by the screenreader as the menu is the main
|
||||
* focus. This is useful with screenreaders that have
|
||||
* "read from top" gestures that read the entire
|
||||
* page from top to bottom when activated.
|
||||
*/
|
||||
this.contentEl.setAttribute('aria-hidden', 'true');
|
||||
}
|
||||
|
||||
// emit open event
|
||||
this.ionDidOpen.emit();
|
||||
|
||||
// focus menu content for screen readers
|
||||
if (this.menuInnerEl) {
|
||||
this.focusFirstDescendant();
|
||||
}
|
||||
|
||||
// setup focus trapping
|
||||
document.addEventListener('focus', this.handleFocus, true);
|
||||
} else {
|
||||
// remove css classes
|
||||
// remove css classes and unhide content from screen readers
|
||||
this.el.classList.remove(SHOW_MENU);
|
||||
|
||||
/**
|
||||
* Remove tabindex from the menu component
|
||||
* so that is cannot be tabbed to.
|
||||
*/
|
||||
this.el.removeAttribute('tabindex');
|
||||
if (this.contentEl) {
|
||||
this.contentEl.classList.remove(MENU_CONTENT_OPEN);
|
||||
|
||||
/**
|
||||
* Remove aria-hidden so screen readers
|
||||
* can announce the main content again
|
||||
* now that the menu is not the main focus.
|
||||
*/
|
||||
this.contentEl.removeAttribute('aria-hidden');
|
||||
}
|
||||
|
||||
if (this.backdropEl) {
|
||||
this.backdropEl.classList.remove(SHOW_BACKDROP);
|
||||
}
|
||||
@@ -528,6 +647,9 @@ AFTER:
|
||||
|
||||
// emit close event
|
||||
this.ionDidClose.emit();
|
||||
|
||||
// undo focus trapping so multiple menus don't collide
|
||||
document.removeEventListener('focus', this.handleFocus, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -561,12 +683,13 @@ AFTER:
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isEndSide, type, disabled, isPaneVisible } = this;
|
||||
const { isEndSide, type, disabled, isPaneVisible, inheritedAttributes } = this;
|
||||
const mode = getIonMode(this);
|
||||
|
||||
return (
|
||||
<Host
|
||||
role="navigation"
|
||||
aria-label={inheritedAttributes['aria-label'] || 'menu'}
|
||||
class={{
|
||||
[mode]: true,
|
||||
[`menu-type-${type}`]: true,
|
||||
|
||||
15
core/src/components/menu/test/a11y/e2e.ts
Normal file
15
core/src/components/menu/test/a11y/e2e.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
import { AxePuppeteer } from '@axe-core/puppeteer';
|
||||
|
||||
test('menu: axe', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/menu/test/a11y?ionic:_testing=true'
|
||||
});
|
||||
|
||||
const menu = await page.find('ion-menu');
|
||||
await menu.callMethod('open');
|
||||
await menu.waitForVisible();
|
||||
|
||||
const results = await new AxePuppeteer(page).analyze();
|
||||
expect(results.violations.length).toEqual(0);
|
||||
});
|
||||
41
core/src/components/menu/test/a11y/index.html
Normal file
41
core/src/components/menu/test/a11y/index.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Segment - a11y</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
|
||||
<link href="../../../../../css/core.css" rel="stylesheet">
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main>
|
||||
<h1>Menu</h1>
|
||||
<ion-menu menu-id="menu" content-id="main-content">
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Menu</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-button>Button</ion-button>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-button>Button 2</ion-button>
|
||||
</ion-item>
|
||||
<ion-item>Menu Item</ion-item>
|
||||
<ion-item>Menu Item</ion-item>
|
||||
<ion-item>Menu Item</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
</ion-menu>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,6 +1,11 @@
|
||||
import { testMenu } from '../test.utils';
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
const DIRECTORY = 'basic';
|
||||
const getActiveElementID = async (page) => {
|
||||
const activeElement = await page.evaluateHandle(() => document.activeElement);
|
||||
return await page.evaluate(el => el && el.id, activeElement);
|
||||
}
|
||||
|
||||
test('menu: start menu', async () => {
|
||||
await testMenu(DIRECTORY, '#start-menu', 'first');
|
||||
@@ -14,6 +19,21 @@ test('menu: end menu', async () => {
|
||||
await testMenu(DIRECTORY, '#end-menu');
|
||||
});
|
||||
|
||||
test('menu: focus trap', async () => {
|
||||
const page = await newE2EPage({ url: '/src/components/menu/test/basic?ionic:_testing=true' });
|
||||
|
||||
await page.click('#open-first');
|
||||
const menu = await page.find('#start-menu');
|
||||
await menu.waitForVisible();
|
||||
|
||||
let activeElID = await getActiveElementID(page);
|
||||
expect(activeElID).toEqual('start-menu-button');
|
||||
|
||||
await page.keyboard.press('Tab');
|
||||
activeElID = await getActiveElementID(page);
|
||||
expect(activeElID).toEqual('start-menu-button');
|
||||
});
|
||||
|
||||
/**
|
||||
* RTL Tests
|
||||
*/
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-menu side="start" menu-id="first" id="start-menu" content-id="main" class="menu-part">
|
||||
<ion-menu side="start" menu-id="first" id="start-menu" content-id="main" class="menu-part" aria-label="start menu">
|
||||
<ion-header>
|
||||
<ion-toolbar color="primary">
|
||||
<ion-title>Start Menu</ion-title>
|
||||
@@ -32,6 +32,9 @@
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-button id="start-menu-button">Button</ion-button>
|
||||
</ion-item>
|
||||
<ion-item>Menu Item</ion-item>
|
||||
<ion-item>Menu Item</ion-item>
|
||||
<ion-item>Menu Item</ion-item>
|
||||
@@ -82,7 +85,7 @@
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="ion-padding">
|
||||
<ion-button expand="block" onclick="openFirst()">Open Start Menu</ion-button>
|
||||
<ion-button expand="block" id="open-first" onclick="openFirst()">Open Start Menu</ion-button>
|
||||
<ion-button expand="block" onclick="openEnd()">Open End Menu</ion-button>
|
||||
<ion-button expand="block" onclick="openCustom()">Open Custom Menu</ion-button>
|
||||
</ion-content>
|
||||
|
||||
@@ -75,5 +75,9 @@
|
||||
--ion-safe-area-right: 0px;
|
||||
--ion-safe-area-bottom: 0px;
|
||||
--ion-safe-area-left: 0px;
|
||||
}
|
||||
display: flex;
|
||||
|
||||
flex-direction: column;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ A Popover is a dialog that appears on top of the current page. It can be used fo
|
||||
|
||||
## Presenting
|
||||
|
||||
To present a popover, call the `present` method on a popover instance. In order to position the popover relative to the element clicked, a click event needs to be passed into the options of the the `present` method. If the event is not passed, the popover will be positioned in the center of the viewport.
|
||||
To present a popover, call the `present` method on a popover instance. In order to position the popover relative to the element clicked, a click event needs to be passed into the options of the `present` method. If the event is not passed, the popover will be positioned in the center of the viewport.
|
||||
|
||||
## Customization
|
||||
|
||||
|
||||
@@ -57,6 +57,14 @@ test('popover: custom class', async () => {
|
||||
await testPopover(DIRECTORY, '#custom-class-popover');
|
||||
});
|
||||
|
||||
test('popover: header', async () => {
|
||||
await testPopover(DIRECTORY, '#header-popover');
|
||||
});
|
||||
|
||||
test('popover: translucent header', async () => {
|
||||
await testPopover(DIRECTORY, '#translucent-header-popover');
|
||||
});
|
||||
|
||||
/**
|
||||
* RTL Tests
|
||||
*/
|
||||
@@ -81,6 +89,14 @@ test('popover:rtl: custom class', async () => {
|
||||
await testPopover(DIRECTORY, '#custom-class-popover', true);
|
||||
});
|
||||
|
||||
test('popover:rtl: header', async () => {
|
||||
await testPopover(DIRECTORY, '#header-popover', true);
|
||||
});
|
||||
|
||||
test('popover:rtl: translucent header', async () => {
|
||||
await testPopover(DIRECTORY, '#translucent-header-popover', true);
|
||||
});
|
||||
|
||||
test('popover: htmlAttributes', async () => {
|
||||
const page = await newE2EPage({ url: '/src/components/popover/test/basic?ionic:_testing=true' });
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
<ion-button id="long-list-popover" expand="block" color="secondary" onclick="presentPopover({ component: 'list-page', event: event })">Show Long List Popover</ion-button>
|
||||
<ion-button id="no-event-popover" expand="block" color="danger" onclick="presentPopover({ component: 'profile-page' })">No Event Popover</ion-button>
|
||||
<ion-button id="custom-class-popover" expand="block" color="tertiary" onclick="presentPopover({ component: 'translucent-page', event: event, cssClass: 'my-custom-class' })">Custom Class Popover</ion-button>
|
||||
<ion-button id="header-popover" expand="block" onclick="presentPopover({ component: 'header-page' })">Popover With Header</ion-button>
|
||||
<ion-button id="translucent-header-popover" expand="block" onclick="presentPopover({ component: 'translucent-header-page' })">Popover With Translucent Header</ion-button>
|
||||
</ion-content>
|
||||
|
||||
<ion-footer>
|
||||
@@ -126,6 +128,56 @@
|
||||
}
|
||||
|
||||
customElements.define('translucent-page', TranslucentPage);
|
||||
|
||||
class HeaderPage extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.innerHTML = `
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Header</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding" color="primary">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.In rutrum tortor lacus, ac interdum ipsum bibendum vel.Aenean non nibh gravida, ullamcorper mi at, tempor nulla.Proin malesuada tellus ut ullamcorper accumsan.Donec semper justo vulputate neque tempus ultricies.Proin non aliquet ipsum.Praesent mauris sem, facilisis eu justo nec, euismod imperdiet tellus.Duis eget justo congue, lacinia orci sed, fermentum urna.Quisque sed massa faucibus, interdum dolor rhoncus, molestie erat.Proin suscipit ante non mauris volutpat egestas.Donec a ultrices ligula.Mauris in felis vel dui consectetur viverra.Nam vitae quam in arcu aliquam aliquam.Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.Cras non velit nisl.Donec viverra, magna quis vestibulum volutpat, metus ante tincidunt augue, non porta nisi mi sit amet neque.Proin dapibus eros vitae nibh tincidunt, blandit rhoncus est porttitor.
|
||||
</ion-content>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('header-page', HeaderPage);
|
||||
|
||||
class TranslucentHeaderPage extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.innerHTML = `
|
||||
<ion-header translucent>
|
||||
<ion-toolbar>
|
||||
<ion-title>Header</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding" fullscreen color="primary">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.In rutrum tortor lacus, ac interdum ipsum bibendum vel.Aenean non nibh gravida, ullamcorper mi at, tempor nulla.Proin malesuada tellus ut ullamcorper accumsan.Donec semper justo vulputate neque tempus ultricies.Proin non aliquet ipsum.Praesent mauris sem, facilisis eu justo nec, euismod imperdiet tellus.Duis eget justo congue, lacinia orci sed, fermentum urna.Quisque sed massa faucibus, interdum dolor rhoncus, molestie erat.Proin suscipit ante non mauris volutpat egestas.Donec a ultrices ligula.Mauris in felis vel dui consectetur viverra.Nam vitae quam in arcu aliquam aliquam.Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.Cras non velit nisl.Donec viverra, magna quis vestibulum volutpat, metus ante tincidunt augue, non porta nisi mi sit amet neque.Proin dapibus eros vitae nibh tincidunt, blandit rhoncus est porttitor.
|
||||
</ion-content>
|
||||
|
||||
<ion-footer translucent>
|
||||
<ion-toolbar>
|
||||
<ion-title>Footer</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-footer>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('translucent-header-page', TranslucentHeaderPage);
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Prop, State, Watch, h } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { Color, Gesture, GestureDetail, KnobName, RangeChangeEventDetail, RangeValue, StyleEventDetail } from '../../interface';
|
||||
import { clamp, debounceEvent, getAriaLabel, inheritAttributes, renderHiddenInput } from '../../utils/helpers';
|
||||
import type {
|
||||
Color,
|
||||
Gesture,
|
||||
GestureDetail,
|
||||
KnobName,
|
||||
RangeChangeEventDetail,
|
||||
RangeValue,
|
||||
StyleEventDetail,
|
||||
} from '../../interface';
|
||||
import { clamp, debounceEvent, getAriaLabel, inheritAriaAttributes, renderHiddenInput } from '../../utils/helpers';
|
||||
import { createColorClasses, hostContext } from '../../utils/theme';
|
||||
|
||||
/**
|
||||
@@ -205,7 +213,7 @@ export class Range implements ComponentInterface {
|
||||
*/
|
||||
this.rangeId = (this.el.hasAttribute('id')) ? this.el.getAttribute('id')! : `ion-r-${rangeIds++}`;
|
||||
|
||||
this.inheritedAttributes = inheritAttributes(this.el, ['aria-label']);
|
||||
this.inheritedAttributes = inheritAriaAttributes(this.el);
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
|
||||
@@ -30,15 +30,24 @@ const CHAIN_3: RouteChain = [
|
||||
describe('matchesIDs', () => {
|
||||
it('should match simple set of ids', () => {
|
||||
const chain: RouteChain = CHAIN_1;
|
||||
expect(matchesIDs(['2'], chain)).toBe(1);
|
||||
expect(matchesIDs(['2', '1'], chain)).toBe(2);
|
||||
expect(matchesIDs(['2', '1', '3'], chain)).toBe(3);
|
||||
expect(matchesIDs(['2', '1', '3', '4'], chain)).toBe(4);
|
||||
expect(matchesIDs(['2', '1', '3', '4', '5'], chain)).toBe(4);
|
||||
expect(matchesIDs([{ id: '2' }], chain)).toBe(1);
|
||||
expect(matchesIDs([{ id: '2' }, { id: '1' }], chain)).toBe(2);
|
||||
expect(matchesIDs([{ id: '2' }, { id: '1' }, { id: '3' }], chain)).toBe(3);
|
||||
expect(matchesIDs([{ id: '2' }, { id: '1' }, { id: '3' }, { id: '4' }], chain)).toBe(4);
|
||||
expect(matchesIDs([{ id: '2' }, { id: '1' }, { id: '3' }, { id: '4' }, { id: '5' }], chain)).toBe(4);
|
||||
|
||||
expect(matchesIDs([], chain)).toBe(0);
|
||||
expect(matchesIDs(['1'], chain)).toBe(0);
|
||||
expect(matchesIDs([{ id: '1' }], chain)).toBe(0);
|
||||
});
|
||||
|
||||
it('should match path with params', () => {
|
||||
const ids = [{ id: 'my-page', params: { s1: 'a', s2: 'b' } }];
|
||||
|
||||
expect(matchesIDs(ids, [{ id: 'my-page', path: [''], params: {} }])).toBe(1);
|
||||
expect(matchesIDs(ids, [{ id: 'my-page', path: [':s1'], params: {} }])).toBe(1);
|
||||
expect(matchesIDs(ids, [{ id: 'my-page', path: [':s1', ':s2'], params: {} }])).toBe(3);
|
||||
expect(matchesIDs(ids, [{ id: 'my-page', path: [':s1', ':s2', ':s3'], params: {} }])).toBe(1);
|
||||
})
|
||||
});
|
||||
|
||||
describe('matchesPath', () => {
|
||||
@@ -227,7 +236,7 @@ describe('mergeParams', () => {
|
||||
});
|
||||
|
||||
describe('RouterSegments', () => {
|
||||
it ('should initialize with empty array', () => {
|
||||
it('should initialize with empty array', () => {
|
||||
const s = new RouterSegments([]);
|
||||
expect(s.next()).toEqual('');
|
||||
expect(s.next()).toEqual('');
|
||||
@@ -236,7 +245,7 @@ describe('RouterSegments', () => {
|
||||
expect(s.next()).toEqual('');
|
||||
});
|
||||
|
||||
it ('should initialize with array', () => {
|
||||
it('should initialize with array', () => {
|
||||
const s = new RouterSegments(['', 'path', 'to', 'destination']);
|
||||
expect(s.next()).toEqual('');
|
||||
expect(s.next()).toEqual('path');
|
||||
|
||||
@@ -32,16 +32,60 @@ export const findRouteRedirect = (path: string[], redirects: RouteRedirect[]) =>
|
||||
return redirects.find(redirect => matchesRedirect(path, redirect));
|
||||
};
|
||||
|
||||
export const matchesIDs = (ids: string[], chain: RouteChain): number => {
|
||||
export const matchesIDs = (ids: Pick<RouteID, 'id' | 'params'>[], chain: RouteChain): number => {
|
||||
const len = Math.min(ids.length, chain.length);
|
||||
let i = 0;
|
||||
for (; i < len; i++) {
|
||||
if (ids[i].toLowerCase() !== chain[i].id) {
|
||||
|
||||
let score = 0;
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
const routeId = ids[i];
|
||||
const routeChain = chain[i];
|
||||
// Skip results where the route id does not match the chain at the same index
|
||||
if (routeId.id.toLowerCase() !== routeChain.id) {
|
||||
break;
|
||||
}
|
||||
if (routeId.params) {
|
||||
const routeIdParams = Object.keys(routeId.params);
|
||||
/**
|
||||
* Only compare routes with the chain that have the same number of parameters.
|
||||
*/
|
||||
if (routeIdParams.length === routeChain.path.length) {
|
||||
/**
|
||||
* Maps the route's params into a path based on the path variable names,
|
||||
* to compare against the route chain format.
|
||||
*
|
||||
* Before:
|
||||
* ```ts
|
||||
* {
|
||||
* params: {
|
||||
* s1: 'a',
|
||||
* s2: 'b'
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* After:
|
||||
* ```ts
|
||||
* [':s1',':s2']
|
||||
* ```
|
||||
*/
|
||||
const pathWithParams = routeIdParams.map(key => `:${key}`);
|
||||
for (let j = 0; j < pathWithParams.length; j++) {
|
||||
// Skip results where the path variable is not a match
|
||||
if (pathWithParams[j].toLowerCase() !== routeChain.path[j]) {
|
||||
break;
|
||||
}
|
||||
// Weight path matches for the same index higher.
|
||||
score++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// Weight id matches
|
||||
score++;
|
||||
}
|
||||
return i;
|
||||
};
|
||||
return score;
|
||||
}
|
||||
|
||||
export const matchesPath = (inputPath: string[], chain: RouteChain): RouteChain | null => {
|
||||
const segments = new RouterSegments(inputPath);
|
||||
@@ -90,16 +134,16 @@ export const matchesPath = (inputPath: string[], chain: RouteChain): RouteChain
|
||||
|
||||
// Merges the route parameter objects.
|
||||
// Returns undefined when both parameters are undefined.
|
||||
export const mergeParams = (a: {[key: string]: any} | undefined, b: {[key: string]: any} | undefined): {[key: string]: any} | undefined => {
|
||||
export const mergeParams = (a: { [key: string]: any } | undefined, b: { [key: string]: any } | undefined): { [key: string]: any } | undefined => {
|
||||
return a || b ? { ...a, ...b } : undefined;
|
||||
};
|
||||
|
||||
export const routerIDsToChain = (ids: RouteID[], chains: RouteChain[]): RouteChain | null => {
|
||||
let match: RouteChain | null = null;
|
||||
let maxMatches = 0;
|
||||
const plainIDs = ids.map(i => i.id);
|
||||
|
||||
for (const chain of chains) {
|
||||
const score = matchesIDs(plainIDs, chain);
|
||||
const score = matchesIDs(ids, chain);
|
||||
if (score > maxMatches) {
|
||||
match = chain;
|
||||
maxMatches = score;
|
||||
|
||||
102
core/src/components/slides/IonicSlides.ts
Normal file
102
core/src/components/slides/IonicSlides.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
export const IonicSlides = (opts: any) => {
|
||||
const { swiper, extendParams } = opts;
|
||||
const slidesParams: any = {
|
||||
effect: undefined,
|
||||
direction: 'horizontal',
|
||||
initialSlide: 0,
|
||||
loop: false,
|
||||
parallax: false,
|
||||
slidesPerView: 1,
|
||||
spaceBetween: 0,
|
||||
speed: 300,
|
||||
slidesPerColumn: 1,
|
||||
slidesPerColumnFill: 'column',
|
||||
slidesPerGroup: 1,
|
||||
centeredSlides: false,
|
||||
slidesOffsetBefore: 0,
|
||||
slidesOffsetAfter: 0,
|
||||
touchEventsTarget: 'container',
|
||||
autoplay: false,
|
||||
freeMode: false,
|
||||
freeModeMomentum: true,
|
||||
freeModeMomentumRatio: 1,
|
||||
freeModeMomentumBounce: true,
|
||||
freeModeMomentumBounceRatio: 1,
|
||||
freeModeMomentumVelocityRatio: 1,
|
||||
freeModeSticky: false,
|
||||
freeModeMinimumVelocity: 0.02,
|
||||
autoHeight: false,
|
||||
setWrapperSize: false,
|
||||
zoom: {
|
||||
maxRatio: 3,
|
||||
minRatio: 1,
|
||||
toggle: false,
|
||||
},
|
||||
touchRatio: 1,
|
||||
touchAngle: 45,
|
||||
simulateTouch: true,
|
||||
touchStartPreventDefault: false,
|
||||
shortSwipes: true,
|
||||
longSwipes: true,
|
||||
longSwipesRatio: 0.5,
|
||||
longSwipesMs: 300,
|
||||
followFinger: true,
|
||||
threshold: 0,
|
||||
touchMoveStopPropagation: true,
|
||||
touchReleaseOnEdges: false,
|
||||
iOSEdgeSwipeDetection: false,
|
||||
iOSEdgeSwipeThreshold: 20,
|
||||
resistance: true,
|
||||
resistanceRatio: 0.85,
|
||||
watchSlidesProgress: false,
|
||||
watchSlidesVisibility: false,
|
||||
preventClicks: true,
|
||||
preventClicksPropagation: true,
|
||||
slideToClickedSlide: false,
|
||||
loopAdditionalSlides: 0,
|
||||
noSwiping: true,
|
||||
runCallbacksOnInit: true,
|
||||
coverflowEffect: {
|
||||
rotate: 50,
|
||||
stretch: 0,
|
||||
depth: 100,
|
||||
modifier: 1,
|
||||
slideShadows: true
|
||||
},
|
||||
flipEffect: {
|
||||
slideShadows: true,
|
||||
limitRotation: true
|
||||
},
|
||||
cubeEffect: {
|
||||
slideShadows: true,
|
||||
shadow: true,
|
||||
shadowOffset: 20,
|
||||
shadowScale: 0.94
|
||||
},
|
||||
fadeEffect: {
|
||||
crossFade: false
|
||||
},
|
||||
a11y: {
|
||||
prevSlideMessage: 'Previous slide',
|
||||
nextSlideMessage: 'Next slide',
|
||||
firstSlideMessage: 'This is the first slide',
|
||||
lastSlideMessage: 'This is the last slide'
|
||||
}
|
||||
}
|
||||
|
||||
if (swiper.pagination) {
|
||||
slidesParams.pagination = {
|
||||
type: 'bullets',
|
||||
clickable: false,
|
||||
hideOnClick: false,
|
||||
}
|
||||
}
|
||||
|
||||
if (swiper.scrollbar) {
|
||||
slidesParams.scrollbar = {
|
||||
hide: true
|
||||
}
|
||||
}
|
||||
|
||||
extendParams(slidesParams);
|
||||
}
|
||||
@@ -120,6 +120,8 @@ export const IonicSwiper = {
|
||||
name: 'ionic',
|
||||
on: {
|
||||
afterInit(swiper: any) {
|
||||
console.warn('[Deprecation Warning]: The IonicSwiper module has been deprecated in favor of the IonSlides module. This change was made to better support the Swiper 7 release. The IonicSwiper module will be removed in Ionic 7.0. See https://ionicframework.com/docs/api/slides#migration for revised migration steps.');
|
||||
|
||||
setupSwiperInIonic(swiper);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Method, Prop, Watch, h } from '@stencil/core';
|
||||
import { Build, Component, ComponentInterface, Element, Event, EventEmitter, Host, Method, Prop, Watch, h } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { componentOnReady } from '../../utils/helpers'
|
||||
@@ -24,8 +24,6 @@ export class Slides implements ComponentInterface {
|
||||
private mutationO?: MutationObserver;
|
||||
private readySwiper!: (swiper: SwiperInterface) => void;
|
||||
private swiper: Promise<SwiperInterface> = new Promise(resolve => { this.readySwiper = resolve; });
|
||||
private syncSwiper?: SwiperInterface;
|
||||
private didInit = false;
|
||||
|
||||
@Element() el!: HTMLIonSlidesElement;
|
||||
|
||||
@@ -141,8 +139,7 @@ export class Slides implements ComponentInterface {
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
// tslint:disable-next-line: strict-type-predicates
|
||||
if (typeof MutationObserver !== 'undefined') {
|
||||
if (Build.isBrowser) {
|
||||
const mut = this.mutationO = new MutationObserver(() => {
|
||||
if (this.swiperReady) {
|
||||
this.update();
|
||||
@@ -154,10 +151,7 @@ export class Slides implements ComponentInterface {
|
||||
});
|
||||
|
||||
componentOnReady(this.el, () => {
|
||||
if (!this.didInit) {
|
||||
this.didInit = true;
|
||||
this.initSwiper();
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -167,23 +161,6 @@ export class Slides implements ComponentInterface {
|
||||
this.mutationO.disconnect();
|
||||
this.mutationO = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to synchronously destroy
|
||||
* swiper otherwise it is possible
|
||||
* that it will be left in a
|
||||
* destroyed state if connectedCallback
|
||||
* is called multiple times
|
||||
*/
|
||||
const swiper = this.syncSwiper;
|
||||
if (swiper !== undefined) {
|
||||
swiper.destroy(true, true);
|
||||
this.swiper = new Promise(resolve => { this.readySwiper = resolve; });
|
||||
this.swiperReady = false;
|
||||
this.syncSwiper = undefined;
|
||||
}
|
||||
|
||||
this.didInit = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -369,7 +346,6 @@ export class Slides implements ComponentInterface {
|
||||
await waitForSlides(this.el);
|
||||
const swiper = new Swiper(this.el, finalOptions);
|
||||
this.swiperReady = true;
|
||||
this.syncSwiper = swiper;
|
||||
this.readySwiper(swiper);
|
||||
}
|
||||
|
||||
@@ -483,6 +459,8 @@ export class Slides implements ComponentInterface {
|
||||
init: () => {
|
||||
setTimeout(() => {
|
||||
this.ionSlidesDidLoad.emit();
|
||||
// Forces the swiper instance to update after initializing.
|
||||
this.update();
|
||||
}, 20);
|
||||
},
|
||||
slideChangeTransitionStart: this.ionSlideWillChange.emit,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Build, Component, ComponentInterface, Element, Event, EventEmitter, Host, Method, Prop, State, Watch, h, readTask } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { Color, StyleEventDetail, TextareaChangeEventDetail } from '../../interface';
|
||||
import { debounceEvent, findItemLabel, inheritAttributes, raf } from '../../utils/helpers';
|
||||
import type { Color, StyleEventDetail, TextareaChangeEventDetail } from '../../interface';
|
||||
import { debounceEvent, findItemLabel, inheritAriaAttributes, inheritAttributes, raf } from '../../utils/helpers';
|
||||
import { createColorClasses } from '../../utils/theme';
|
||||
|
||||
/**
|
||||
@@ -214,7 +214,10 @@ export class Textarea implements ComponentInterface {
|
||||
}
|
||||
|
||||
componentWillLoad() {
|
||||
this.inheritedAttributes = inheritAttributes(this.el, ['title']);
|
||||
this.inheritedAttributes = {
|
||||
...inheritAriaAttributes(this.el),
|
||||
...inheritAttributes(this.el, ['title']),
|
||||
};
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
|
||||
@@ -11,15 +11,15 @@ This guide will go over the recommended virtual scrolling packages for each fram
|
||||
|
||||
## Angular
|
||||
|
||||
For virtual scrolling options in Ionic Angular, please see [Angular Virtual Scroll Guide](../angular/virtual-scroll).
|
||||
For virtual scrolling options in Ionic Angular, please see [Angular Virtual Scroll Guide](../../angular/virtual-scroll).
|
||||
|
||||
## React
|
||||
|
||||
For virtual scrolling options in Ionic React, please see [React Virtual Scroll Guide](../react/virtual-scroll).
|
||||
For virtual scrolling options in Ionic React, please see [React Virtual Scroll Guide](../../react/virtual-scroll).
|
||||
|
||||
## Vue
|
||||
|
||||
For virtual scrolling options in Ionic Vue, please see [Vue Virtual Scroll Guide](../vue/virtual-scroll).
|
||||
For virtual scrolling options in Ionic Vue, please see [Vue Virtual Scroll Guide](../../vue/virtual-scroll).
|
||||
|
||||
------
|
||||
|
||||
|
||||
@@ -201,3 +201,10 @@ ion-card-header.ion-color .ion-inherit-color {
|
||||
.md .menu-content-push {
|
||||
box-shadow: $menu-md-box-shadow;
|
||||
}
|
||||
|
||||
// Safari/iOS 15 changes the appearance of input[type="date"].
|
||||
// For backwards compatibility from Ionic 5/Safari 14 designs,
|
||||
// we override the appearance only when using within an ion-input.
|
||||
ion-input input::-webkit-date-and-time-value {
|
||||
text-align: start;
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
// Slides
|
||||
// --------------------------------------------------
|
||||
|
||||
.swiper-container {
|
||||
.swiper {
|
||||
|
||||
// These values are the same for iOS and MD
|
||||
// We just do not add a .md or .ios class beforehand
|
||||
@@ -33,11 +33,11 @@
|
||||
// Pagination Bullets
|
||||
// --------------------------------------------------
|
||||
|
||||
.swiper-pagination-bullet {
|
||||
.swiper .swiper-pagination-bullet {
|
||||
background: var(--bullet-background);
|
||||
}
|
||||
|
||||
.swiper-pagination-bullet-active {
|
||||
.swiper .swiper-pagination-bullet-active {
|
||||
background: var(--bullet-background-active);
|
||||
}
|
||||
|
||||
@@ -45,36 +45,29 @@
|
||||
// Pagination Progress Bar
|
||||
// --------------------------------------------------
|
||||
|
||||
.swiper-pagination-progressbar {
|
||||
.swiper .swiper-pagination-progressbar {
|
||||
background: var(--progress-bar-background);
|
||||
}
|
||||
|
||||
.swiper-pagination-progressbar .swiper-pagination-progressbar-fill {
|
||||
.swiper .swiper-pagination-progressbar .swiper-pagination-progressbar-fill {
|
||||
background: var(--progress-bar-background-active);
|
||||
}
|
||||
|
||||
// Scrollbar
|
||||
// --------------------------------------------------
|
||||
|
||||
.swiper-scrollbar {
|
||||
.swiper .swiper-scrollbar {
|
||||
background: var(--scroll-bar-background);
|
||||
}
|
||||
|
||||
.swiper-scrollbar-drag {
|
||||
.swiper .swiper-scrollbar-drag {
|
||||
background: var(--scroll-bar-background-active);
|
||||
}
|
||||
|
||||
// Slide
|
||||
// --------------------------------------------------
|
||||
|
||||
ion-slide {
|
||||
display: block;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.slide-zoom {
|
||||
.swiper .slide-zoom {
|
||||
display: block;
|
||||
|
||||
width: 100%;
|
||||
@@ -82,7 +75,7 @@ ion-slide {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.swiper-slide {
|
||||
.swiper .swiper-slide {
|
||||
|
||||
// Center slide text vertically
|
||||
display: flex;
|
||||
@@ -101,7 +94,7 @@ ion-slide {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.swiper-slide img {
|
||||
.swiper .swiper-slide img {
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
|
||||
@@ -14,3 +14,4 @@ export { LIFECYCLE_WILL_ENTER, LIFECYCLE_DID_ENTER, LIFECYCLE_WILL_LEAVE, LIFECY
|
||||
export { menuController } from './utils/menu-controller';
|
||||
export { alertController, actionSheetController, modalController, loadingController, pickerController, popoverController, toastController } from './utils/overlays';
|
||||
export { IonicSwiper } from './components/slides/IonicSwiper';
|
||||
export { IonicSlides } from './components/slides/IonicSlides';
|
||||
|
||||
@@ -51,6 +51,74 @@ export const inheritAttributes = (el: HTMLElement, attributes: string[] = []) =>
|
||||
return attributeObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of available ARIA attributes + `role`.
|
||||
* Removed deprecated attributes.
|
||||
* https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes
|
||||
*/
|
||||
const ariaAttributes = [
|
||||
'role',
|
||||
'aria-activedescendant',
|
||||
'aria-atomic',
|
||||
'aria-autocomplete',
|
||||
'aria-braillelabel',
|
||||
'aria-brailleroledescription',
|
||||
'aria-busy',
|
||||
'aria-checked',
|
||||
'aria-colcount',
|
||||
'aria-colindex',
|
||||
'aria-colindextext',
|
||||
'aria-colspan',
|
||||
'aria-controls',
|
||||
'aria-current',
|
||||
'aria-describedby',
|
||||
'aria-description',
|
||||
'aria-details',
|
||||
'aria-disabled',
|
||||
'aria-errormessage',
|
||||
'aria-expanded',
|
||||
'aria-flowto',
|
||||
'aria-haspopup',
|
||||
'aria-hidden',
|
||||
'aria-invalid',
|
||||
'aria-keyshortcuts',
|
||||
'aria-label',
|
||||
'aria-labelledby',
|
||||
'aria-level',
|
||||
'aria-live',
|
||||
'aria-multiline',
|
||||
'aria-multiselectable',
|
||||
'aria-orientation',
|
||||
'aria-owns',
|
||||
'aria-placeholder',
|
||||
'aria-posinset',
|
||||
'aria-pressed',
|
||||
'aria-readonly',
|
||||
'aria-relevant',
|
||||
'aria-required',
|
||||
'aria-roledescription',
|
||||
'aria-rowcount',
|
||||
'aria-rowindex',
|
||||
'aria-rowindextext',
|
||||
'aria-rowspan',
|
||||
'aria-selected',
|
||||
'aria-setsize',
|
||||
'aria-sort',
|
||||
'aria-valuemax',
|
||||
'aria-valuemin',
|
||||
'aria-valuenow',
|
||||
'aria-valuetext',
|
||||
];
|
||||
|
||||
/**
|
||||
* Returns an array of aria attributes that should be copied from
|
||||
* the shadow host element to a target within the light DOM.
|
||||
* @param el The element that the attributes should be copied from.
|
||||
*/
|
||||
export const inheritAriaAttributes = (el: HTMLElement) => {
|
||||
return inheritAttributes(el, ariaAttributes);
|
||||
};
|
||||
|
||||
export const addEventListener = (el: any, eventName: string, callback: any, opts?: any) => {
|
||||
if (typeof (window as any) !== 'undefined') {
|
||||
const win = window as any;
|
||||
@@ -164,8 +232,8 @@ export const getAriaLabel = (componentEl: HTMLElement, inputId: string): { label
|
||||
labelText = label.textContent;
|
||||
label.setAttribute('aria-hidden', 'true');
|
||||
|
||||
// if there is no label, check to see if the user has provided
|
||||
// one by setting an id on the component and using the label element
|
||||
// if there is no label, check to see if the user has provided
|
||||
// one by setting an id on the component and using the label element
|
||||
} else if (componentId.trim() !== '') {
|
||||
label = document.querySelector(`label[for="${componentId}"]`);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { inheritAttributes } from '../helpers';
|
||||
import { inheritAttributes, inheritAriaAttributes } from '../helpers';
|
||||
|
||||
describe('inheritAttributes()', () => {
|
||||
it('should create an attribute inheritance object', () => {
|
||||
@@ -37,3 +37,29 @@ describe('inheritAttributes()', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('inheritAriaAttributes()', () => {
|
||||
it('should inherit ARIA attributes defined on the HTML element', () => {
|
||||
const el = document.createElement('div');
|
||||
el.setAttribute('aria-label', 'myLabel');
|
||||
el.setAttribute('aria-describedby', 'myDescription');
|
||||
|
||||
const attributeObject = inheritAriaAttributes(el);
|
||||
|
||||
expect(attributeObject).toEqual({
|
||||
'aria-label': 'myLabel',
|
||||
'aria-describedby': 'myDescription',
|
||||
});
|
||||
});
|
||||
|
||||
it('should inherit the role attribute defined on the HTML element', () => {
|
||||
const el = document.createElement('div');
|
||||
el.setAttribute('role', 'button');
|
||||
|
||||
const attributeObject = inheritAriaAttributes(el);
|
||||
|
||||
expect(attributeObject).toEqual({
|
||||
role: 'button',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -107,7 +107,7 @@ export const config: Config = {
|
||||
{
|
||||
type: 'docs-vscode',
|
||||
file: 'dist/html.html-data.json',
|
||||
sourceCodeBaseUrl: 'https://github.com/ionic-team/ionic/tree/master/core/',
|
||||
sourceCodeBaseUrl: 'https://github.com/ionic-team/ionic/tree/main/core/',
|
||||
},
|
||||
{
|
||||
type: 'dist',
|
||||
|
||||
@@ -4,4 +4,4 @@ This package publishes the JSON data used to build the [Ionic API documentation]
|
||||
|
||||
## License
|
||||
|
||||
* [MIT](https://raw.githubusercontent.com/ionic-team/ionic/master/LICENSE)
|
||||
* [MIT](https://raw.githubusercontent.com/ionic-team/ionic/main/LICENSE)
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/docs",
|
||||
"version": "5.8.2",
|
||||
"version": "5.9.4",
|
||||
"description": "Pre-packaged API documentation for the Ionic docs.",
|
||||
"main": "core.json",
|
||||
"types": "core.d.ts",
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
"release.dev": "node .scripts/release-dev.js",
|
||||
"release.prepare": "node .scripts/prepare.js",
|
||||
"release": "node .scripts/release.js",
|
||||
"changelog": "conventional-changelog -p angular -i ./CHANGELOG.md -k core -s"
|
||||
"changelog": "conventional-changelog -p angular -i ./CHANGELOG.md -k core -s",
|
||||
"commitizenBranches": "git-branch-is -q --not -r \"^(main|next|release-)\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^13.1.0",
|
||||
@@ -18,6 +19,7 @@
|
||||
"cz-conventional-changelog": "^3.3.0",
|
||||
"execa": "^0.10.0",
|
||||
"fs-extra": "^7.0.0",
|
||||
"git-branch-is": "^4.0.0",
|
||||
"husky": "^4.3.8",
|
||||
"inquirer": "^6.0.0",
|
||||
"listr": "^0.14.0",
|
||||
@@ -34,8 +36,8 @@
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
|
||||
"prepare-commit-msg": "exec < /dev/tty && git cz --hook || true"
|
||||
"commit-msg": "npm run commitizenBranches --silent && commitlint -E HUSKY_GIT_PARAMS || true",
|
||||
"prepare-commit-msg": "npm run commitizenBranches --silent && exec < /dev/tty && git cz --hook || true"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
18
packages/angular-server/package-lock.json
generated
18
packages/angular-server/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@ionic/angular-server",
|
||||
"version": "5.8.2",
|
||||
"version": "5.9.4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/angular-server",
|
||||
"version": "5.8.2",
|
||||
"version": "5.9.4",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@angular/animations": "8.2.13",
|
||||
@@ -16,7 +16,7 @@
|
||||
"@angular/core": "8.2.13",
|
||||
"@angular/platform-browser": "8.2.13",
|
||||
"@angular/platform-server": "8.2.13",
|
||||
"@ionic/core": "5.8.1",
|
||||
"@ionic/core": "5.9.3",
|
||||
"ng-packagr": "5.7.1",
|
||||
"tslint": "^5.12.1",
|
||||
"tslint-ionic-rules": "0.0.21",
|
||||
@@ -137,9 +137,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "5.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.8.1.tgz",
|
||||
"integrity": "sha512-twAPHhrGMYvHW0NgebMBfN70xDUkFxW+Zcxeus7jrhuJh1uWp/3MwawLi4InCwpyuFQiBo8yAaqC1hB1wTZmLA==",
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.9.3.tgz",
|
||||
"integrity": "sha512-WM50vVxAAw+MQYqWXKUK4usBgkr7iQ9UWSb6t59mG4ZSy/fPAb7ZIdAjxY0U5i1ykk6A7Ur4B9ZJMpC/a7nnug==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.4.0",
|
||||
@@ -5424,9 +5424,9 @@
|
||||
}
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "5.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.8.1.tgz",
|
||||
"integrity": "sha512-twAPHhrGMYvHW0NgebMBfN70xDUkFxW+Zcxeus7jrhuJh1uWp/3MwawLi4InCwpyuFQiBo8yAaqC1hB1wTZmLA==",
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-5.9.3.tgz",
|
||||
"integrity": "sha512-WM50vVxAAw+MQYqWXKUK4usBgkr7iQ9UWSb6t59mG4ZSy/fPAb7ZIdAjxY0U5i1ykk6A7Ur4B9ZJMpC/a7nnug==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@stencil/core": "^2.4.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/angular-server",
|
||||
"version": "5.8.2",
|
||||
"version": "5.9.4",
|
||||
"description": "Angular SSR Module for Ionic",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -49,7 +49,7 @@
|
||||
"@angular/core": "8.2.13",
|
||||
"@angular/platform-browser": "8.2.13",
|
||||
"@angular/platform-server": "8.2.13",
|
||||
"@ionic/core": "5.8.2",
|
||||
"@ionic/core": "5.9.4",
|
||||
"ng-packagr": "5.7.1",
|
||||
"tslint": "^5.12.1",
|
||||
"tslint-ionic-rules": "0.0.21",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/react-router",
|
||||
"version": "5.8.2",
|
||||
"version": "5.9.4",
|
||||
"description": "React Router wrapper for @ionic/react",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -27,7 +27,8 @@
|
||||
"lint": "tslint --project .",
|
||||
"lint.fix": "tslint --project . --fix",
|
||||
"tsc": "tsc -p .",
|
||||
"test.spec": "jest --ci"
|
||||
"test.spec": "jest --ci",
|
||||
"sync": "sh ./scripts/sync.sh"
|
||||
},
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.esm.js",
|
||||
@@ -39,15 +40,14 @@
|
||||
"tslib": "*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ionic/react": "5.8.2",
|
||||
"@ionic/react": "5.9.4",
|
||||
"react": ">=16.8.6",
|
||||
"react-dom": ">=16.8.6",
|
||||
"react-router": "^5.0.1",
|
||||
"react-router-dom": "^5.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ionic/core": "5.8.2",
|
||||
"@ionic/react": "5.8.2",
|
||||
"@ionic/react": "5.9.4",
|
||||
"@rollup/plugin-node-resolve": "^8.1.0",
|
||||
"@testing-library/jest-dom": "^5.11.6",
|
||||
"@testing-library/react": "^11.2.2",
|
||||
|
||||
15
packages/react-router/scripts/sync.sh
Normal file
15
packages/react-router/scripts/sync.sh
Normal file
@@ -0,0 +1,15 @@
|
||||
# Copy ionic react dist
|
||||
rm -rf node_modules/@ionic/react/dist node_modules/@ionic/react/css
|
||||
cp -a ../react/dist node_modules/@ionic/react/dist
|
||||
cp -a ../react/css node_modules/@ionic/react/css
|
||||
cp -a ../react/package.json node_modules/@ionic/react/package.json
|
||||
|
||||
# Copy core dist
|
||||
rm -rf node_modules/@ionic/core/dist node_modules/@ionic/core/loader
|
||||
cp -a ../../core/dist node_modules/@ionic/core/dist
|
||||
cp -a ../../core/loader node_modules/@ionic/core/loader
|
||||
cp -a ../../core/package.json node_modules/@ionic/core/package.json
|
||||
|
||||
# Copy ionicons
|
||||
rm -rf node_modules/ionicons
|
||||
cp -a ../../core/node_modules/ionicons node_modules/ionicons
|
||||
40542
packages/react-router/test-app/package-lock.json
generated
40542
packages/react-router/test-app/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -3,97 +3,57 @@
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "7.8.4",
|
||||
"@capacitor/android": "^2.2.0",
|
||||
"@capacitor/core": "1.5.2",
|
||||
"@capacitor/ios": "^2.2.0",
|
||||
"@ionic/react": "5.6.3",
|
||||
"@ionic/react-router": "^5.6.3",
|
||||
"@svgr/webpack": "4.3.3",
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.4.0",
|
||||
"@testing-library/user-event": "^8.0.3",
|
||||
"@types/jest": "^24.0.25",
|
||||
"@types/node": "^12.12.24",
|
||||
"@types/react": "^16.9.17",
|
||||
"@types/react-dom": "^16.9.4",
|
||||
"@capacitor/app": "1.0.3",
|
||||
"@capacitor/core": "3.2.4",
|
||||
"@capacitor/haptics": "1.1.0",
|
||||
"@capacitor/keyboard": "1.1.0",
|
||||
"@capacitor/status-bar": "1.0.3",
|
||||
"@ionic/react": "^5.8.3",
|
||||
"@ionic/react-router": "^5.8.3",
|
||||
"@testing-library/jest-dom": "^5.11.9",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/user-event": "^12.6.3",
|
||||
"@types/jest": "^26.0.20",
|
||||
"@types/node": "^12.19.15",
|
||||
"@types/react": "^16.14.3",
|
||||
"@types/react-dom": "^16.9.10",
|
||||
"@types/react-router": "^5.1.8",
|
||||
"@types/react-router-dom": "^5.1.3",
|
||||
"@typescript-eslint/eslint-plugin": "^2.10.0",
|
||||
"@typescript-eslint/parser": "^2.10.0",
|
||||
"babel-jest": "^24.9.0",
|
||||
"babel-loader": "^8.1.0",
|
||||
"babel-plugin-named-asset-import": "^0.3.6",
|
||||
"babel-preset-react-app": "^9.1.1",
|
||||
"camelcase": "^5.3.1",
|
||||
"case-sensitive-paths-webpack-plugin": "2.3.0",
|
||||
"concurrently": "^6.0.0",
|
||||
"cpy-cli": "^3.1.1",
|
||||
"css-loader": "3.4.2",
|
||||
"dotenv": "8.2.0",
|
||||
"dotenv-expand": "5.1.0",
|
||||
"eslint": "^6.6.0",
|
||||
"eslint-config-react-app": "^5.2.0",
|
||||
"eslint-loader": "3.0.3",
|
||||
"eslint-plugin-flowtype": "4.6.0",
|
||||
"eslint-plugin-import": "2.20.0",
|
||||
"eslint-plugin-jsx-a11y": "6.2.3",
|
||||
"eslint-plugin-react": "7.18.0",
|
||||
"eslint-plugin-react-hooks": "^1.6.1",
|
||||
"file-loader": "4.3.0",
|
||||
"fs-extra": "^8.1.0",
|
||||
"html-webpack-plugin": "4.0.0-beta.11",
|
||||
"identity-obj-proxy": "3.0.0",
|
||||
"ionicons": "^5.0.0",
|
||||
"jest": "24.9.0",
|
||||
"jest-environment-jsdom-fourteen": "1.0.1",
|
||||
"jest-resolve": "24.9.0",
|
||||
"jest-watch-typeahead": "0.4.2",
|
||||
"mini-css-extract-plugin": "0.9.0",
|
||||
"npm-watch": "^0.6.0",
|
||||
"optimize-css-assets-webpack-plugin": "5.0.3",
|
||||
"pnp-webpack-plugin": "1.6.0",
|
||||
"postcss-flexbugs-fixes": "4.1.0",
|
||||
"postcss-loader": "3.0.0",
|
||||
"postcss-normalize": "8.0.1",
|
||||
"postcss-preset-env": "6.7.0",
|
||||
"postcss-safe-parser": "4.0.1",
|
||||
"react": "^16.12.0",
|
||||
"react-app-polyfill": "^1.0.6",
|
||||
"react-dev-utils": "^10.2.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"@types/react-router-dom": "^5.1.7",
|
||||
"ionicons": "^5.4.0",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-router": "^5.2.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"resolve": "1.15.0",
|
||||
"resolve-url-loader": "3.1.1",
|
||||
"sass-loader": "8.0.2",
|
||||
"semver": "6.3.0",
|
||||
"source-map-loader": "^0.2.4",
|
||||
"style-loader": "0.23.1",
|
||||
"terser-webpack-plugin": "2.3.4",
|
||||
"ts-pnp": "1.1.5",
|
||||
"typescript": "3.7.4",
|
||||
"url-loader": "2.3.0",
|
||||
"wait-on": "^5.3.0",
|
||||
"webpack": "4.41.5",
|
||||
"webpack-dev-server": "3.10.2",
|
||||
"webpack-manifest-plugin": "2.2.0",
|
||||
"workbox-webpack-plugin": "4.3.1"
|
||||
},
|
||||
"watch": {
|
||||
"copyRouter": "../src/ReactRouter/*.*"
|
||||
"react-scripts": "^4.0.3",
|
||||
"typescript": "^4.1.3",
|
||||
"web-vitals": "^0.2.4",
|
||||
"workbox-background-sync": "^5.1.4",
|
||||
"workbox-broadcast-update": "^5.1.4",
|
||||
"workbox-cacheable-response": "^5.1.4",
|
||||
"workbox-core": "^5.1.4",
|
||||
"workbox-expiration": "^5.1.4",
|
||||
"workbox-google-analytics": "^5.1.4",
|
||||
"workbox-navigation-preload": "^5.1.4",
|
||||
"workbox-precaching": "^5.1.4",
|
||||
"workbox-range-requests": "^5.1.4",
|
||||
"workbox-routing": "^5.1.4",
|
||||
"workbox-strategies": "^5.1.4",
|
||||
"workbox-streams": "^5.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
"copyRouter": "cpy ../src/ReactRouter ./src/ReactRouter",
|
||||
"start": "concurrently \"npm-watch copyRouter\" \"node scripts/start.js --no-cache\"",
|
||||
"start": "npm run sync && react-scripts start",
|
||||
"start.ci": "npm run sync && BROWSER=none react-scripts start",
|
||||
"build": "node scripts/build.js",
|
||||
"test": "cypress open",
|
||||
"cypress": "node_modules/.bin/cypress run --headless --browser chrome",
|
||||
"e2e": "npm run copyRouter && concurrently \"node scripts/start.js --no-cache\" \"wait-on http-get://localhost:3000 && npm run cypress\" --kill-others --success first",
|
||||
"e2e": "npm run sync && concurrently \"SKIP_PREFLIGHT_CHECK=true react-scripts start\" \"wait-on http-get://localhost:3000 && npm run cypress\" --kill-others --success first",
|
||||
"sync": "sh ./scripts/sync.sh"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
@@ -108,64 +68,11 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@capacitor/cli": "1.5.2",
|
||||
"cypress": "^6.8.0",
|
||||
"react-scripts": "3.4.1"
|
||||
"@capacitor/cli": "3.2.4",
|
||||
"concurrently": "^6.3.0",
|
||||
"cpy-cli": "^3.1.1",
|
||||
"cypress": "^8.5.0",
|
||||
"wait-on": "^6.0.0"
|
||||
},
|
||||
"description": "An Ionic project",
|
||||
"jest": {
|
||||
"roots": [
|
||||
"<rootDir>/src"
|
||||
],
|
||||
"collectCoverageFrom": [
|
||||
"src/**/*.{js,jsx,ts,tsx}",
|
||||
"!src/**/*.d.ts"
|
||||
],
|
||||
"setupFiles": [
|
||||
"react-app-polyfill/jsdom"
|
||||
],
|
||||
"setupFilesAfterEnv": [
|
||||
"<rootDir>/src/setupTests.ts"
|
||||
],
|
||||
"testMatch": [
|
||||
"<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}",
|
||||
"<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}"
|
||||
],
|
||||
"testEnvironment": "jest-environment-jsdom-fourteen",
|
||||
"transform": {
|
||||
"^.+\\.(js|jsx|ts|tsx)$": "<rootDir>/node_modules/babel-jest",
|
||||
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
|
||||
"^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
|
||||
},
|
||||
"transformIgnorePatterns": [
|
||||
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$",
|
||||
"^.+\\.module\\.(css|sass|scss)$"
|
||||
],
|
||||
"modulePaths": [],
|
||||
"moduleNameMapper": {
|
||||
"^react-native$": "react-native-web",
|
||||
"^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy"
|
||||
},
|
||||
"moduleFileExtensions": [
|
||||
"web.js",
|
||||
"js",
|
||||
"web.ts",
|
||||
"ts",
|
||||
"web.tsx",
|
||||
"tsx",
|
||||
"json",
|
||||
"web.jsx",
|
||||
"jsx",
|
||||
"node"
|
||||
],
|
||||
"watchPlugins": [
|
||||
"jest-watch-typeahead/filename",
|
||||
"jest-watch-typeahead/testname"
|
||||
]
|
||||
},
|
||||
"babel": {
|
||||
"presets": [
|
||||
"react-app"
|
||||
]
|
||||
}
|
||||
"description": "An Ionic project"
|
||||
}
|
||||
|
||||
198
packages/react-router/test-app/scripts/build.js
vendored
198
packages/react-router/test-app/scripts/build.js
vendored
@@ -1,198 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
// Do this as the first thing so that any code reading it knows the right env.
|
||||
process.env.BABEL_ENV = 'production';
|
||||
process.env.NODE_ENV = 'production';
|
||||
|
||||
// Makes the script crash on unhandled rejections instead of silently
|
||||
// ignoring them. In the future, promise rejections that are not handled will
|
||||
// terminate the Node.js process with a non-zero exit code.
|
||||
process.on('unhandledRejection', (err) => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
// Ensure environment variables are read.
|
||||
require('../config/env');
|
||||
|
||||
const path = require('path');
|
||||
const chalk = require('react-dev-utils/chalk');
|
||||
const fs = require('fs-extra');
|
||||
const webpack = require('webpack');
|
||||
const configFactory = require('../config/webpack.config');
|
||||
const paths = require('../config/paths');
|
||||
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
|
||||
const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
|
||||
const printHostingInstructions = require('react-dev-utils/printHostingInstructions');
|
||||
const FileSizeReporter = require('react-dev-utils/FileSizeReporter');
|
||||
const printBuildError = require('react-dev-utils/printBuildError');
|
||||
|
||||
const measureFileSizesBeforeBuild = FileSizeReporter.measureFileSizesBeforeBuild;
|
||||
const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild;
|
||||
const useYarn = fs.existsSync(paths.yarnLockFile);
|
||||
|
||||
// These sizes are pretty large. We'll warn for bundles exceeding them.
|
||||
const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
|
||||
const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
|
||||
|
||||
const isInteractive = process.stdout.isTTY;
|
||||
|
||||
// Warn and crash if required files are missing
|
||||
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Generate configuration
|
||||
const config = configFactory('production');
|
||||
|
||||
// We require that you explicitly set browsers and do not fall back to
|
||||
// browserslist defaults.
|
||||
const { checkBrowsers } = require('react-dev-utils/browsersHelper');
|
||||
checkBrowsers(paths.appPath, isInteractive)
|
||||
.then(() => {
|
||||
// First, read the current file sizes in build directory.
|
||||
// This lets us display how much they changed later.
|
||||
return measureFileSizesBeforeBuild(paths.appBuild);
|
||||
})
|
||||
.then((previousFileSizes) => {
|
||||
// Remove all content but keep the directory so that
|
||||
// if you're in it, you don't end up in Trash
|
||||
fs.emptyDirSync(paths.appBuild);
|
||||
// Merge with the public folder
|
||||
copyPublicFolder();
|
||||
// Start the webpack build
|
||||
return build(previousFileSizes);
|
||||
})
|
||||
.then(
|
||||
({ stats, previousFileSizes, warnings }) => {
|
||||
if (warnings.length) {
|
||||
console.log(chalk.yellow('Compiled with warnings.\n'));
|
||||
console.log(warnings.join('\n\n'));
|
||||
console.log(
|
||||
'\nSearch for the ' +
|
||||
chalk.underline(chalk.yellow('keywords')) +
|
||||
' to learn more about each warning.'
|
||||
);
|
||||
console.log(
|
||||
'To ignore, add ' + chalk.cyan('// eslint-disable-next-line') + ' to the line before.\n'
|
||||
);
|
||||
} else {
|
||||
console.log(chalk.green('Compiled successfully.\n'));
|
||||
}
|
||||
|
||||
console.log('File sizes after gzip:\n');
|
||||
printFileSizesAfterBuild(
|
||||
stats,
|
||||
previousFileSizes,
|
||||
paths.appBuild,
|
||||
WARN_AFTER_BUNDLE_GZIP_SIZE,
|
||||
WARN_AFTER_CHUNK_GZIP_SIZE
|
||||
);
|
||||
console.log();
|
||||
|
||||
const appPackage = require(paths.appPackageJson);
|
||||
const publicUrl = paths.publicUrlOrPath;
|
||||
const publicPath = config.output.publicPath;
|
||||
const buildFolder = path.relative(process.cwd(), paths.appBuild);
|
||||
printHostingInstructions(appPackage, publicUrl, publicPath, buildFolder, useYarn);
|
||||
},
|
||||
(err) => {
|
||||
const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true';
|
||||
if (tscCompileOnError) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'Compiled with the following type errors (you may want to check these before deploying your app):\n'
|
||||
)
|
||||
);
|
||||
printBuildError(err);
|
||||
} else {
|
||||
console.log(chalk.red('Failed to compile.\n'));
|
||||
printBuildError(err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
)
|
||||
.catch((err) => {
|
||||
if (err && err.message) {
|
||||
console.log(err.message);
|
||||
}
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
// Create the production build and print the deployment instructions.
|
||||
function build(previousFileSizes) {
|
||||
// We used to support resolving modules according to `NODE_PATH`.
|
||||
// This now has been deprecated in favor of jsconfig/tsconfig.json
|
||||
// This lets you use absolute paths in imports inside large monorepos:
|
||||
if (process.env.NODE_PATH) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'Setting NODE_PATH to resolve modules absolutely has been deprecated in favor of setting baseUrl in jsconfig.json (or tsconfig.json if you are using TypeScript) and will be removed in a future major release of create-react-app.'
|
||||
)
|
||||
);
|
||||
console.log();
|
||||
}
|
||||
|
||||
console.log('Creating an optimized production build...');
|
||||
|
||||
const compiler = webpack(config);
|
||||
return new Promise((resolve, reject) => {
|
||||
compiler.run((err, stats) => {
|
||||
let messages;
|
||||
if (err) {
|
||||
if (!err.message) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
let errMessage = err.message;
|
||||
|
||||
// Add additional information for postcss errors
|
||||
if (Object.prototype.hasOwnProperty.call(err, 'postcssNode')) {
|
||||
errMessage += '\nCompileError: Begins at CSS selector ' + err['postcssNode'].selector;
|
||||
}
|
||||
|
||||
messages = formatWebpackMessages({
|
||||
errors: [errMessage],
|
||||
warnings: [],
|
||||
});
|
||||
} else {
|
||||
messages = formatWebpackMessages(
|
||||
stats.toJson({ all: false, warnings: true, errors: true })
|
||||
);
|
||||
}
|
||||
if (messages.errors.length) {
|
||||
// Only keep the first error. Others are often indicative
|
||||
// of the same problem, but confuse the reader with noise.
|
||||
if (messages.errors.length > 1) {
|
||||
messages.errors.length = 1;
|
||||
}
|
||||
return reject(new Error(messages.errors.join('\n\n')));
|
||||
}
|
||||
if (
|
||||
process.env.CI &&
|
||||
(typeof process.env.CI !== 'string' || process.env.CI.toLowerCase() !== 'false') &&
|
||||
messages.warnings.length
|
||||
) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'\nTreating warnings as errors because process.env.CI = true.\n' +
|
||||
'Most CI servers set it automatically.\n'
|
||||
)
|
||||
);
|
||||
return reject(new Error(messages.warnings.join('\n\n')));
|
||||
}
|
||||
|
||||
return resolve({
|
||||
stats,
|
||||
previousFileSizes,
|
||||
warnings: messages.warnings,
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function copyPublicFolder() {
|
||||
fs.copySync(paths.appPublic, paths.appBuild, {
|
||||
dereference: true,
|
||||
filter: (file) => file !== paths.appHtml,
|
||||
});
|
||||
}
|
||||
138
packages/react-router/test-app/scripts/start.js
vendored
138
packages/react-router/test-app/scripts/start.js
vendored
@@ -1,138 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
// Do this as the first thing so that any code reading it knows the right env.
|
||||
process.env.BABEL_ENV = 'development';
|
||||
process.env.NODE_ENV = 'development';
|
||||
|
||||
// Makes the script crash on unhandled rejections instead of silently
|
||||
// ignoring them. In the future, promise rejections that are not handled will
|
||||
// terminate the Node.js process with a non-zero exit code.
|
||||
process.on('unhandledRejection', (err) => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
// Ensure environment variables are read.
|
||||
require('../config/env');
|
||||
|
||||
const fs = require('fs');
|
||||
const chalk = require('react-dev-utils/chalk');
|
||||
const webpack = require('webpack');
|
||||
const WebpackDevServer = require('webpack-dev-server');
|
||||
const clearConsole = require('react-dev-utils/clearConsole');
|
||||
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
|
||||
const {
|
||||
choosePort,
|
||||
createCompiler,
|
||||
prepareProxy,
|
||||
prepareUrls,
|
||||
} = require('react-dev-utils/WebpackDevServerUtils');
|
||||
const openBrowser = require('react-dev-utils/openBrowser');
|
||||
const paths = require('../config/paths');
|
||||
const configFactory = require('../config/webpack.config');
|
||||
const createDevServerConfig = require('../config/webpackDevServer.config');
|
||||
|
||||
const useYarn = fs.existsSync(paths.yarnLockFile);
|
||||
const isInteractive = process.stdout.isTTY;
|
||||
|
||||
// Warn and crash if required files are missing
|
||||
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Tools like Cloud9 rely on this.
|
||||
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;
|
||||
const HOST = process.env.HOST || '0.0.0.0';
|
||||
|
||||
if (process.env.HOST) {
|
||||
console.log(
|
||||
chalk.cyan(
|
||||
`Attempting to bind to HOST environment variable: ${chalk.yellow(
|
||||
chalk.bold(process.env.HOST)
|
||||
)}`
|
||||
)
|
||||
);
|
||||
console.log(`If this was unintentional, check that you haven't mistakenly set it in your shell.`);
|
||||
console.log(`Learn more here: ${chalk.yellow('https://bit.ly/CRA-advanced-config')}`);
|
||||
console.log();
|
||||
}
|
||||
|
||||
// We require that you explicitly set browsers and do not fall back to
|
||||
// browserslist defaults.
|
||||
const { checkBrowsers } = require('react-dev-utils/browsersHelper');
|
||||
checkBrowsers(paths.appPath, isInteractive)
|
||||
.then(() => {
|
||||
// We attempt to use the default port but if it is busy, we offer the user to
|
||||
// run on a different port. `choosePort()` Promise resolves to the next free port.
|
||||
return choosePort(HOST, DEFAULT_PORT);
|
||||
})
|
||||
.then((port) => {
|
||||
if (port == null) {
|
||||
// We have not found a port.
|
||||
return;
|
||||
}
|
||||
|
||||
const config = configFactory('development');
|
||||
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
|
||||
const appName = require(paths.appPackageJson).name;
|
||||
const useTypeScript = fs.existsSync(paths.appTsConfig);
|
||||
const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true';
|
||||
const urls = prepareUrls(protocol, HOST, port, paths.publicUrlOrPath.slice(0, -1));
|
||||
const devSocket = {
|
||||
warnings: (warnings) => devServer.sockWrite(devServer.sockets, 'warnings', warnings),
|
||||
errors: (errors) => devServer.sockWrite(devServer.sockets, 'errors', errors),
|
||||
};
|
||||
// Create a webpack compiler that is configured with custom messages.
|
||||
const compiler = createCompiler({
|
||||
appName,
|
||||
config,
|
||||
devSocket,
|
||||
urls,
|
||||
useYarn,
|
||||
useTypeScript,
|
||||
tscCompileOnError,
|
||||
webpack,
|
||||
});
|
||||
// Load proxy config
|
||||
const proxySetting = require(paths.appPackageJson).proxy;
|
||||
const proxyConfig = prepareProxy(proxySetting, paths.appPublic, paths.publicUrlOrPath);
|
||||
// Serve webpack assets generated by the compiler over a web server.
|
||||
const serverConfig = createDevServerConfig(proxyConfig, urls.lanUrlForConfig);
|
||||
const devServer = new WebpackDevServer(compiler, serverConfig);
|
||||
// Launch WebpackDevServer.
|
||||
devServer.listen(port, HOST, (err) => {
|
||||
if (err) {
|
||||
return console.log(err);
|
||||
}
|
||||
if (isInteractive) {
|
||||
clearConsole();
|
||||
}
|
||||
|
||||
// We used to support resolving modules according to `NODE_PATH`.
|
||||
// This now has been deprecated in favor of jsconfig/tsconfig.json
|
||||
// This lets you use absolute paths in imports inside large monorepos:
|
||||
if (process.env.NODE_PATH) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'Setting NODE_PATH to resolve modules absolutely has been deprecated in favor of setting baseUrl in jsconfig.json (or tsconfig.json if you are using TypeScript) and will be removed in a future major release of create-react-app.'
|
||||
)
|
||||
);
|
||||
console.log();
|
||||
}
|
||||
|
||||
console.log(chalk.cyan('Starting the development server...\n'));
|
||||
openBrowser(urls.localUrlForBrowser);
|
||||
});
|
||||
|
||||
['SIGINT', 'SIGTERM'].forEach(function (sig) {
|
||||
process.on(sig, function () {
|
||||
devServer.close();
|
||||
process.exit();
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err && err.message) {
|
||||
console.log(err.message);
|
||||
}
|
||||
process.exit(1);
|
||||
});
|
||||
51
packages/react-router/test-app/scripts/test.js
vendored
51
packages/react-router/test-app/scripts/test.js
vendored
@@ -1,51 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
// Do this as the first thing so that any code reading it knows the right env.
|
||||
process.env.BABEL_ENV = 'test';
|
||||
process.env.NODE_ENV = 'test';
|
||||
process.env.PUBLIC_URL = '';
|
||||
|
||||
// Makes the script crash on unhandled rejections instead of silently
|
||||
// ignoring them. In the future, promise rejections that are not handled will
|
||||
// terminate the Node.js process with a non-zero exit code.
|
||||
process.on('unhandledRejection', (err) => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
// Ensure environment variables are read.
|
||||
require('../config/env');
|
||||
|
||||
const jest = require('jest');
|
||||
const execSync = require('child_process').execSync;
|
||||
let argv = process.argv.slice(2);
|
||||
|
||||
function isInGitRepository() {
|
||||
try {
|
||||
execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' });
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function isInMercurialRepository() {
|
||||
try {
|
||||
execSync('hg --cwd . root', { stdio: 'ignore' });
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Watch unless on CI or explicitly running all tests
|
||||
if (
|
||||
!process.env.CI &&
|
||||
argv.indexOf('--watchAll') === -1 &&
|
||||
argv.indexOf('--watchAll=false') === -1
|
||||
) {
|
||||
// https://github.com/facebook/create-react-app/issues/5210
|
||||
const hasSourceControl = isInGitRepository() || isInMercurialRepository();
|
||||
argv.push(hasSourceControl ? '--watch' : '--watchAll');
|
||||
}
|
||||
|
||||
jest.run(argv);
|
||||
@@ -1,6 +1,6 @@
|
||||
import { IonApp } from '@ionic/react';
|
||||
import React from 'react';
|
||||
import { Route, Redirect, BrowserRouter, Link } from 'react-router-dom';
|
||||
import { Route } from 'react-router-dom';
|
||||
|
||||
/* Core CSS required for Ionic components to work properly */
|
||||
import '@ionic/react/css/core.css';
|
||||
@@ -21,7 +21,7 @@ import '@ionic/react/css/text-transformation.css';
|
||||
/* Theme variables */
|
||||
import './theme/variables.css';
|
||||
import Main from './pages/Main';
|
||||
import { IonReactRouter } from './ReactRouter/IonReactRouter';
|
||||
import { IonReactRouter } from '@ionic/react-router';
|
||||
import DynamicRoutes from './pages/dynamic-routes/DynamicRoutes';
|
||||
import Routing from './pages/routing/Routing';
|
||||
import MultipleTabs from './pages/muiltiple-tabs/MultipleTabs';
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
IonButton,
|
||||
} from '@ionic/react';
|
||||
import { Route, Redirect } from 'react-router';
|
||||
import { IonReactRouter } from '../../ReactRouter/IonReactRouter';
|
||||
import { IonReactRouter } from '@ionic/react-router';
|
||||
import { triangle, square } from 'ionicons/icons';
|
||||
|
||||
const DynamicTabs: React.FC = () => {
|
||||
|
||||
@@ -8,9 +8,7 @@ import {
|
||||
IonButtons,
|
||||
IonBackButton,
|
||||
IonLabel,
|
||||
IonCard,
|
||||
IonButton,
|
||||
useIonViewWillEnter,
|
||||
} from '@ionic/react';
|
||||
import { useParams, useLocation } from 'react-router';
|
||||
|
||||
|
||||
@@ -7,10 +7,9 @@ import {
|
||||
IonListHeader,
|
||||
IonMenu,
|
||||
IonMenuToggle,
|
||||
IonNote,
|
||||
} from '@ionic/react';
|
||||
import React from 'react';
|
||||
import { bookmarkOutline, heartOutline, heartSharp, mailOutline, mailSharp } from 'ionicons/icons';
|
||||
import { heartOutline, heartSharp, mailOutline, mailSharp } from 'ionicons/icons';
|
||||
|
||||
interface MenuProps {}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
useIonViewWillEnter,
|
||||
IonButton,
|
||||
} from '@ionic/react';
|
||||
import { Route } from 'react-router';
|
||||
|
||||
interface OtherPageProps {}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ const RedirectRouting: React.FC = () => {
|
||||
const ionRouterContext = useContext(IonRouterContext);
|
||||
useEffect(() => {
|
||||
ionRouterContext.push('/routing/tabs', 'none');
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
IonContent,
|
||||
IonHeader,
|
||||
IonPage,
|
||||
IonTitle,
|
||||
IonToolbar,
|
||||
IonRouterOutlet,
|
||||
IonSplitPane,
|
||||
} from '@ionic/react';
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user