Compare commits

..

355 Commits

Author SHA1 Message Date
Brandy Carney
bea21e73b6 merge release-4.11.13
4.11.13
2020-10-01 15:09:21 -04:00
Brandy Carney
e8e76324d9 4.11.13 2020-10-01 14:07:06 -04:00
Brandy Carney
210db5b265 fix(datetime): do not set ampm when the column doesn't exist (#22224) 2020-10-01 13:58:20 -04:00
Brandy Carney
13168b6d77 merge release-4.11.12
4.11.12
2020-09-29 17:15:11 -04:00
Brandy Carney
4fe3798787 4.11.12 2020-09-29 16:45:51 -04:00
Brandy Carney
0d56c51664 fix(datetime): remove the automatic switching from am to pm and vice versa (#22208)
fixes #18924
2020-09-29 16:32:41 -04:00
Brandy Carney
390ca65079 merge release-4.11.11
Release 4.11.11
2020-09-11 17:08:58 -04:00
Brandy Carney
3dbffa89b1 chore(scripts): add in v4-lts npm tag as an option to publish 2020-09-11 16:38:44 -04:00
Brandy Carney
c28c45f493 4.11.11 2020-09-11 16:18:46 -04:00
Brandy Carney
478723c55f chore(common): comment out tests due to Stencil updating the jest version and causing build errors 2020-09-11 16:12:13 -04:00
Brandy Carney
1dac5a46f5 fix(datetime): do not reset to am when changing the hour and pm is set (#22016)
fixes #19175 fixes #19260 fixes #20026 references #16630
2020-09-11 13:05:26 -04:00
Brandy Carney
b396e54d4f chore(dependencies): update dependencies, lock them, build swiper (#22015) 2020-09-01 12:55:21 -04:00
Liam DeBeasi
5bccf31bed merge release-4.11.10
Release 4.11.10
2020-01-24 16:54:08 -05:00
Liam DeBeasi
0179aad2b3 4.11.10 2020-01-24 16:15:45 -05:00
Liam DeBeasi
db1fd1d72a fix(input): revert previous type change
This reverts commit 3a56228290.
2020-01-24 16:03:03 -05:00
Ely Lucas
1bfc1c0393 release-4.11.9 2020-01-23 13:06:05 -07:00
Ely Lucas
7b9515ffa3 4.11.9 2020-01-23 13:00:15 -07:00
Ely Lucas
708020551f fix(core): updating type of input value to accept numbers, fixes #20173 (#20267) 2020-01-23 11:15:22 -07:00
Ely Lucas
63d4e877fb fix(react): remove leaving view when routerdirection is back, fixes #20124 (#20268) 2020-01-22 17:07:22 -07:00
Ely Lucas
ec6a8dd86f fix(react): adding missing overlay component events, fixes #19923 (#20266) 2020-01-22 14:52:21 -07:00
Ely Lucas
2f8c13b696 fix(react): support routes without a path for notfound routes, fixes #20259 (#20261) 2020-01-21 16:12:42 -07:00
Ely Lucas
1411d8a173 fix(react): update icon types to be a string as well, fixes #20229 (#20230) 2020-01-17 16:57:11 -07:00
Ely Lucas
9e35ebed4a fix(react): re attach props on update, fixes 20192 (#20228) 2020-01-17 16:23:26 -07:00
Ely Lucas
aff9612d11 fix(react): Don't render overlay children if isOpen is false, fixes #20225 (#20226) 2020-01-17 15:42:58 -07:00
Ely Lucas
22f92294ce chore(react): updating types for location state to fix type errors (#20206) 2020-01-14 12:17:55 -07:00
Ely Lucas
ad8f3db725 release-4.11.8 2020-01-13 09:58:01 -07:00
Ely Lucas
023b835d16 4.11.8 2020-01-13 09:52:21 -07:00
Ely Lucas
8a5aba2068 fix(react): add missing react memory router 2020-01-13 09:08:34 -07:00
Ely Lucas
676cc19b89 fix(react): supporting ios and md props on icons (#20170) 2020-01-08 16:13:52 -07:00
Ely Lucas
654d04c265 chore(docs): updating ActionSheet React sample 2019-12-17 10:52:58 -07:00
Ely Lucas
857bab6641 fix(react): fixing type of icon in ToastOptions, ActionSheetOptions, fixes #20100 2019-12-17 10:42:15 -07:00
Ely Lucas
027306a258 merge release-4.11.7 2019-12-12 15:35:01 -07:00
Ely Lucas
0f10bb29e8 4.11.7 2019-12-12 14:58:54 -07:00
Ely Lucas
4a73544502 fix(react): fire lifecycle events on initial render, fixes #20071 2019-12-12 14:31:57 -07:00
Ely Lucas
9ea75ebec7 fix(react): fire lifecycle events on initial render, fixes #20071 2019-12-12 14:30:25 -07:00
Ely Lucas
1454539cd3 chore(core): removing old test 2019-12-11 10:02:57 -07:00
Ely Lucas
6dfa0da460 merge release-4.11.6 2019-12-11 09:57:10 -07:00
Ely Lucas
78b3029665 4.11.6 2019-12-11 09:13:38 -07:00
Ely Lucas
e116712275 fix(react): support for 'root' router direction, fixes #19982 (#20052) 2019-12-09 17:23:39 -07:00
Ely Lucas
1c7d1e5cf1 fix(react): first render performance improvements 2019-12-09 14:36:47 -07:00
Ely Lucas
684293ddbf fix(react): don't show back button when not appropriate 2019-12-03 15:29:55 -07:00
Ely Lucas
f9bf8dbe6f fix(react): support navigating to same page and route updates in IonRouterOutlet, fixes #19891, #19892, #19986 2019-12-03 14:22:26 -07:00
Ely Lucas
eef55bb007 fix(react): fix refs for controllers, overlays, ionpage, and ionrouteroutlet, fixes #19924 (#20012) 2019-11-27 16:08:56 -07:00
Ely Lucas
637b082976 chore(react): fix tabs docs (#19995) 2019-11-25 11:15:03 -07:00
Liam DeBeasi
6c20fecab0 merge release-4.11.5
Release 4.11.5
2019-11-14 15:15:53 -05:00
Liam DeBeasi
06c0c77673 4.11.5 2019-11-14 14:59:57 -05:00
Liam DeBeasi
dd007d55fe chore(angular): update Config deprecation message (#19908)
* update deprecation msg

* add exact release
2019-11-14 14:42:50 -05:00
Ely Lucas
5ff786a23d fix(react): improving lifecycle hooks to deal with stale closures, fixes #19873 (#19874) 2019-11-08 16:15:52 -07:00
Ely Lucas
f0efe4aed6 merge release-4.11.4 2019-11-07 14:47:51 -07:00
Ely Lucas
d8b6098e30 4.11.4 2019-11-07 14:34:46 -07:00
Aubrey Holland
7356c40174 fix(react): check for component unmount, fixes #19859 2019-11-07 13:32:45 -07:00
Ely Lucas
de0a899be7 chore(react): lowering the timeout for the ionpage check to avoid false positives 2019-11-07 13:21:23 -07:00
Ely Lucas
0a3014d35e fix(react): adding multiple subscriptions to lifecycle events, fixes #19792 (#19858) 2019-11-07 11:55:47 -07:00
Ely Lucas
628e76668e fix(react): add check to warn if no ionpage is found, fixes #19832 (#19857) 2019-11-07 10:00:17 -07:00
Ely Lucas
d89508b1b5 fix(react): expand the location stack to better support back button, fixes #19748 (#19856) 2019-11-07 09:00:01 -07:00
Ely Lucas
fd9745ddcd fix(react): adding hardware back button support, fixes(19819) (#19851) 2019-11-06 14:54:06 -07:00
Ely Lucas
bcc40c8d59 fix(react): adding swipe back functionality and routerOutlet ready improvements, fixes #19818 (#19849) 2019-11-06 10:08:57 -07:00
Ely Lucas
9fad4161be fix(react): create a new overlay each time component is presented, fixes #19841, #19823 (#19842) 2019-11-05 16:49:10 -07:00
Ely Lucas
17fe23a3b9 release-4.11.3 2019-10-30 12:23:08 -06:00
Ely Lucas
e61d7a3aeb chore(changelog): fixing changelog items 2019-10-30 12:20:01 -06:00
Ely Lucas
8d55564a0e 4.11.3 2019-10-30 12:11:29 -06:00
Ely Lucas
f74d9c6b9b chore(build): setting max workers to 2 in core tests 2019-10-30 11:17:48 -06:00
Ely Lucas
8fe8b4bbba chore(build): awaiting on test task 2019-10-30 09:50:11 -06:00
Brandy Carney
7713f7fe74 chore(build): linking react 2019-10-30 09:49:28 -06:00
Ely Lucas
9d0caf6de0 fix(react): checking if node is actually an element before treating it like one, fixes #19769 (#19783) 2019-10-29 10:36:28 -06:00
Ely Lucas
2dc5540910 fix(react): unmount leaving view when using browser back button, fixes #19749 (#19781) 2019-10-29 09:30:37 -06:00
Ely Lucas
f70e71a3d4 fix(react): checking isOpen again after async call before opening overlay, fixes #19755 2019-10-28 10:22:03 -06:00
Ely Lucas
31c754dab7 fix(react): don't remove current view, provide a better method to determine showGoBack fixes #19731 and #19732 2019-10-23 12:11:33 -06:00
Liam DeBeasi
70fefb5463 merge release-4.11.2
Release 4.11.2
2019-10-21 17:27:58 -04:00
Liam DeBeasi
8853bd5045 4.11.2 2019-10-21 15:05:43 -04:00
Brandy Carney
e63c65b644 chore(release): update release script to move the npm link 2019-10-21 13:14:22 -04:00
Liam DeBeasi
d97e167f31 fix(animations): ensure all elements are cleaned up when calling .destroy() (#19654)
* fix race condition

* remove zero
2019-10-21 12:37:19 -04:00
Liam DeBeasi
48539093bf fix(header): collapsible header works in tabs (#19658)
fixes #19640
2019-10-21 12:34:40 -04:00
Liam DeBeasi
1535e95a5f fix(menu): clamp out of bounds swipe value (#19684)
fixes #18927
2019-10-21 12:34:32 -04:00
Liam DeBeasi
70e0562dc9 fix(ios): hide leaving view after nav transition to avoid flicker (#19691)
fixes #19674
2019-10-21 12:34:26 -04:00
Ely Lucas
b7baf24e50 fix(react): adding change events to iontabs, fixes #19665 (#19711) 2019-10-21 06:29:19 -06:00
Ely Lucas
ee21d3ae43 fix(react): removing pages from DOM on nav, fixes #19701 (#19712) 2019-10-21 06:25:01 -06:00
Ely Lucas
d8ca878cb1 chore(react): removing console log and tree shaking change 2019-10-17 17:31:06 -06:00
Ely Lucas
fcdbb3ce98 fix(react): adding HashRouter to available ion routers, fixes #19621 (#19683) 2019-10-17 12:32:47 -06:00
Ely Lucas
fc6a754b38 merge r
Release 4.11.1
2019-10-14 10:41:03 -06:00
Ely Lucas
048a1a8265 4.11.1 2019-10-14 09:54:49 -06:00
Ely Lucas
ec188990d6 chore(): bumping timeout 2019-10-14 09:26:44 -06:00
Ely Lucas
81b1072322 chore(react): fixing test and another method to tab nav 2019-10-14 08:43:39 -06:00
Ely Lucas
87765564f6 fix(react): handle tab back nav better, fixes #19646 (#19647) 2019-10-13 15:20:39 -06:00
Ely Lucas
ed98d9e658 fix(react): add IonPicker as controller component, fixes #19620 (#19643) 2019-10-13 11:59:47 -06:00
Ely Lucas
b552daa6dd fix(build): properly update peer dependencies (#19639) 2019-10-11 16:57:57 -06:00
Ely Lucas
7f4b77ddba fix(react): moving tslint and friends to devDependencies (#19624) 2019-10-11 16:47:42 -06:00
Brandy Carney
c6ab439efb merge release-4.11.0
Release 4.11.0
2019-10-09 17:01:40 -04:00
Ely Lucas
209cd5adfa 4.11.0 2019-10-09 14:33:20 -06:00
Liam DeBeasi
4be0dde283 merge release-4.10.3
master Release 4.10.3
2019-10-09 15:15:16 -04:00
Liam DeBeasi
42a2be136f merge release-4.10.3
Release 4.10.3
2019-10-09 15:14:19 -04:00
Liam DeBeasi
6f5e304e18 4.10.3 2019-10-09 15:03:01 -04:00
Brandy Carney
637f26b364 fix(searchbar): update alignment of chips and other elements in toolbar (#19596)
fixes #19495 fixes #19502
2019-10-09 14:38:30 -04:00
Manu MA
63c2008a86 fix(content): set overscroll only on iOS (#19470)
fixes #19465
2019-10-09 14:38:24 -04:00
Ely Lucas
033abe994b fix(react): handle undefined attributes better, fixes #19563, #19580 (#19588) 2019-10-09 10:36:25 -06:00
Brandy Carney
7ce916cc7c fix(searchbar): update alignment of chips and other elements in toolbar (#19596)
fixes #19495 fixes #19502
2019-10-08 19:42:59 -04:00
Manu MA
3c4e65ba97 feat(): typed @ionic/docs (#19547) 2019-10-08 20:35:45 +02:00
Manu MA
bb32cea5c9 fix(content): set overscroll only on iOS (#19470)
fixes #19465
2019-10-08 13:01:38 -04:00
Liam DeBeasi
fcd7a5620b merge release-4.10.2
master Release 4.10.2
2019-10-08 11:23:23 -04:00
Liam DeBeasi
109b5fc633 merge release-4.10.2
Release 4.10.2
2019-10-08 11:23:02 -04:00
Liam DeBeasi
bc56c4aa7b docs(slides): fix variable name in animation examples (#19584) 2019-10-08 11:10:14 -04:00
Liam DeBeasi
9b0bbc86b8 4.10.2 2019-10-08 11:07:49 -04:00
Liam DeBeasi
a7b964279b fix(overlay): ensure lifecycles fire properly (#19579) 2019-10-08 10:41:52 -04:00
Ely Lucas
8706ecf9c3 chore(): React Build Scripts (#19501) 2019-10-07 10:37:20 -06:00
Nick Stucko
aed2dba5aa docs(range): add range pin CSS custom properties (#19537) 2019-10-07 12:02:47 -04:00
Liam DeBeasi
3050e9fe88 merge release-4.10.1
4.10.1
2019-10-07 11:49:40 -04:00
Liam DeBeasi
02c1724978 merge release-4.10.1
Release 4.10.1
2019-10-07 11:48:32 -04:00
Liam DeBeasi
790e0c69ea 4.10.1 2019-10-07 11:28:10 -04:00
Liam DeBeasi
19ee21a06c fix(md): fix flicker when navigating back in MD mode on certain Android devices (#19553)
fixes #19491
2019-10-07 10:19:39 -04:00
Liam DeBeasi
dea1c2635d fix(header): fix collapsing iOS header when using with split pane (#19480)
fixes #19541
2019-10-04 15:21:15 -04:00
Liam DeBeasi
17614cdcb3 refactor(animation): rename AnimationOnFinishOptions to AnimationCallbackOptions (#19551) 2019-10-04 12:19:23 -04:00
Brandy Carney
bfb704e2d2 fix(css): update deprecations to remove wrap (#19535)
the wrap attribute is still deprecated from global CSS but it improperly throws errors on textarea where it's valid

fixes #19499
2019-10-02 18:05:28 -04:00
Manu MA
9688f4d42f refactor(menu): deprecate main html attribute (#19237) 2019-10-02 17:13:27 -04:00
Manu MA
f4818a1f3a refactor(animation): update animation API (#19529) 2019-10-02 19:52:46 +02:00
Liam DeBeasi
71b8853ff4 fix(list): add bottom border for first item in inset list (#19525)
fixes #19507
2019-10-02 12:38:30 -04:00
Brandy Carney
77658e61cc fix(searchbar): update padding and button alignment (#19532)
fixes #19502
2019-10-02 12:23:23 -04:00
Liam DeBeasi
cdfd82a750 chore(): remove duplicate changelog item (#19512) 2019-10-02 10:42:17 -04:00
Liam DeBeasi
9f5ed231c3 fix(animation): animation timer fallback now accounts for iterations (#19527) 2019-10-02 10:41:29 -04:00
marcushultgren
3c846a7b06 docs(popover): fix Object.assign typo (#19497) 2019-09-30 11:30:39 -04:00
Ely Lucas
cb26f73f80 fix(react): adding href prop when routerLink is specified (#19481) 2019-09-27 14:28:10 -06:00
Liam DeBeasi
a02319b06b chore(): add experimental to large title (#19479) 2019-09-27 15:57:58 -04:00
Liam DeBeasi
c101dfe6db merge release-4.10.0
4.10.0
2019-09-27 13:39:08 -04:00
Liam DeBeasi
7768ab2307 merge release-4.10.0
Release 4.10.0
2019-09-27 13:37:37 -04:00
Liam DeBeasi
26f50ca651 4.10.0 2019-09-27 13:26:40 -04:00
Manu MA
44ad07480b fix(ie): css variables (#19473) 2019-09-27 18:27:15 +02:00
Liam DeBeasi
8a52c7d66b fix(content): remove pointer-events from iOS transition shadow (#19471)
fixes #19466
2019-09-27 09:33:52 -04:00
Manu MA
20ffc95ff1 chore(): webpack does not some local variables (#19458)
fixes #19442
2019-09-27 14:58:10 +02:00
Manu MA
b4d92c6241 fix(ie): classList does not support variadic (#19460) 2019-09-27 13:12:06 +02:00
Manu MA
a28e501272 test(angular): fix dependencies (#19468) 2019-09-27 13:07:45 +02:00
Manu MA
f4b97fd74a chore(): update stencil (#19462) 2019-09-26 19:58:20 +02:00
Liam DeBeasi
8ca97ce42c perf(animation): avoid ngzone with requestAnimationFrame (#19457)
* add patched zone for animations

* minify raf better
2019-09-26 11:25:30 -04:00
Liam DeBeasi
eab0865fba fix(menu): menus show proper drop shadows (#19454)
fixes #19387
2019-09-26 09:38:28 -04:00
Ely Lucas
c79e74b91f fix(react): fix types for new stencil 2019-09-25 17:05:11 -06:00
Liam DeBeasi
cf223e40c1 fix(radio-group): get radios before caching value to avoid infinite loop (#19448)
fixes #19277
2019-09-25 13:06:17 -04:00
Manu MA
446cf78e58 chore(): update deps (#19437) 2019-09-25 18:12:57 +02:00
Manu MA
0f05ea4245 feat(config): expose getMode() and deprecate Config (#19104) 2019-09-25 17:21:43 +02:00
Liam DeBeasi
bfa17d1594 fix(router-outlet): hide leaving view after transition finishes (#19335) 2019-09-24 19:45:58 +01:00
Ely Lucas
61f04e50b1 Master react (#19439)
chore(react): react rc3 release
2019-09-24 11:52:12 -06:00
Liam DeBeasi
e90e960294 chore(header): finalize collapse API (#19276)
* make requested changes

* add e2e

* add RTL support

* fix typo

* add info on how to make collapsable title

* add usage examples

* fix typo

* fix another typo

* fix typos

* update usage

* fix alpha order

* update api

* add class to collapse buttons

* merge

* update

* change back to collapse

* remove platform specific class

* update docs

* run build

* update api again

* run build
2019-09-24 18:00:03 +01:00
Nuno Arruda
1e081c0a22 docs(breaking): fix minor grammar issues (#19418) 2019-09-24 12:26:02 -04:00
Matthew Harris
bf2953cf85 docs(item): fragment links pointed at root not doc (#19402) 2019-09-20 14:00:29 -04:00
Matthew Harris
7f76f94c9d docs(item-divider): remove extra word "like" (#19403) 2019-09-20 13:59:46 -04:00
Matthew Harris
a74754179c docs(item-group): add sliding item comment as docs (#19404) 2019-09-20 13:59:01 -04:00
Matthew Harris
c5e1290dfe docs(item-options): use title case for headers (#19406) 2019-09-20 13:58:31 -04:00
Matthew Harris
6b9abf22f0 docs(item-sliding): set header to title case (#19407) 2019-09-20 13:58:05 -04:00
Manu MA
e98769edd0 fix(angular): add double initialize warning (#19393) 2019-09-20 14:29:34 +02:00
Manu MA
123d0f38b6 chore(): update swiper (#19398) 2019-09-20 13:58:37 +02:00
Liam DeBeasi
1b9593963e merge release-4.9.1
Release 4.9.1
2019-09-16 15:06:20 -04:00
Liam DeBeasi
e7cbafd4b3 merge release-4.9.1
Release 4.9.1
2019-09-16 15:03:49 -04:00
Liam DeBeasi
f7027fc9ad 4.9.1 2019-09-16 14:32:23 -04:00
Liam DeBeasi
4a900964dd fix(platform): properly detect iPads running iPadOS (#19258)
* Add support for iPadOS

* add better test

* small tweak
2019-09-16 14:22:22 -04:00
Ely Lucas
73dd70d756 feature(react): rc2 release
* fix(): add a page with class ion-page back to ionrouteroutlet - fixes #19146

* wip

* fix(react): attributes show up in dom

* chore(): adding ion-page to core wip

* wip

* fix destroy method

* wrap dom writes in raf

* Add comments

* fix(react): IonPage work

* chore(): ionpage rc3 changelog text

* fix(): syncing ion-page in a new way to get rid of timeout loop

* chore(): ViewStacks refactor out of router

* fix(): remove unused method in router

* wip - before setActiveView rework

* fix(): react router ion page work

* chore(): cleanup and dev release

* fix(): remove need to name tabs

* chore(): adding dev mode helpers

* fix(): adding className prop to back button fixes #19251

* fix(): routerDirection changes

* chore(): rc2 release

* fix(): fix react version in package

* chores(): build kickoff
2019-09-12 14:25:37 -06:00
Liam DeBeasi
aec2936725 fix(platform): properly detect iPads running iPadOS (#19258)
* Add support for iPadOS

* add better test

* small tweak
2019-09-12 09:29:50 -04:00
swifmaneum
70ba488502 docs(datetime): fix grammar and improve readability (#19316)
* docs(datetime): Fix grammar, improve readability

Fixed minor mistakes in the ion-datetime documentation

* docs(datetime): Improve readability
2019-09-12 08:58:19 -04:00
Brandy Carney
151548b0bc docs(ripple-effect): update usage to include styling
includes documentation on the different types and styles required for ripple to work properly

closes ionic-team/ionic-docs#699
references #17477
2019-09-11 15:06:01 -04:00
Liam DeBeasi
1cbb52c55c fix(animation): set property defaults to avoid inconsistencies (#19321)
* set defaults to avoid inconsistencies

* update test
2019-09-11 13:25:50 -04:00
Brandy Carney
e62780411f docs(back-button): fix vue usage
closes ionic-team/ionic-docs#775
2019-09-10 17:03:35 -04:00
Brandy Carney
fea061215d docs(modal): fix typo in usage
closes ionic-team/ionic-docs#806
2019-09-10 16:59:29 -04:00
Liam DeBeasi
2d39c07fec fix(animation): fallback to CSS Animations on older versions of Chrome (#19288)
fixes #19272
2019-09-10 11:32:40 -04:00
Liam DeBeasi
4e544f1d90 fix(animation): animations of duration 0 now run in Safari (#19287)
fixes #19285
2019-09-10 11:27:11 -04:00
Manu MA
a3f345c06d feat(docs): add vscode docs support (#19309) 2019-09-10 01:50:51 +02:00
Brandy Carney
e27962dcaf feat(title): add support for small title (#19215)
Updates title to include `small` size and updates searchbar and UI to match native.

closes #18898
2019-09-05 17:32:19 -04:00
Matthew Harris
ff2aaadf41 docs(nav): fix typos (#18948) 2019-09-05 12:47:07 -04:00
Matthew Harris
696be833dc docs(nav): terminology tweaks (#18970) 2019-09-05 12:46:30 -04:00
Manu MA
c15ae7cbf5 chore(): fix css warnings (#19265) 2019-09-05 17:07:25 +02:00
Liam DeBeasi
d9514801a8 chore(): add missing change to CHANGELOG (#19269) 2019-09-04 15:46:39 -04:00
Liam DeBeasi
923312ecd5 feat(title): add large iOS toolbar title (#19268)
Co-authored-by: Brandy Carney <brandyscarney@users.noreply.github.com>
2019-09-04 11:38:48 -04:00
Liam DeBeasi
d9610cdbdf merge release-4.9.0
4.9.0
2019-09-04 10:55:04 -04:00
Liam DeBeasi
c959d75633 merge release-4.9.0
Release 4.9.0
2019-09-04 10:53:19 -04:00
Liam DeBeasi
4cfd29f574 4.9.0 2019-09-04 10:41:31 -04:00
Liam DeBeasi
a81653bcdc fix(animation): add correct onFinish interface parameters (#19199) 2019-09-03 12:04:10 -04:00
Liam DeBeasi
07140cf2c5 stop menu animation when closed (#19234)
fixes #19203
2019-09-03 12:02:22 -04:00
Manu MA
c7b302c7a6 refactor(): add scss usage deprecation warning (#19238) 2019-08-30 20:20:55 +02:00
Manu MA
d1ee36b2c8 docs(all): update usage of css utils (#19208) 2019-08-30 18:32:21 +02:00
Manu MA
3d935978b3 test(): remove initial waitFor (#19217) 2019-08-30 16:45:13 +02:00
Manu MA
4c30878fc7 fix(menu-toggle): use ESM menuController (#19225) 2019-08-29 15:19:01 +02:00
Manu MA
9751f145e1 fix(segment): don't emit ionChange until didLoad (#19218)
fixes #19204
2019-08-29 09:30:37 +02:00
Liam DeBeasi
6eca5b0d7f fix(animation): better feature detection (#19212)
fixes #19205
2019-08-28 13:20:54 -04:00
Liam DeBeasi
93f2064927 fix(animation): properly clean up elements (#19210)
* fix destroy method

* wrap dom writes in raf

* Add comments
2019-08-28 12:01:29 -04:00
Manu MA
da5d3f0e04 refactor(): add warnings for deprecated CSS attributes 2019-08-28 13:53:21 +02:00
Liam DeBeasi
e1fa461e9b feat(swiper): expose full API (#19137)
* expose full swiper API

* update types

* run build

* run angular build
2019-08-27 12:25:35 -04:00
Liam DeBeasi
0e18f049c2 merge release-4.8.1
Release 4.8.1
2019-08-27 12:20:42 -04:00
Manu MA
ef34402960 refactor(events): add deprecations (#19103) 2019-08-27 18:20:07 +02:00
Liam DeBeasi
03bffc5d95 merge release-4.8.1
Release 4.8.1
2019-08-27 12:19:40 -04:00
Manu MA
c3044f59df feat(nav-link): merge nav-push/pop/set-root into a single component (#18909) 2019-08-27 18:14:13 +02:00
Liam DeBeasi
4902de4631 4.8.1 2019-08-27 11:56:32 -04:00
Michael Tintiuc
d031434b5d fix(vue): apply polyfills before defining custom elements
Closes #19176
2019-08-27 11:31:51 -04:00
Matthew Harris
7f6664708c docs(img): unencoded img tag in readme (#19172) 2019-08-27 10:50:56 -04:00
Manu MA
48a27636c7 fix(all): component reusage (#18963)
Use new stencil APIs to allow ionic elements to be reused once removed from the DOM.

fixes #18843
fixes #17344
fixes #16453
fixes #15879
fixes #15788
fixes #15484
fixes #17890
fixes #16364
2019-08-27 16:29:37 +02:00
Liam DeBeasi
b3c7436e01 fix(animation): account for negative values on menu gesture (#19196) 2019-08-27 10:12:52 -04:00
Manu MA
a65d897214 refactor(): deprecate web component controllers (#19109) 2019-08-27 14:00:45 +02:00
Simon
3e63b3c2c4 fix(input): update inputmode attribute values to match the specs (#19131) 2019-08-26 16:07:54 -04:00
Matthew Harris
d4db3af881 docs(css): replace text-wrap directive with class (#19144) 2019-08-26 15:27:00 -04:00
Manu MA
c7b6c7d563 test(sanitization): migrate test to spec (#19186) 2019-08-26 17:39:46 +02:00
Liam DeBeasi
b1c8fa39d6 fix(swipe-back): account for negative step values (#19188)
fixes #19181
2019-08-26 11:33:11 -04:00
Liam DeBeasi
fa958a5764 fix(animation): avoid partial keyframes (#19169)
* ensure custom props not part of final keyframes

* fix clear

* clean up
2019-08-23 12:50:09 -04:00
Liam DeBeasi
fb7098080a fix(animation): enable backwards compatibility for overlay animations (#19160)
* fix backwards compat for overlays

* fix overlay

* Address navigation edge case
2019-08-23 12:50:09 -04:00
Liam DeBeasi
547f648433 fix(animation): properties can be cleared after animation finishes (#19155)
* remove certain properties when done animating

* fix bug, add more tests

* clean up

* bug fix
2019-08-23 12:50:09 -04:00
Liam DeBeasi
0e8ab49d7f fix(animation): set fill mode to MD transition to both (#19161) 2019-08-23 12:50:09 -04:00
Liam DeBeasi
f2cfdf1bad fix(animation): avoid partial keyframes (#19169)
* ensure custom props not part of final keyframes

* fix clear

* clean up
2019-08-23 12:48:20 -04:00
Liam DeBeasi
c610406ba6 fix(animation): enable backwards compatibility for overlay animations (#19160)
* fix backwards compat for overlays

* fix overlay

* Address navigation edge case
2019-08-23 10:56:05 -04:00
Liam DeBeasi
50a92c026c fix(animation): properties can be cleared after animation finishes (#19155)
* remove certain properties when done animating

* fix bug, add more tests

* clean up

* bug fix
2019-08-22 16:12:17 -04:00
Liam DeBeasi
62a04d76f1 fix(animation): set fill mode to MD transition to both (#19161) 2019-08-22 16:11:50 -04:00
Ely Lucas
2923aac44e Master react (#19150)
* chore(): bump to beta 8

* fix(): IonFabButton href fix

* fix(react): support components with href attributes

* fix(): Prep work to break router out

* fix(): breaking react-router and react-core into own packages

* chore(): moving view stuff out of react-core

* chore(): dev build 8-1

* chore(): update to react beta 8

* chore(): fixes to deps

* fix(): removing IonAnchor in favor of IonRouterLink

* chore(): beta 9 release

* refactor(react): treeshake, minify, api

* wip

* fix(): react dev builds

* fix(): fixes to get app builds working again

* fix(): removing tgz file

* feat(): adding platform helper methods

* fix(): don't map attributes to props

* chore(): add test app

* feat(): copy css folder from core

* chore(): move rollup node resolve to devDependencies

* fix(): expose setupConfig()

* perf(): improve treeshaking

* fix(): removing crypto from generateUniqueId

* fix(): adding missing rollup dp

* fix(): test cleanup and fixes to make tests pass

* chore(): moving react to packages folder

* fix(): fixing react build due to move to packages

* feat(): adding missing IonInfiniteScrollContent component

* chore(): add automated testing using cypress

* fix(): adding option onDidDismiss to controller components

* 0.0.10 react

* wip

* fix(): removing deprecated React calls

* fix(): exporting setupConfig from core

* chore(): bump to 4.8.0-rc.0

* chore(): updating test-app deps and fixing test

* chore(): updates to react readme

* fix(): exposing isPlatform

* fix(react): support using class attribute for core components

* fix(react): fixing react tests by removing the webcrypto

* fix(react): supporting going back to pages with query strings

* chore(): adding react changelog

* chore(): react rc1 release
2019-08-21 18:11:32 -06:00
Ely Lucas
c6051e89a5 fix(): updating link to react readme (#19154) 2019-08-21 17:25:08 -06:00
Liam DeBeasi
27d042fe38 merge release-4.8.0
Release 4.8.0
2019-08-21 15:32:27 -04:00
Liam DeBeasi
c3871b0cda merge release-4.8.0
Release 4.8.0
2019-08-21 15:31:24 -04:00
Liam DeBeasi
919c73f66d 4.8.0 2019-08-21 15:18:33 -04:00
Liam DeBeasi
e0fa4a5276 chore(transition): update swipe back duration (#19148) 2019-08-21 10:09:40 -04:00
Adam Bradley
3b51f8f27c chore(ionicons): update ionicons version (#19143) 2019-08-20 22:54:52 -05:00
Liam DeBeasi
cd75428785 fix(animation): allow for quick swipes (#19141) 2019-08-20 19:27:24 -04:00
Liam DeBeasi
45a59d13cc perf(animation): reduce flickering when updating css animation on lower end devices (#19138)
* fix flickering on lower end devices

* fix flickering, reduce timeout padding

* Add raf for clean up

* bug fix

* ensure animations are cleaned up

* Revert "ensure animations are cleaned up"

Thie reverts commit cf363f00be.

* fix dependnecy

* Revert "ensure animations are cleaned up"
merge
This reverts commit cf363f00be.
2019-08-20 19:03:17 -04:00
Kelvin Dart
67ed89ded8 fix(alert): apply styling to disabled items (#18545)
* fix(datetime): ensure hasValue returns correct value

* fix(alert): apply styling to disabled items

* test(datetime): add tests for empty value datetime

* fix(): update getter for stencil update

* fix: change default opacity to disabled button opacity

* test(select): add tests to ion-select-option disabled items

* Revert "test(select): add tests to ion-select-option disabled items"

This reverts commit b7ac8675

* update disabled css to use classes
2019-08-20 10:24:30 -04:00
Domvel
cbd230c67e docs(): correct loading usage in BREAKING.md (#19136)
`content` does not exist in `LoadingOptions`. It's now called `message`.
2019-08-20 10:06:17 -04:00
Liam DeBeasi
5a2c441b3c fix(animation): add cubic-bezier conversions for gesture animations (#19134)
* enable linear easing switch on progressEnd

* Add easing to menu

* remove console log

* Add tests

* clean up code

* update comments
2019-08-19 13:18:49 -04:00
Liam DeBeasi
fd65765bdf fix(nav): prevent completing transition from being interrupted (#19113)
* do not enable swipe to begin before previous one has ended

* update defaults

* use canStart instead

* pause animations on finish

* remove old pause code
2019-08-16 13:33:39 -04:00
Liam DeBeasi
624e118b56 fix(animation): prevent animation re-run when toggling element visibility (#19115)
* clean up pause fn, rename oneTime to oneTimeCallback

* remove duration, play state, and delay from animations to prevent reruns when toggling visibility
2019-08-16 10:18:06 -04:00
Liam DeBeasi
7f39f8c357 perf(animation): improve reliability of reusing animation (#19106)
* fix race condition on reset

* fix linter

* fix linter

* remove unneeded pause at end
2019-08-15 10:08:55 -04:00
Manu MA
930b271a4a Master react (#18998)
* chore(): bump to beta 8

* fix(): IonFabButton href fix

* fix(react): support components with href attributes

* fix(): Prep work to break router out

* fix(): breaking react-router and react-core into own packages

* chore(): moving view stuff out of react-core

* chore(): dev build 8-1

* chore(): update to react beta 8

* chore(): fixes to deps

* fix(): removing IonAnchor in favor of IonRouterLink

* chore(): beta 9 release

* refactor(react): treeshake, minify, api

* wip

* fix(): react dev builds

* fix(): fixes to get app builds working again

* fix(): removing tgz file

* feat(): adding platform helper methods

* fix(): don't map attributes to props

* chore(): add test app

* feat(): copy css folder from core

* chore(): move rollup node resolve to devDependencies

* fix(): expose setupConfig()

* perf(): improve treeshaking

* fix(): removing crypto from generateUniqueId

* fix(): adding missing rollup dp

* fix(): test cleanup and fixes to make tests pass

* chore(): moving react to packages folder

* fix(): fixing react build due to move to packages

* feat(): adding missing IonInfiniteScrollContent component

* chore(): add automated testing using cypress

* fix(): adding option onDidDismiss to controller components

* 0.0.10 react

* wip

* fix(): removing deprecated React calls

* fix(): exporting setupConfig from core

* chore(): bump to 4.8.0-rc.0

* chore(): updating test-app deps and fixing test

* chore(): updates to react readme
2019-08-13 14:24:44 -06:00
Liam DeBeasi
0b1e23f754 perf(animation): remove display: none check (#19086)
* wrap offsetParent in raf

* Revert "wrap offsetParent in raf"
merge
This reverts commit 9910032964.

* remove display none check, add note to document
2019-08-13 14:46:40 -04:00
Adam Bradley
a2b7d57336 chore(package): update to stencil 1.2.5 (#19085) 2019-08-13 12:40:19 -05:00
Liam DeBeasi
ce192713c3 fix(animations): gesture based animations no longer flicker on slower devices (#19083)
* remove unneeded step

* remove unneeded recursion
2019-08-13 09:57:50 -04:00
Seth Lilly
94e525c10b fix(toggle): change background to use CSS variable (#19012)
fixes #18940
2019-08-12 10:25:59 -04:00
Liam DeBeasi
30ca46ab12 feat(animation): add animation utility (#18918)
* Add new keyframes proof of concept

* update esm import

* add base before and after methods, add tests

* add base before and after hooks

* update clean up methods, add tests

* add web animations support, change to arrow functions

* remove console logs

* add from, to, fromTo, and other properties

* add more tests, fix onFinish functionality, being testing with nav transitions

* add progress methods, use force linear

* run linter

* Add playSync

* integrate animations with framework components

* onFinish now supports multiple callbacks

* change const to let

* testing reverse

* add support for both animation utilities

* bug fix

* export createAnimation, a few tweaks

* add base tests

* fix issue with onFinish being called out of order. added tests

* fix race conditions in tests

* clean up

* fix bug where onFinish not calling for empty elements array,  update test

* clean up

* fix treeshaking, remove old comments

* remove old tests

* Add test for animationbuilder backwards compat

* update typings for menu controller

* mock web animations in tests

* run build

* fix type errors

* sync with master

* use requestAnimationFrame instead of writeTask

* fix flaky tests, fix menu

* fix ordering

* update webdriver

* fix wrong version

* Revert "fix wrong version"

This reverts commit be91296e97.

Revert chromedriver update

* Revert "update webdriver"

This reverts commit e49bc9d76e.

Revert chromedriver update

* expose raw animation object, add tests

* add stylesheet recycling

* finalize before and after hook tests

* a few styling changes

* fix lint warnings

* get rid of old code

* Fix progressStep overflow bug

* disable reuse stylesheet

* small updates

* fix old animation create

* setStyleProperty helper

* reuse keyframe styles

* keyframes

* fix css animation issue with display: none, add tests

* add comment

* fix issue with progress animations and css animations

* clean up

* clean up pt2

* fix tests

* fix linter

* add fill for overlays

* fix swipe to go back

* clean up css animations when done

* fix edge cases with css animations

* fix menu open and close

* add reset function

* clean up reset fn

* Fix issue where animation always being reset

* allow updating animations on the fly

* add clear onfinish method

* fix linter

* add callback options, expand force direction

* ensure opts is defined

* fix css animations open and close for menus

* remove test

* add extra check

* clean up

* fix css anim bug swipe to go back

* fix pause

* setup alt animation to avoid flickering

* clean up

* reset flags on destroy

* add ability to change duration on progressEnd

* fix flicker on duration change for css animations

* fix ios transition

* remove unneeded recursion

* increase durability of updating css animations on the fly

* fix gesture anim

* fix web anim as well. more work for cleanup

* simplify progressEnd for css animations

* fix swipe to go back race condition

* clean up

* Add todo

* fix one more bug
2019-08-12 10:05:04 -04:00
Adam Bradley
e33cf854a9 feat(spinner): add circular spinner for MD default (#19052) 2019-08-08 16:08:13 -05:00
Robin
e8cdda0fae fix(platform): set correct electron regex (#19044)
fixes #19043
2019-08-08 20:35:43 +02:00
Simon
1187dc2fc7 feat(searchbar): add inputmode property (#18980) 2019-08-08 20:13:34 +02:00
Manu MA
3c925bb27e test(virtual-scroll): make cards test deterministic (#19049) 2019-08-08 20:07:22 +02:00
Manu MA
ea3fdae2dd chore(): update deps (#18856) 2019-08-08 20:06:12 +02:00
Adam Bradley
a5d3c6bcd2 fix(transition): enable ios transition shadow by default (#19051) 2019-08-08 12:30:02 -05:00
Mike Hartington
5f869796be chore(): update ssr test app
Enables ES2015 builds and passes the bundleDependencies flag
2019-08-08 13:09:18 -04:00
Manu MA
7c48500f27 refactor(platform): isPlatform() does not need window (#19022) 2019-08-08 17:24:54 +02:00
Adam Duren
e4357f9823 docs(action-sheet): Make property names match component (#19041) 2019-08-08 16:54:45 +02:00
Liam DeBeasi
fb81966973 merge release-4.7.4
4.7.4
2019-08-07 16:11:18 -04:00
Liam DeBeasi
4ec74f8535 merge release-4.7.4
4.7.4 to master
2019-08-07 16:10:56 -04:00
Liam DeBeasi
c9f7c47571 4.7.4 2019-08-07 15:55:08 -04:00
Manu MA
39f076847f fix(): remove semicolons (#19033) 2019-08-07 13:12:30 -06:00
Manu MA
c473b3ed92 chore(): add production build check (#19031) 2019-08-07 12:00:15 -06:00
Liam DeBeasi
6d7b221b86 merge release-4.7.3
Release 4.7.3
2019-08-07 13:31:48 -04:00
Liam DeBeasi
a1b00a7804 merge release-4.7.3
4.7.3
2019-08-07 13:31:23 -04:00
Liam DeBeasi
2f7e3dbacd chore(): update 4.7.3 changelog 2019-08-07 13:07:43 -04:00
Liam DeBeasi
04b350ce0b 4.7.3 2019-08-07 13:06:03 -04:00
Liam DeBeasi
7f4d3a36df merge release-4.7.2
Release 4.7.2 merge to master
2019-08-07 12:23:40 -04:00
Liam DeBeasi
cb149ddd19 merge release-4.7.2
Release 4.7.2
2019-08-07 12:23:03 -04:00
Liam DeBeasi
a633db1688 4.7.2 2019-08-07 12:08:11 -04:00
Liam DeBeasi
3ec9607281 chore(): disable swipe to go back e2e tests (#19024) 2019-08-07 11:25:22 -04:00
Adam Bradley
84e306c1a6 feat(ssr): add ionic angular server (#18880) 2019-08-06 12:24:42 -05:00
Manu MA
713ea8adaa fix(router): fix partial gesture (#18977)
fixes #18462
2019-08-06 17:28:29 +02:00
Manu MA
8f7853c5e9 fix(range): participate in <form> (#19008) 2019-08-06 16:51:48 +02:00
Manu MA
f94300cbb3 refactor(angular): use arrow functions (#18910) 2019-08-06 14:18:08 +02:00
Manu MA
3a22105375 fix(platform): subscribeWithPriority trigger change detection (#18962)
fixes #18959
2019-08-06 13:39:01 +02:00
Manu MA
6bbdb80871 fix(accessor): ngModel conflits with nested inputs (#18976)
fixes #18248
2019-08-06 13:34:54 +02:00
Manu MA
7cd68b59fc fix(): remove JSX array commas (#19006) 2019-08-06 13:28:30 +02:00
Manu MA
d237e808c2 fix(reorder): only move item if reorder happens (#19007) 2019-08-06 13:26:37 +02:00
Manu MA
e043ea9dae chore(): fix e2e angular (#19005) 2019-08-06 13:05:47 +02:00
Liam DeBeasi
f9579bcd1d refactor(toast): add deprecation warnings for showCloseButton and closeButtonText (#18955) 2019-08-05 09:01:19 -04:00
James Spencer
23f327ecb6 feat(toast): optionally render ion-icon from asset path if provided (#18969) 2019-08-02 08:17:43 -05:00
Brandy Carney
3e1dfc657b chore(github): update issue template to include stackblitz 2019-07-31 16:49:28 -04:00
Matthew Harris
32bb1f7230 docs(nav-set-root): fix typos (#18946)
* docs(nav-set-root): fix typo a / of

* docs(nav-set-root): fix inconsistent terminology
2019-07-30 12:23:44 -04:00
Matthew Harris
48352533ff docs(nav-pop): fix typos & terminology (#18947) 2019-07-30 12:23:16 -04:00
Adam Bradley
e3a5d1f93a chore(angular-server): init angular-server package (#18950) 2019-07-30 09:50:23 -05:00
Brandy Carney
f08ac68e0b refactor(searchbar): add deprecation warnings for showCancelButton (#18938) 2019-07-30 10:12:51 -04:00
Brandy Carney
7951289460 docs(changelog): update changelog to include Angular 8 support 2019-07-29 10:26:08 -04:00
Liam DeBeasi
9f32d0edd7 merge release-4.7.1
Hotfix 4.7.1
2019-07-26 11:48:15 -04:00
Liam DeBeasi
ee4c404bd3 merge release-4.7.1
Release 4.7.1
2019-07-26 11:46:40 -04:00
Liam DeBeasi
27a68b3f7f 4.7.1 2019-07-26 11:35:34 -04:00
Manu MA
962783bfba fix(router-outlet): change detection fires properly (#18896)
* fix(router-outlet): never detach() the entering view

fixes #18894

* add tests

* ci

* update package-lock

* circle sync runtime
2019-07-26 11:13:50 -04:00
Manu MA
e82648bda2 refactor(all): update to one (part 3) (#18874) 2019-07-25 20:22:44 +02:00
Liam DeBeasi
9b85e13493 merge release-4.7.0
Merge changes from release-4.7.0 to master
2019-07-25 11:36:30 -04:00
Liam DeBeasi
462cee5b2e merge release-4.7.0
Release 4.7.0
2019-07-25 11:29:12 -04:00
Liam DeBeasi
d792560447 4.7.0 2019-07-25 11:10:51 -04:00
Liam DeBeasi
7272d481bf chore(): update stencil to 1.2.1 (#18891) 2019-07-25 10:58:47 -04:00
Manu Mtz.-Almeida
c83edd9329 chore(): update core in react 2019-07-25 16:18:51 +02:00
Amy Marsh
a869ca0bba (fix): define top-level ARIA landmark regions to improve accessibility (#18672)
references #18671
2019-07-24 17:35:50 -04:00
tomsk
c2348f71a5 fix(vue): rename swipeEnable to swipeGesture (#17346)
fixes #16002
2019-07-24 17:25:57 -04:00
Manu MA
67ffe2f9cc chore(): update stencil to 1.2.0 (#18882)
* chore(): update stencil

* Update to @stencil/core@1.2.0
2019-07-24 15:17:04 -04:00
Romulo Cintra
2e02dc7319 refactor(utils): remove duplicated functions in react utils (#18817) 2019-07-24 14:15:01 -04:00
Vlad Topala
b7761fe353 fix(datetime): allow AM/PM to be changed (#18684)
fixes #18585
2019-07-24 12:52:36 -04:00
Stefanos Anagnostou
00891119f7 feat(virtual-scroll): adds headerHeight and footerHeight (#18851)
Currently, if you have an ion-virtual-scroll with a list of items and a search bar for filtering them, when you change the list of items, the items disappear until rendered again, causing a flicker. This could be solved for the items using the itemHeight function to provide the exact height size and bypass some calculations and be more performant etc.

However, if you had a header or footer, they would still flicker. This commit adds two more optional functions named headerHeight and footerHeight that return the exact size of the header and footer respectively and resolve the flicker.
2019-07-24 18:29:16 +02:00
Manu MA
c91819c94f fix(virtual-scroll): rebuild cells on resizing (#18878) 2019-07-24 18:15:35 +02:00
Manu MA
3ef6ecf422 fix(virtual-scroll): make virtual-scroll css more specific (#18877)
fixes #18870
2019-07-24 18:05:16 +02:00
Manu MA
7ba718c0db fix(datetime): column validation (#18875)
fixes #18793
2019-07-24 18:04:43 +02:00
Matthew Harris
e8ab0fd317 docs(select): clarify button customisation options (#18835)
closes #18834 closes ionic-team/ionic-docs#836
2019-07-24 10:43:14 -04:00
Adam Bradley
815fa2eb06 feat(hydrate): add @ionic/core/hydrate app (#18867) 2019-07-23 16:46:06 -05:00
Adam Bradley
c52b3b4997 fix(hydrate): check for client runtime method (#18866) 2019-07-23 16:11:29 -05:00
Adam Bradley
23ce6fae9e fix(hydrate): avoid window reference (#18865) 2019-07-23 15:28:20 -05:00
Adam Bradley
a8455a90ff chore(ssr): fix document.body reference (#18863) 2019-07-23 14:11:09 -05:00
Amy Marsh
798103bf63 feat(searchbar): improve accessibility (#18797) 2019-07-23 10:21:10 -05:00
Adam Bradley
bd8ca63451 chore(ionicons): update to ionicons 4.6.2 (#18861) 2019-07-23 10:05:46 -05:00
Matthew Harris
cf27063aae docs(process): tiny typos (#18855) 2019-07-23 01:36:49 +02:00
Manu MA
fb18f3ba25 feat(): support for stackblitz (#18846) 2019-07-23 01:01:36 +02:00
Manu MA
71137a2ffa fix(tap-click): ensure ripple is removed (#18854)
fixes #18836
2019-07-22 18:54:50 +02:00
Manu MA
544e550286 fix(platform): wrap event listeners around zone (#18853)
fixes #18831
2019-07-22 18:53:31 +02:00
Matthew Harris
854004cf2c docs(nav-controller): fix typos (#18848) 2019-07-22 11:00:53 -04:00
Brandy Carney
6b5a59dc43 fix(components): apply translucent if backdrop-filter is supported (#18832)
This updates the components and the docs so that translucent is only applied when backdrop filter is supported, this prevents it from being applied when viewing iOS in Chrome, for example.

closes ionic-team/ionic-docs#666
2019-07-19 11:16:10 -04:00
Ken Sodemann
fbfc07688e fix(menu-controller): add swipeGesture proxy (#18806) 2019-07-18 15:56:09 -05:00
Adam Bradley
9b075ef529 feat(transition): iOS page transition shadow (#18695)
Closes #18661
2019-07-18 14:50:56 -05:00
Manu MA
97fec92365 fix(router-outlet): attach entering view before first change detection (#18821) 2019-07-18 10:26:54 +02:00
Manu MA
26e6d6f115 fix(textarea): autogrow (#18822)
fixes #18744
2019-07-17 19:23:13 +02:00
Nico L
978cc39009 fix(hardwareBackButton): added missing import of hardware back button… (#18794) 2019-07-17 17:54:19 +02:00
Manu MA
53179c475c fix(inputs): apply ng form classes (#18820) 2019-07-17 17:46:22 +02:00
Mike Hartington
7ae9303a97 chore(): change peer deps to support ng8 (#18645) 2019-07-15 10:13:02 -05:00
Brandy Carney
045bc59b75 fix(theming): update components to use the proper colors for dark themes (#18735)
references #18713
2019-07-12 17:31:42 -04:00
Mike Hartington
08af35aad2 chore(): update vue version 2019-07-12 15:43:59 -04:00
Ely Lucas
5b932152f8 React beta 7 (#18780)
* fix(react): ion-item work for href attribute

* fix(react): route redirect bugs

* chore(react): dev version bump

* fix(package): point module to correct esm dist file

* chore(ionicons): update to ionicons 4.6.2-0

* fix(): ion-item work for href attribute

* fix(): route redirect bugs

* fix(package): point module to correct esm dist file

* chore(): removing un-needed export

* fix(react): subsequent render redirect fix

* chore(react): bump version for beta 7 release
2019-07-12 09:38:52 -06:00
Max Lynch
9993b73355 Update v3 package.json
Again trying to get github to credit us for v3 installs on the Used By feature. This time trying a new repo URL
2019-07-11 09:29:05 -05:00
Max Lynch
f1eeed1c91 Move package.json to angular directory for v3.
Per conversation with Adam, we are trying to get GitHub to properly pick up the Used By
count for Ionic 3 which is much higher than v4 today. This is a dummy package.
2019-07-10 12:47:40 -05:00
Brandy Carney
ee81907713 merge release-4.6.2 2019-07-10 13:20:37 -04:00
Brandy Carney
1f40d8fffd Revert "chore(scripts): update release script"
This reverts commit e33bfc7f1d.
2019-07-10 13:20:00 -04:00
Brandy Carney
723196a157 merge release-4.6.2 2019-07-10 13:18:32 -04:00
Manu Mtz.-Almeida
0b0dddf8ec 4.6.2 2019-07-10 19:12:11 +02:00
Brandy Carney
e33bfc7f1d chore(scripts): update release script 2019-07-10 11:02:26 -04:00
Manu MA
03c1d19e07 perf(all): minify better by using arrow functions (#18730) 2019-07-10 10:33:33 -04:00
Manu MA
8beeff2c52 fix(virtual-scroll): remove runOutsideAngular error (#18752)
fixes #18746
2019-07-10 10:21:42 -04:00
Brandy Carney
f060db5fe6 merge release-4.6.1 2019-07-09 12:41:23 -04:00
Brandy Carney
4a3ff61571 merge release-4.6.1 2019-07-09 12:41:09 -04:00
Brandy Carney
908f36f574 4.6.1 2019-07-09 12:28:12 -04:00
Max Lynch
292cc867a5 Create v3 package.json for proper Used By count
Github scans repos to compute the Used By, and ionic 3 has more usage which we should get credit for so this adds a dummy `package.json` file for v3
2019-07-09 10:54:16 -05:00
Manu Mtz.-Almeida
ab20bf472d revert disconnecting page on leaving page 2019-07-09 10:32:46 +02:00
Mike Hartington
470615eb05 chore(): add page component 2019-07-08 20:26:39 -04:00
Simon Wicki
f56fea6a1f fix(vue): update imports for types and ionicons
Closes #18701
2019-07-08 20:25:30 -04:00
Brandy Carney
7fda509333 test(e2e): increase wait time 2019-07-08 13:16:17 -04:00
Brandy Carney
0031ab82b7 style(lint): fix lint issues 2019-07-08 11:11:49 -04:00
Manu Mtz.-Almeida
e059fc8048 perf(angular): skip zone 2019-07-06 19:33:34 +02:00
Manu Mtz.-Almeida
7953088418 fix(angular): fix linting issues 2019-07-05 20:32:42 +02:00
Manu Mtz.-Almeida
1add112be6 chore(): update stencil 2019-07-05 19:33:22 +02:00
Brandy Carney
f16b118794 fix(overlays): fallback to step color if overlay background variable is unset (#18709)
fixes #18658
2019-07-05 10:52:47 -04:00
Liam DeBeasi
d71c1cd6b0 Revert "fix(angular): use baseURI has base path"
This reverts commit 4038e0a60c.

revert
2019-07-03 14:11:53 -04:00
Liam DeBeasi
ccd46028f2 chore(): update stencil to 1.1.4 2019-07-03 13:29:25 -04:00
Brandy Carney
24840d4d99 fix(menu-button): hide menu button when auto hide or split pane (#18702)
- updates menu-button to use the host element
- moves menu-toggle logic to a utils file for menu button to share
- removes the dependency on menu-toggle
- adds an e2e test for an auto-hidden menu button

fixes #18666
2019-07-03 11:51:30 -04:00
Liam DeBeasi
a656dadf4b Merge branch '4.6.1-hotfix' of https://github.com/ionic-team/ionic into 4.6.1-hotfix
merge
2019-07-02 16:06:06 -04:00
Adam Bradley
03c834c647 fix(tabs): do not emit tab change if selectedTab undefined 2019-07-02 15:04:46 -05:00
Brandy Carney
876ab41ba8 fix(menu-button): move font-size to host for easier customization (#18699)
fixes #18667
2019-07-02 15:37:16 -04:00
Brandy Carney
dfa2b13c3a fix(item): do not disable entire item if there are multiple inputs (#18696)
references #18655
fixes #18670
2019-07-02 14:45:24 -04:00
Ely Lucas
c6bb2730a8 chore() react beta 6 release (#18588)
* fix(react) attribute data for web components fix

* fix(react) attribute data for web components fix

* wip

* putting back cause issues

* update version 0.6-6

* wip

* fix(react) - fixing flash between moving between tabs

* update version to 0.6-7

* update to core 4.6

* update to 6-9 and tab button selected fix

* wrapping react router

* beta 6 release
2019-07-02 10:08:23 -06:00
Liam DeBeasi
08daaeb1a3 Merge branch '4.6.1-hotfix' of https://github.com/ionic-team/ionic into 4.6.1-hotfix
update
2019-07-01 11:39:16 -04:00
Brandy Carney
1f51ab27c4 fix(router-link): add missing target prop (#18659)
references #18655
2019-07-01 11:23:41 -04:00
Manu Mtz.-Almeida
36a58df181 fix(): copy all scss files 2019-07-01 17:12:44 +02:00
Manu Mtz.-Almeida
4038e0a60c fix(angular): use baseURI has base path 2019-07-01 17:01:14 +02:00
Brandy Carney
6042b39313 fix(fab-button): set opacity on disabled fab button (#18685)
fixes #18682
2019-07-01 10:54:02 -04:00
Liam DeBeasi
dc04a4b8a9 Merge branch '4.6.1-hotfix' of https://github.com/ionic-team/ionic into 4.6.1-hotfix
merg
2019-07-01 10:51:26 -04:00
Manu Mtz.-Almeida
98499acff9 chore(): update ionicons 2019-06-28 22:59:33 +02:00
Liam DeBeasi
2417d32316 a# the commit.
merge
2019-06-28 16:33:35 -04:00
Liam DeBeasi
735280168f Merge branch '4.6.x' of https://github.com/ionic-team/ionic into 4.6.x
merge
2019-06-28 16:33:08 -04:00
Manu Mtz.-Almeida
ef10f190cd fix(): copy theme scss 2019-06-28 22:26:23 +02:00
Manu Mtz.-Almeida
b9b60df0a4 chore(): update stencil 2019-06-28 22:26:17 +02:00
Manu Mtz.-Almeida
b69fb69a1a fix(router-outlet): fix swipe to go back 2019-06-27 17:51:03 +02:00
Kelvin Dart
92e0f98633 fix(datetime): datetime no longer reports having a value if none is set (#18541)
fixes #17979 
fixes #18540
2019-06-27 17:51:03 +02:00
Manu Mtz.-Almeida
0d58101edc fix(infinite-scroll): fix scroll listener 2019-06-27 17:50:13 +02:00
Manu Mtz.-Almeida
44c88ad908 fix(): overlay create opts are optional 2019-06-27 17:36:26 +02:00
Kelvin Dart
45b82dc466 fix(datetime): datetime no longer reports having a value if none is set (#18541)
fixes #17979 
fixes #18540
2019-06-27 10:48:09 -04:00
Brandy Carney
22ac160021 merge release-4.6.0 2019-06-26 14:15:46 -04:00
Brandy Carney
b46a025576 merge release-4.6.0
Release 4.6.0
2019-06-26 14:12:51 -04:00
Liam DeBeasi
335e02aa44 merge release-4.5.0
Release 4.5.0
2019-06-12 13:06:52 -04:00
Liam DeBeasi
017febed96 merge release-4.4.2
Release 4.4.2
2019-05-22 19:55:09 -04:00
824 changed files with 44906 additions and 20554 deletions

View File

@@ -91,6 +91,75 @@ jobs:
paths:
- "*"
build-angular-server:
<<: *defaults
steps:
- checkout
- attach_workspace:
at: /tmp/workspace
- run:
command: npm install
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:
- "*"
build-react:
<<: *defaults
steps:
- checkout
- attach_workspace:
at: /tmp/workspace
- run:
command: npm install
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:
- "*"
build-react-router:
<<: *defaults
steps:
- checkout
- attach_workspace:
at: /tmp/workspace
- run:
command: npm install
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:
- "*"
test-core-clean-build:
<<: *defaults
steps:
@@ -164,6 +233,64 @@ jobs:
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-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
test-angular-e2e:
<<: *defaults
steps:
@@ -173,6 +300,9 @@ jobs:
- run:
command: npm install
working_directory: /tmp/workspace/angular/test/test-app
- run:
command: npm run sync
working_directory: /tmp/workspace/angular/test/test-app
- run:
command: npm test
working_directory: /tmp/workspace/angular/test/test-app
@@ -205,7 +335,23 @@ workflows:
- 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]
- test-angular-lint:
requires: [build-angular]
- test-angular-e2e:
requires: [build-angular]
requires:
- build-angular
- build-angular-server

View File

@@ -37,6 +37,7 @@ assignees: ''
A sample application via GitHub
StackBlitz (https://stackblitz.com)
Ionic Angular StackBlitz: https://stackblitz.com/edit/ionic-v4-angular-tabs
Plunker (http://plnkr.co/edit/cpeRJs?p=preview)

6
.github/PROCESS.md vendored
View File

@@ -64,7 +64,7 @@ If the issue is a support question, the submitter should be redirected to our [f
### Incomplete Template
If the issue template has not been filled out completely, the issue should be closed and locked. The submitter should be informed top re-submit the issue making sure they fill the form out completely. Use the `ionitron: missing template` label to accomplish this.
If the issue template has not been filled out completely, the issue should be closed and locked. The submitter should be informed to re-submit the issue making sure they fill the form out completely. Use the `ionitron: missing template` label to accomplish this.
### Issues with Open Questions
@@ -77,7 +77,7 @@ NOTE: be sure to perform those actions in the order stated. If you add the comme
If there is a response to the question, the bot will remove the `needs: reply` and apply the `triage` label. The issue will then go through the triage handling again.
if there is no response within 30 days, the issue will be closed and locked.
If there is no response within 30 days, the issue will be closed and locked.
## Workflow
@@ -248,4 +248,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 `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.

3
.gitignore vendored
View File

@@ -57,8 +57,9 @@ prerender-static.html
# stencil
angular/css/
packages/react/css/
core/css/
core/hydrated/
core/hydrate/
core/loader/
core/www/
.stencil/

View File

@@ -1,6 +1,7 @@
const fs = require('fs-extra');
const path = require('path');
const execa = require('execa');
const inquirer = require('inquirer');
const Listr = require('listr');
const semver = require('semver');
const tc = require('turbocolor');
@@ -11,6 +12,8 @@ const packages = [
'core',
'docs',
'angular',
'packages/react',
'packages/react-router'
];
function readPkg(project) {
@@ -32,37 +35,79 @@ function projectPath(project) {
return path.join(rootDir, project);
}
async function askNpmTag(version) {
const prompts = [
{
type: 'list',
name: 'npmTag',
message: 'Select npm tag or specify a new tag',
choices: ['latest', 'next', 'v4-lts']
.concat([
new inquirer.Separator(),
{
name: 'Other (specify)',
value: null
}
])
},
{
type: 'confirm',
name: 'confirm',
message: answers => {
return `Will publish ${tc.cyan(version)} to ${tc.cyan(answers.npmTag)}. Continue?`;
}
}
];
const { npmTag, confirm } = await inquirer.prompt(prompts);
return { npmTag, confirm };
}
function checkGit(tasks) {
tasks.push(
{
title: 'Check current branch',
task: () => execa.stdout('git', ['symbolic-ref', '--short', 'HEAD']).then(branch => {
if (branch.indexOf('release') === -1 && branch.indexOf('hotfix') === -1) {
throw new Error(`Must be on a "release" or "hotfix" branch.`);
}
})
task: () =>
execa.stdout('git', ['symbolic-ref', '--short', 'HEAD']).then(branch => {
if (branch.indexOf('release') === -1 && branch.indexOf('hotfix') === -1) {
throw new Error(`Must be on a "release" or "hotfix" branch.`);
}
})
},
{
title: 'Check local working tree',
task: () => execa.stdout('git', ['status', '--porcelain']).then(status => {
if (status !== '') {
throw new Error(`Unclean working tree. Commit or stash changes first.`);
}
})
task: () =>
execa.stdout('git', ['status', '--porcelain']).then(status => {
if (status !== '') {
throw new Error(`Unclean working tree. Commit or stash changes first.`);
}
})
},
{
title: 'Check remote history',
task: () => execa.stdout('git', ['rev-list', '--count', '--left-only', '@{u}...HEAD']).then(result => {
if (result !== '0') {
throw new Error(`Remote history differs. Please pull changes.`);
}
})
task: () =>
execa.stdout('git', ['rev-list', '--count', '--left-only', '@{u}...HEAD']).then(result => {
if (result !== '0') {
throw new Error(`Remote history differs. Please pull changes.`);
}
})
}
);
}
const isValidVersion = input => Boolean(semver.valid(input));
function checkTestDist(tasks) {
tasks.push({
title: 'Check dist folders for required files',
task: () =>
execa.stdout('node', ['.scripts/test-dist.js']).then(status => {
if (status.indexOf('✅ test.dist') === -1) {
throw new Error(`Test Dist did not find some required files`);
}
})
});
}
const isValidVersion = input => Boolean(semver.valid(input));
function preparePackage(tasks, package, version, install) {
const projectRoot = projectPath(package);
@@ -74,7 +119,9 @@ function preparePackage(tasks, package, version, install) {
title: `${pkg.name}: validate new version`,
task: () => {
if (!isVersionGreater(pkg.version, version)) {
throw new Error(`New version \`${version}\` should be higher than current version \`${pkg.version}\``);
throw new Error(
`New version \`${version}\` should be higher than current version \`${pkg.version}\``
);
}
}
});
@@ -82,7 +129,7 @@ function preparePackage(tasks, package, version, install) {
projectTasks.push({
title: `${pkg.name}: install npm dependencies`,
task: async () => {
await fs.remove(path.join(projectRoot, 'node_modules'))
await fs.remove(path.join(projectRoot, 'node_modules'));
await execa('npm', ['i'], { cwd: projectRoot });
}
});
@@ -95,6 +142,13 @@ function preparePackage(tasks, package, version, install) {
title: `${pkg.name}: npm link @ionic/core`,
task: () => execa('npm', ['link', '@ionic/core'], { cwd: projectRoot })
});
if (package === 'packages/react-router') {
projectTasks.push({
title: `${pkg.name}: npm link @ionic/react`,
task: () => execa('npm', ['link', '@ionic/react'], { cwd: projectRoot })
});
}
}
if (version) {
@@ -102,29 +156,33 @@ function preparePackage(tasks, package, version, install) {
title: `${pkg.name}: lint`,
task: () => execa('npm', ['run', 'lint'], { cwd: projectRoot })
});
projectTasks.push({
title: `${pkg.name}: update ionic/core dep to ${version}`,
task: () => {
updateDependency(pkg, "@ionic/core", version);
writePkg(package, pkg);
}
});
projectTasks.push({
title: `${pkg.name}: test`,
task: () => execa('npm', ['test'], { cwd: projectRoot })
});
// Disable tests for publish, these pass locally
// projectTasks.push({
// title: `${pkg.name}: test`,
// task: async () => await execa('npm', ['test'], { cwd: projectRoot })
// });
}
projectTasks.push({
title: `${pkg.name}: build`,
task: () => execa('npm', ['run', 'build'], { cwd: projectRoot })
});
if (package === 'core') {
if (package === 'core' || package === 'packages/react') {
projectTasks.push({
title: `${pkg.name}: npm link`,
task: () => execa('npm', ['link'], { cwd: projectRoot })
});
}
if (version) {
projectTasks.push({
title: `${pkg.name}: update ionic/core dep to ${version}`,
task: () => {
updateDependency(pkg, '@ionic/core', version);
writePkg(package, pkg);
}
});
}
}
// Add project tasks
@@ -134,7 +192,6 @@ function preparePackage(tasks, package, version, install) {
});
}
function prepareDevPackage(tasks, package, version) {
const projectRoot = projectPath(package);
const pkg = readPkg(package);
@@ -152,7 +209,7 @@ function prepareDevPackage(tasks, package, version) {
projectTasks.push({
title: `${pkg.name}: update ionic/core dep to ${version}`,
task: () => {
updateDependency(pkg, "@ionic/core", version);
updateDependency(pkg, '@ionic/core', version);
writePkg(package, pkg);
}
});
@@ -162,7 +219,7 @@ function prepareDevPackage(tasks, package, version) {
task: () => execa('npm', ['run', 'build'], { cwd: projectRoot })
});
if (package === 'core') {
if (package === 'core' || package === 'packages/react') {
projectTasks.push({
title: `${pkg.name}: npm link`,
task: () => execa('npm', ['link'], { cwd: projectRoot })
@@ -181,33 +238,38 @@ function updatePackageVersions(tasks, packages, version) {
packages.forEach(package => {
updatePackageVersion(tasks, package, version);
tasks.push(
{
title: `${package} update @ionic/core dependency, if present ${tc.dim(`(${version})`)}`,
task: async () => {
if (package !== 'core') {
const pkg = readPkg(package);
updateDependency(pkg, '@ionic/core', version);
writePkg(package, pkg);
}
},
tasks.push({
title: `${package} update @ionic/core dependency, if present ${tc.dim(`(${version})`)}`,
task: async () => {
if (package !== 'core') {
const pkg = readPkg(package);
updateDependency(pkg, '@ionic/core', version);
writePkg(package, pkg);
}
}
)
});
if (package === 'packages/react-router') {
tasks.push({
title: `${package} update @ionic/react dependency, if present ${tc.dim(`(${version})`)}`,
task: async () => {
const pkg = readPkg(package);
updateDependency(pkg, '@ionic/react', version);
writePkg(package, pkg);
}
});
}
});
}
function updatePackageVersion(tasks, package, version) {
const projectRoot = projectPath(package);
tasks.push(
{
title: `${package}: update package.json ${tc.dim(`(${version})`)}`,
task: async () => {
await execa('npm', ['version', version], { cwd: projectRoot });
}
tasks.push({
title: `${package}: update package.json ${tc.dim(`(${version})`)}`,
task: async () => {
await execa('npm', ['version', version], { cwd: projectRoot });
}
);
});
}
function publishPackages(tasks, packages, version, tag = 'latest') {
@@ -237,7 +299,7 @@ function publishPackages(tasks, packages, version, tag = 'latest') {
title: `${package}: publish to ${tag} tag`,
task: async () => {
await execa('npm', ['publish', '--tag', tag], { cwd: projectRoot });
},
}
});
});
}
@@ -249,6 +311,9 @@ function updateDependency(pkg, dependency, version) {
if (pkg.devDependencies && pkg.devDependencies[dependency]) {
pkg.devDependencies[dependency] = version;
}
if (pkg.peerDependencies && pkg.peerDependencies[dependency]) {
pkg.peerDependencies[dependency] = version;
}
}
function isVersionGreater(oldVersion, newVersion) {
@@ -258,11 +323,20 @@ function isVersionGreater(oldVersion, newVersion) {
return true;
}
function copyCDNLoader(tasks, version) {
tasks.push({
title: `Copy CDN loader`,
task: () => execa('node', ['copy-cdn-loader.js', version], { cwd: path.join(rootDir, 'core', 'scripts') })
});
}
module.exports = {
checkTestDist,
checkGit,
askNpmTag,
isValidVersion,
isVersionGreater,
copyCDNLoader,
packages,
packagePath,
prepareDevPackage,
@@ -274,5 +348,5 @@ module.exports = {
updateDependency,
updatePackageVersion,
updatePackageVersions,
writePkg,
writePkg
};

View File

@@ -107,15 +107,17 @@ async function preparePackages(packages, version, install) {
});
// add update package.json of each project
packages.forEach(package => {
common.updatePackageVersion(tasks, package, version);
});
common.updatePackageVersions(tasks, packages, version);
// generate changelog
generateChangeLog(tasks);
// check dist folders
common.checkTestDist(tasks);
// update core readme with version number
updateCoreReadme(tasks, version);
common.copyCDNLoader(tasks, version);
const listr = new Listr(tasks, { showSubtasks: true });
await listr.run();
@@ -171,7 +173,6 @@ function updateCoreReadme(tasks, version) {
});
}
const SEMVER_INCREMENTS = ['patch', 'minor', 'major'];
const isValidVersionInput = input => SEMVER_INCREMENTS.indexOf(input) !== -1 || common.isValidVersion(input);

View File

@@ -38,6 +38,7 @@ async function main() {
packages.forEach(package => {
common.prepareDevPackage(tasks, package, devVersion);
});
common.copyCDNLoader(tasks, devVersion);
common.publishPackages(tasks, packages, devVersion, DIST_NPM_TAG);
const listr = new Listr(tasks);

View File

@@ -5,6 +5,7 @@
const tc = require('turbocolor');
const execa = require('execa');
const Listr = require('listr');
const path = require('path');
const octokit = require('@octokit/rest')()
const common = require('./common');
const fs = require('fs-extra');
@@ -12,10 +13,14 @@ const fs = require('fs-extra');
async function main() {
try {
const dryRun = process.argv.indexOf('--dry-run') > -1;
if (!process.env.GH_TOKEN) {
throw new Error('env.GH_TOKEN is undefined');
}
checkProductionRelease();
const tasks = [];
const { version } = common.readPkg('core');
const changelog = findChangelog();
@@ -23,15 +28,31 @@ async function main() {
// repo must be clean
common.checkGit(tasks);
// publish each package in NPM
common.publishPackages(tasks, common.packages, version);
const { npmTag, confirm } = await common.askNpmTag(version);
// push tag to git remote
publishGit(tasks, version, changelog);
if (!confirm) {
return;
}
if(!dryRun) {
// publish each package in NPM
common.publishPackages(tasks, common.packages, version, npmTag);
// push tag to git remote
publishGit(tasks, version, changelog, npmTag);
}
const listr = new Listr(tasks);
await listr.run();
console.log(`\nionic ${version} published!! 🎉\n`);
// Dry run doesn't publish to npm or git
if (dryRun) {
console.log(`
\n${tc.yellow('Did not publish. Remove the "--dry-run" flag to publish:')}\n${tc.green(version)} to ${tc.cyan(npmTag)}\n
`);
} else {
console.log(`\nionic ${version} published to ${npmTag}!! 🎉\n`);
}
} catch (err) {
console.log('\n', tc.red(err), '\n');
@@ -39,6 +60,15 @@ async function main() {
}
}
function checkProductionRelease() {
const corePath = common.projectPath('core');
const hasEsm = fs.existsSync(path.join(corePath, 'dist', 'esm'));
const hasEsmEs5 = fs.existsSync(path.join(corePath, 'dist', 'esm-es5'));
const hasCjs = fs.existsSync(path.join(corePath, 'dist', 'cjs'));
if (!hasEsm || !hasEsmEs5 || !hasCjs) {
throw new Error('core build is not a production build');
}
}
function publishGit(tasks, version, changelog) {
const tag = `v${version}`;
@@ -54,7 +84,7 @@ function publishGit(tasks, version, changelog) {
},
{
title: 'Push tags to remove',
task: () => execa('git', ['push', '--tags'], { cwd: common.rootDir })
task: () => execa('git', ['push', '--follow-tags'], { cwd: common.rootDir })
},
{
title: 'Publish Github release',

82
.scripts/test-dist.js Normal file
View File

@@ -0,0 +1,82 @@
const path = require('path');
const fs = require('fs');
// Test dist build:
// Double-triple check all the packages
// and files are good to go before publishing
[
// core
{
files: ['../core/dist/index.js', '../core/dist/ionic/index.esm.js']
},
// angular
{
files: ['../angular/dist/fesm5.cjs.js']
},
// react
{
files: ['../packages/react/dist/index.js']
},
// react-router
{
files: ['../packages/react-router/dist/index.js']
}
].forEach(testPackage);
function testPackage(testPkg) {
if (testPkg.packageJson) {
const pkgDir = path.dirname(testPkg.packageJson);
const pkgJson = require(testPkg.packageJson);
if (!pkgJson.name) {
throw new Error('missing package.json name: ' + testPkg.packageJson);
}
if (!pkgJson.main) {
throw new Error('missing package.json main: ' + testPkg.packageJson);
}
const pkgPath = path.join(pkgDir, pkgJson.main);
const pkgImport = require(pkgPath);
if (testPkg.files) {
if (!Array.isArray(pkgJson.files)) {
throw new Error(testPkg.packageJson + ' missing "files" property');
}
testPkg.files.forEach(testPkgFile => {
if (!pkgJson.files.includes(testPkgFile)) {
throw new Error(testPkg.packageJson + ' missing file ' + testPkgFile);
}
const filePath = path.join(__dirname, pkgDir, testPkgFile);
fs.accessSync(filePath);
});
}
if (pkgJson.module) {
const moduleIndex = path.join(__dirname, pkgDir, pkgJson.module);
fs.accessSync(moduleIndex);
}
if (pkgJson.types) {
const pkgTypes = path.join(__dirname, pkgDir, pkgJson.types);
fs.accessSync(pkgTypes);
}
if (testPkg.exports) {
testPkg.exports.forEach(exportName => {
const m = pkgImport[exportName];
if (!m) {
throw new Error('export "' + exportName + '" not found in: ' + testPkg.packageJson);
}
});
}
} else if (testPkg.files) {
testPkg.files.forEach(file => {
const filePath = path.join(__dirname, file);
fs.statSync(filePath);
});
}
}
console.log(`✅ test.dist`);

View File

@@ -1,3 +1,428 @@
## [4.11.13](https://github.com/ionic-team/ionic/compare/v4.11.12...v4.11.13) (2020-10-01)
### Bug Fixes
* **datetime:** do not set ampm when the column doesn't exist ([#22224](https://github.com/ionic-team/ionic/issues/22224)) ([210db5b](https://github.com/ionic-team/ionic/commit/210db5b265c04dcdc847f173503c5c096fdb3374))
## [4.11.12](https://github.com/ionic-team/ionic/compare/v4.11.11...v4.11.12) (2020-09-29)
### Bug Fixes
* **datetime:** remove the automatic switching from am to pm and vice versa ([#22208](https://github.com/ionic-team/ionic/issues/22208)) ([0d56c51](https://github.com/ionic-team/ionic/commit/0d56c5166497de38df9be432f8c7577b4b6c0e94)), closes [#18924](https://github.com/ionic-team/ionic/issues/18924)
## [4.11.11](https://github.com/ionic-team/ionic/compare/v4.11.0...v4.11.11) (2020-09-11)
### Bug Fixes
* **datetime:** do not reset to am when changing the hour and pm is set ([#22016](https://github.com/ionic-team/ionic/issues/22016)) ([1dac5a4](https://github.com/ionic-team/ionic/commit/1dac5a46f5e5adad9638e4e4e901bae1058c7287)), closes [#19175](https://github.com/ionic-team/ionic/issues/19175) [#19260](https://github.com/ionic-team/ionic/issues/19260) [#20026](https://github.com/ionic-team/ionic/issues/20026) [#16630](https://github.com/ionic-team/ionic/issues/16630)
## [4.11.10](https://github.com/ionic-team/ionic/compare/v4.11.9...v4.11.10) (2020-01-24)
### Bug Fixes
* **input:** revert previous type change ([db1fd1d](https://github.com/ionic-team/ionic/commit/db1fd1d72a8a0ade824ad2309d1adb2953731f37))
## [4.11.9](https://github.com/ionic-team/ionic/compare/v4.11.8...v4.11.9) (2020-01-23)
### Bug Fixes
* **core:** updating type of input value to accept numbers, fixes [#20173](https://github.com/ionic-team/ionic/issues/20173) ([#20267](https://github.com/ionic-team/ionic/issues/20267)) ([7080205](https://github.com/ionic-team/ionic/commit/708020551f9c51ca3b32d7b49bf4572db3dda12e))
* **react:** adding missing overlay component events, fixes [#19923](https://github.com/ionic-team/ionic/issues/19923) ([#20266](https://github.com/ionic-team/ionic/issues/20266)) ([ec6a8dd](https://github.com/ionic-team/ionic/commit/ec6a8dd86f3854edba367f79a6ebac7d60eed839))
* **react:** Don't render overlay children if isOpen is false, fixes [#20225](https://github.com/ionic-team/ionic/issues/20225) ([#20226](https://github.com/ionic-team/ionic/issues/20226)) ([aff9612](https://github.com/ionic-team/ionic/commit/aff9612d1197dca48eab6eff9d749032c380cf82))
* **react:** re attach props on update, fixes 20192 ([#20228](https://github.com/ionic-team/ionic/issues/20228)) ([9e35ebe](https://github.com/ionic-team/ionic/commit/9e35ebed4a1590ef2521f5f8c393bdd9dea32a04))
* **react:** remove leaving view when routerdirection is back, fixes [#20124](https://github.com/ionic-team/ionic/issues/20124) ([#20268](https://github.com/ionic-team/ionic/issues/20268)) ([63d4e87](https://github.com/ionic-team/ionic/commit/63d4e877fb18c90d70c4cbd5f66ffccb8ee6489c))
* **react:** support routes without a path for notfound routes, fixes [#20259](https://github.com/ionic-team/ionic/issues/20259) ([#20261](https://github.com/ionic-team/ionic/issues/20261)) ([2f8c13b](https://github.com/ionic-team/ionic/commit/2f8c13b6960f9bcfb941c36fa6e1742b96f80ba9))
* **react:** update icon types to be a string as well, fixes [#20229](https://github.com/ionic-team/ionic/issues/20229) ([#20230](https://github.com/ionic-team/ionic/issues/20230)) ([1411d8a](https://github.com/ionic-team/ionic/commit/1411d8a173bfefd7db5241218fd5641b7e9da823))
## [4.11.8](https://github.com/ionic-team/ionic/compare/v4.11.7...v4.11.8) (2020-01-13)
### Bug Fixes
* **react:** add missing react memory router ([8a5aba2](https://github.com/ionic-team/ionic/commit/8a5aba206865ce2af7f8bb85f4e7cd8dec37831d))
* **react:** fixing type of icon in ToastOptions, ActionSheetOptions, fixes [#20100](https://github.com/ionic-team/ionic/issues/20100) ([857bab6](https://github.com/ionic-team/ionic/commit/857bab66419a851c6d189cd1456cd67c1c2d934c))
* **react:** supporting ios and md props on icons ([#20170](https://github.com/ionic-team/ionic/issues/20170)) ([676cc19](https://github.com/ionic-team/ionic/commit/676cc19b89cd6374346aaac9cc3292872c7148fa))
## [4.11.7](https://github.com/ionic-team/ionic/compare/v4.11.6...v4.11.7) (2019-12-12)
### Bug Fixes
* **react:** fire lifecycle events on initial render, fixes [#20071](https://github.com/ionic-team/ionic/issues/20071) ([9ea75eb](https://github.com/ionic-team/ionic/commit/9ea75ebec7b1367fc0e319fe61c1f42516357e10))
## [4.11.6](https://github.com/ionic-team/ionic/compare/v4.11.5...v4.11.6) (2019-12-11)
### Bug Fixes
* **react:** don't show back button when not appropriate ([684293d](https://github.com/ionic-team/ionic/commit/684293ddbf1ad4edce590d56f7ff66fcd6c817a5))
* **react:** first render performance improvements ([1c7d1e5](https://github.com/ionic-team/ionic/commit/1c7d1e5cf1ad7e53ebbee2566e8fa89f567f7fb5))
* **react:** fix refs for controllers, overlays, ionpage, and ionrouteroutlet, fixes [#19924](https://github.com/ionic-team/ionic/issues/19924) ([#20012](https://github.com/ionic-team/ionic/issues/20012)) ([eef55bb](https://github.com/ionic-team/ionic/commit/eef55bb0072a9e54b1fd7d1c8c69e7fd43b2a5c5))
* **react:** support for 'root' router direction, fixes [#19982](https://github.com/ionic-team/ionic/issues/19982) ([#20052](https://github.com/ionic-team/ionic/issues/20052)) ([e116712](https://github.com/ionic-team/ionic/commit/e1167122758b23221935e897bcd65839b75c59aa))
* **react:** support navigating to same page and route updates in IonRouterOutlet, fixes [#19891](https://github.com/ionic-team/ionic/issues/19891), [#19892](https://github.com/ionic-team/ionic/issues/19892), [#19986](https://github.com/ionic-team/ionic/issues/19986) ([f9bf8db](https://github.com/ionic-team/ionic/commit/f9bf8dbe6f952ee53b6b213a4c0d043d25f49b93))
### Upgrade Note
If you run into a "Property 'translate' is missing in type" error building after updating to 4.11.6, update your React Typings library to the latest:
npm i @types/react@latest @types/react-dom@latest
## [4.11.5](https://github.com/ionic-team/ionic/compare/v4.11.0...v4.11.5) (2019-11-14)
### Bug Fixes
* **react:** improved lifecycle hooks to deal with stale closures, fixes [#19873](https://github.com/ionic-team/ionic/issues/19873) ([#19874](https://github.com/ionic-team/ionic/issues/19874)) ([5ff786a](https://github.com/ionic-team/ionic/commit/5ff786a23d5aa32281bbf5daaa7f8156de39caca))
## [4.11.4](https://github.com/ionic-team/ionic/compare/v4.11.1...v4.11.4) (2019-11-07)
### Bug Fixes
* **react:** check for component unmount, fixes [#19859](https://github.com/ionic-team/ionic/issues/19859) ([7356c40](https://github.com/ionic-team/ionic/commit/7356c401742ce2b3241d6ab05fce0fa65d2f1f8a))
* **react:** adding multiple subscriptions to lifecycle events, fixes [#19792](https://github.com/ionic-team/ionic/issues/19792) ([#19858](https://github.com/ionic-team/ionic/issues/19858)) ([0a3014d](https://github.com/ionic-team/ionic/commit/0a3014d35e2102570fd3d8c5ada29eb01aab18e9))
* **react:** add check to warn if no ionpage is found, fixes [#19832](https://github.com/ionic-team/ionic/issues/19832) ([#19857](https://github.com/ionic-team/ionic/issues/19857)) ([628e766](https://github.com/ionic-team/ionic/commit/628e76668ea72baebdb02b9dcfe24c0da837fb08))
* **react:** expand the location stack to better support back button, fixes [#19748](https://github.com/ionic-team/ionic/issues/19748) ([#19856](https://github.com/ionic-team/ionic/issues/19856)) ([d89508b](https://github.com/ionic-team/ionic/commit/d89508b1b58481d518b89362a8792d05f3f451c9))
* **react:** adding hardware back button support, fixes(19819) ([#19851](https://github.com/ionic-team/ionic/issues/19851)) ([fd9745d](https://github.com/ionic-team/ionic/commit/fd9745ddcddded76d64220838aef0f599bf4352f))
* **react:** adding swipe back functionality and routerOutlet ready improvements, fixes [#19818](https://github.com/ionic-team/ionic/issues/19818) ([#19849](https://github.com/ionic-team/ionic/issues/19849)) ([bcc40c8](https://github.com/ionic-team/ionic/commit/bcc40c8d59b723bbdb1dfd318bfb2219eb8df3cf))
* **react:** create a new overlay each time component is presented, fixes [#19841](https://github.com/ionic-team/ionic/issues/19841), [#19823](https://github.com/ionic-team/ionic/issues/19823) ([#19842](https://github.com/ionic-team/ionic/issues/19842)) ([9fad416](https://github.com/ionic-team/ionic/commit/9fad4161be4859969e14d4d33169ef022052d6bf))
## [4.11.3](https://github.com/ionic-team/ionic/compare/v4.11.1...v4.11.3) (2019-10-30)
### Bug Fixes
* **react:** adding change events to iontabs, fixes [#19665](https://github.com/ionic-team/ionic/issues/19665) ([#19711](https://github.com/ionic-team/ionic/issues/19711)) ([b7baf24](https://github.com/ionic-team/ionic/commit/b7baf24e5053a379156e6c3d82c2b5d3afa999f1))
* **react:** adding HashRouter to available ion routers, fixes [#19621](https://github.com/ionic-team/ionic/issues/19621) ([#19683](https://github.com/ionic-team/ionic/issues/19683)) ([fcdbb3c](https://github.com/ionic-team/ionic/commit/fcdbb3ce98747d3b37107904ca110daad95e48bc))
* **react:** checking if node is actually an element before treating it like one, fixes [#19769](https://github.com/ionic-team/ionic/issues/19769) ([#19783](https://github.com/ionic-team/ionic/issues/19783)) ([9d0caf6](https://github.com/ionic-team/ionic/commit/9d0caf6de070145c4af618847b27e24c49027b8e))
* **react:** checking isOpen again after async call before opening overlay, fixes [#19755](https://github.com/ionic-team/ionic/issues/19755) ([f70e71a](https://github.com/ionic-team/ionic/commit/f70e71a3d461cdab65626a5a7e1b6f4d03b852b1))
* **react:** don't remove current view, provide a better method to determine showGoBack fixes [#19731](https://github.com/ionic-team/ionic/issues/19731) and [#19732](https://github.com/ionic-team/ionic/issues/19732) ([31c754d](https://github.com/ionic-team/ionic/commit/31c754dab7ada494ff5f0026d5cf3f7f65198eff))
* **react:** removing pages from DOM on nav, fixes [#19701](https://github.com/ionic-team/ionic/issues/19701) ([#19712](https://github.com/ionic-team/ionic/issues/19712)) ([ee21d3a](https://github.com/ionic-team/ionic/commit/ee21d3ae43d8c6b076387a58bca655a56c920bcd))
* **react:** unmount leaving view when using browser back button, fixes [#19749](https://github.com/ionic-team/ionic/issues/19749) ([#19781](https://github.com/ionic-team/ionic/issues/19781)) ([2dc5540](https://github.com/ionic-team/ionic/commit/2dc554091056612f1bcd2751d6eeb41cae488751))
## [4.11.2](https://github.com/ionic-team/ionic/compare/v4.11.0...v4.11.2) (2019-10-21)
### Bug Fixes
* **animations:** ensure all elements are cleaned up when calling .destroy() ([#19654](https://github.com/ionic-team/ionic/issues/19654)) ([d97e167](https://github.com/ionic-team/ionic/commit/d97e167))
* **header:** collapsible header works in tabs ([#19658](https://github.com/ionic-team/ionic/issues/19658)) ([4853909](https://github.com/ionic-team/ionic/commit/4853909)), closes [#19640](https://github.com/ionic-team/ionic/issues/19640)
* **ios:** hide leaving view after nav transition to avoid flicker ([#19691](https://github.com/ionic-team/ionic/issues/19691)) ([70e0562](https://github.com/ionic-team/ionic/commit/70e0562)), closes [#19674](https://github.com/ionic-team/ionic/issues/19674)
* **menu:** clamp out of bounds swipe value ([#19684](https://github.com/ionic-team/ionic/issues/19684)) ([1535e95](https://github.com/ionic-team/ionic/commit/1535e95)), closes [#18927](https://github.com/ionic-team/ionic/issues/18927)
* **react:** add IonPicker as controller component, fixes [#19620](https://github.com/ionic-team/ionic/issues/19620) ([#19643](https://github.com/ionic-team/ionic/issues/19643)) ([ed98d9e](https://github.com/ionic-team/ionic/commit/ed98d9e))
* **react:** adding change events to IonTabs, fixes [#19665](https://github.com/ionic-team/ionic/issues/19665) ([#19711](https://github.com/ionic-team/ionic/issues/19711)) ([b7baf24](https://github.com/ionic-team/ionic/commit/b7baf24))
* **react:** adding HashRouter to available ion routers, fixes [#19621](https://github.com/ionic-team/ionic/issues/19621) ([#19683](https://github.com/ionic-team/ionic/issues/19683)) ([fcdbb3c](https://github.com/ionic-team/ionic/commit/fcdbb3c))
* **react:** pages no longer hidden when navigating between tabs, fixes [#19646](https://github.com/ionic-team/ionic/issues/19646) ([#19647](https://github.com/ionic-team/ionic/issues/19647)) ([8776556](https://github.com/ionic-team/ionic/commit/8776556))
* **react:** ensure views are removed from DOM after navigating back, fixes [#19701](https://github.com/ionic-team/ionic/issues/19701) ([#19712](https://github.com/ionic-team/ionic/issues/19712)) ([ee21d3a](https://github.com/ionic-team/ionic/commit/ee21d3a))
## [4.11.1](https://github.com/ionic-team/ionic/compare/v4.11.0...v4.11.1) (2019-10-14)
### Bug Fixes
* **build:** properly update peer dependencies ([#19639](https://github.com/ionic-team/ionic/issues/19639)) ([b552daa](https://github.com/ionic-team/ionic/commit/b552daa))
* **react:** add IonPicker as controller component, fixes [#19620](https://github.com/ionic-team/ionic/issues/19620) ([#19643](https://github.com/ionic-team/ionic/issues/19643)) ([ed98d9e](https://github.com/ionic-team/ionic/commit/ed98d9e))
* **react:** handle tab back nav better, fixes [#19646](https://github.com/ionic-team/ionic/issues/19646) ([#19647](https://github.com/ionic-team/ionic/issues/19647)) ([8776556](https://github.com/ionic-team/ionic/commit/8776556))
* **react:** moving tslint and friends to devDependencies ([#19624](https://github.com/ionic-team/ionic/issues/19624)) ([7f4b77d](https://github.com/ionic-team/ionic/commit/7f4b77d))
# [4.11.0 Sodium](https://github.com/ionic-team/ionic/compare/v4.10.3...v4.11.0) (2019-10-09)
Ionic React! Enjoy! 🧂 🌊 🐼
## [4.10.3](https://github.com/ionic-team/ionic/compare/v4.10.2...v4.10.3) (2019-10-09)
### Bug Fixes
* **content:** set overscroll only on iOS ([#19470](https://github.com/ionic-team/ionic/issues/19470)) ([63c2008](https://github.com/ionic-team/ionic/commit/63c2008a86de19847677fda7b9fedce73ed7669f)), closes [#19465](https://github.com/ionic-team/ionic/issues/19465)
* **searchbar:** update alignment of chips and other elements in toolbar ([#19596](https://github.com/ionic-team/ionic/issues/19596)) ([637f26b](https://github.com/ionic-team/ionic/commit/637f26b3642a266b6ef3b9d3d71b7327a5d3cc37)), closes [#19495](https://github.com/ionic-team/ionic/issues/19495) [#19502](https://github.com/ionic-team/ionic/issues/19502)
## [4.10.2](https://github.com/ionic-team/ionic/compare/v4.10.1...v4.10.2) (2019-10-08)
### Bug Fixes
* **overlay:** ensure lifecycle events fire properly ([#19579](https://github.com/ionic-team/ionic/issues/19579)) ([a7b9642](https://github.com/ionic-team/ionic/commit/a7b9642)), closes [#19576](https://github.com/ionic-team/ionic/issues/19576)
## [4.10.1](https://github.com/ionic-team/ionic/compare/v4.10.0...v4.10.1) (2019-10-07)
### Bug Fixes
* **animation:** animation timer fallback now accounts for iterations ([#19527](https://github.com/ionic-team/ionic/issues/19527)) ([9f5ed23](https://github.com/ionic-team/ionic/commit/9f5ed23))
* **css:** update deprecations to remove wrap ([#19535](https://github.com/ionic-team/ionic/issues/19535)) ([bfb704e](https://github.com/ionic-team/ionic/commit/bfb704e)), closes [#19499](https://github.com/ionic-team/ionic/issues/19499)
* **header:** fix collapsing iOS header when using with split pane ([#19480](https://github.com/ionic-team/ionic/issues/19480)) ([dea1c26](https://github.com/ionic-team/ionic/commit/dea1c26)), closes [#19541](https://github.com/ionic-team/ionic/issues/19541)
* **list:** add bottom border for first item in inset list ([#19525](https://github.com/ionic-team/ionic/issues/19525)) ([71b8853](https://github.com/ionic-team/ionic/commit/71b8853)), closes [#19507](https://github.com/ionic-team/ionic/issues/19507)
* **md:** fix flicker when navigating back in MD mode on certain Android devices ([#19553](https://github.com/ionic-team/ionic/issues/19553)) ([19ee21a](https://github.com/ionic-team/ionic/commit/19ee21a)), closes [#19491](https://github.com/ionic-team/ionic/issues/19491)
* **searchbar:** update padding and button alignment ([#19532](https://github.com/ionic-team/ionic/issues/19532)) ([77658e6](https://github.com/ionic-team/ionic/commit/77658e6)), closes [#19502](https://github.com/ionic-team/ionic/issues/19502)
# [4.10.0 Neon](https://github.com/ionic-team/ionic/compare/v4.9.1...v4.10.0) (2019-09-27)
### Bug Fixes
* **angular:** add warning if initialized more than once ([#19393](https://github.com/ionic-team/ionic/issues/19393)) ([e98769e](https://github.com/ionic-team/ionic/commit/e98769e))
* **animation:** set property defaults to avoid inconsistencies ([#19321](https://github.com/ionic-team/ionic/issues/19321)) ([1cbb52c](https://github.com/ionic-team/ionic/commit/1cbb52c))
* **animation:** fallback to CSS Animations on older versions of Chrome ([#19288](https://github.com/ionic-team/ionic/issues/19288)) ([2d39c07](https://github.com/ionic-team/ionic/commit/2d39c07)), closes [#19272](https://github.com/ionic-team/ionic/issues/19272)
* **animation:** animations of duration 0 now run in Safari ([#19287](https://github.com/ionic-team/ionic/issues/19287)) ([4e544f1](https://github.com/ionic-team/ionic/commit/4e544f1)), closes [#19285](https://github.com/ionic-team/ionic/issues/19285)
* **components:** fix crash in IE11 when using classList add() or remove() ([#19460](https://github.com/ionic-team/ionic/issues/19460)) ([b4d92c6](https://github.com/ionic-team/ionic/commit/b4d92c6))
* **components:** improve CSS Variable support in IE11 ([#19473](https://github.com/ionic-team/ionic/issues/19473)) ([44ad074](https://github.com/ionic-team/ionic/commit/44ad074))
* **content:** remove pointer-events from iOS transition shadow ([#19471](https://github.com/ionic-team/ionic/issues/19471)) ([8a52c7d](https://github.com/ionic-team/ionic/commit/8a52c7d)), closes [#19466](https://github.com/ionic-team/ionic/issues/19466)
* **menu:** menus show proper drop shadows ([#19454](https://github.com/ionic-team/ionic/issues/19454)) ([eab0865](https://github.com/ionic-team/ionic/commit/eab0865)), closes [#19387](https://github.com/ionic-team/ionic/issues/19387)
* **radio-group:** get radios before caching value to avoid infinite loop ([#19448](https://github.com/ionic-team/ionic/issues/19448)) ([cf223e4](https://github.com/ionic-team/ionic/commit/cf223e4)), closes [#19277](https://github.com/ionic-team/ionic/issues/19277)
* **react:** update events to use proper types ([c79e74b](https://github.com/ionic-team/ionic/commit/c79e74b))
* **router-outlet:** hide leaving view after transition finishes ([#19335](https://github.com/ionic-team/ionic/issues/19335)) ([bfa17d1](https://github.com/ionic-team/ionic/commit/bfa17d1))
### Features
* **config:** expose getMode() and deprecate Config.set() ([#19104](https://github.com/ionic-team/ionic/issues/19104)) ([0f05ea4](https://github.com/ionic-team/ionic/commit/0f05ea4))
* **docs:** add VSCode docs support ([#19309](https://github.com/ionic-team/ionic/issues/19309)) ([a3f345c](https://github.com/ionic-team/ionic/commit/a3f345c))
* **title:** add support for small title ([#19215](https://github.com/ionic-team/ionic/issues/19215)) ([e27962d](https://github.com/ionic-team/ionic/commit/e27962d)), closes [#18898](https://github.com/ionic-team/ionic/issues/18898)
* **title:** add support for large title (experimental) ([#19268](https://github.com/ionic-team/ionic/issues/19268)) ([923312e](https://github.com/ionic-team/ionic/commit/923312e)), closes [#16885](https://github.com/ionic-team/ionic/issues/16885)
### Performance Improvements
* **animation:** avoid ngzone with requestAnimationFrame ([#19457](https://github.com/ionic-team/ionic/issues/19457)) ([8ca97ce](https://github.com/ionic-team/ionic/commit/8ca97ce))
## [4.9.1](https://github.com/ionic-team/ionic/compare/v4.9.0...v4.9.1) (2019-09-16)
### Bug Fixes
* **platform:** properly detect iPads running iPadOS ([#19258](https://github.com/ionic-team/ionic/issues/19258)) ([4a90096](https://github.com/ionic-team/ionic/commit/4a90096))
# [4.9.0 Fluorine](https://github.com/ionic-team/ionic/compare/v4.8.1...v4.9.0) (2019-09-04)
### Bug Fixes
* **all:** allow elements to be reused once removed from the DOM ([#18963](https://github.com/ionic-team/ionic/pull/18963)) ([48a2763](https://github.com/ionic-team/ionic/commit/48a2763)), closes [#18843](https://github.com/ionic-team/ionic/issues/18843) [#17344](https://github.com/ionic-team/ionic/issues/17344) [#16453](https://github.com/ionic-team/ionic/issues/16453) [#15879](https://github.com/ionic-team/ionic/issues/15879) [#15788](https://github.com/ionic-team/ionic/issues/15788) [#15484](https://github.com/ionic-team/ionic/issues/15484) [#17890](https://github.com/ionic-team/ionic/issues/17890) [#16364](https://github.com/ionic-team/ionic/issues/16364)
* **animation:** add correct `onFinish` interface parameters ([#19199](https://github.com/ionic-team/ionic/issues/19199)) ([a81653b](https://github.com/ionic-team/ionic/commit/a81653b))
* **animation:** improve Web Animation feature detection accuracy ([#19212](https://github.com/ionic-team/ionic/issues/19212)) ([6eca5b0](https://github.com/ionic-team/ionic/commit/6eca5b0)), closes [#19205](https://github.com/ionic-team/ionic/issues/19205)
* **animation:** properly clean up elements when using `destroy` ([#19210](https://github.com/ionic-team/ionic/issues/19210)) ([93f2064](https://github.com/ionic-team/ionic/commit/93f2064))
* **segment:** do not emit ionChange until didLoad ([#19218](https://github.com/ionic-team/ionic/issues/19218)) ([9751f14](https://github.com/ionic-team/ionic/commit/9751f14)), closes [#19204](https://github.com/ionic-team/ionic/issues/19204)
### Features
* **nav-link:** add `nav-link` and deprecate `nav-push`, `nav-pop`, and `nav-set-root` ([#18909](https://github.com/ionic-team/ionic/issues/18909)) ([c3044f5](https://github.com/ionic-team/ionic/commit/c3044f5))
* **slides:** expose full Swiper API ([#19137](https://github.com/ionic-team/ionic/issues/19137)) ([e1fa461](https://github.com/ionic-team/ionic/commit/e1fa461))
## [4.8.1](https://github.com/ionic-team/ionic/compare/v4.8.0...v4.8.1) (2019-08-27)
### Bug Fixes
* **animation:** enable backwards compatibility for overlay animations ([#19160](https://github.com/ionic-team/ionic/issues/19160)) ([fb70980](https://github.com/ionic-team/ionic/commit/fb70980))
* **gesture:** account for negative step values with Web Animations ([#19196](https://github.com/ionic-team/ionic/issues/19196)) ([b3c7436](https://github.com/ionic-team/ionic/commit/b3c7436))
* **ios:** clear opacity on toolbar background after iOS transition ([#19169](https://github.com/ionic-team/ionic/issues/19169)) ([fa958a5](https://github.com/ionic-team/ionic/commit/fa958a5))
* **md:** set fill mode on MD transition to `both` ([#19161](https://github.com/ionic-team/ionic/issues/19161)) ([0e8ab49](https://github.com/ionic-team/ionic/commit/0e8ab49))
# [4.8.0 Oxygen](https://github.com/ionic-team/ionic/compare/v4.7.4...v4.8.0) (2019-08-21)
### Bug Fixes
* **alert:** apply styling to disabled items ([#18545](https://github.com/ionic-team/ionic/issues/18545)) ([67ed89d](https://github.com/ionic-team/ionic/commit/67ed89d))
* **platform:** properly detect Electron platform ([#19044](https://github.com/ionic-team/ionic/issues/19044)) ([e8cdda0](https://github.com/ionic-team/ionic/commit/e8cdda0)), closes [#19043](https://github.com/ionic-team/ionic/issues/19043)
* **toggle:** change background to use CSS variable ([#19012](https://github.com/ionic-team/ionic/issues/19012)) ([94e525c](https://github.com/ionic-team/ionic/commit/94e525c)), closes [#18940](https://github.com/ionic-team/ionic/issues/18940)
* **transition:** enable iOS transition shadow by default ([#19051](https://github.com/ionic-team/ionic/issues/19051)) ([a5d3c6b](https://github.com/ionic-team/ionic/commit/a5d3c6b))
### Features
* **animation:** add animation utility (experimental) ([#18918](https://github.com/ionic-team/ionic/issues/18918)) ([30ca46a](https://github.com/ionic-team/ionic/commit/30ca46a))
* **gesture:** add gesture utility (experimental) ([#18918](https://github.com/ionic-team/ionic/issues/18918)) ([30ca46a](https://github.com/ionic-team/ionic/commit/30ca46a))
* **searchbar:** add `inputmode` property ([#18980](https://github.com/ionic-team/ionic/issues/18980)) ([1187dc2](https://github.com/ionic-team/ionic/commit/1187dc2))
* **spinner:** add circular spinner for MD default ([#19052](https://github.com/ionic-team/ionic/issues/19052)) ([e33cf85](https://github.com/ionic-team/ionic/commit/e33cf85))
## [4.7.4](https://github.com/ionic-team/ionic/compare/v4.7.3...v4.7.4) (2019-08-07)
### Bug Fixes
* **core:** remove extra semicolons being rendered ([#19033](https://github.com/ionic-team/ionic/issues/19033)) ([39f0768](https://github.com/ionic-team/ionic/commit/39f0768))
## [4.7.3](https://github.com/ionic-team/ionic/compare/v4.7.2...v4.7.3) (2019-08-07)
* **core:** fix an issue with production builds of `@ionic/core`
## [4.7.2](https://github.com/ionic-team/ionic/compare/v4.7.1...v4.7.2) (2019-08-07)
### Bug Fixes
* **angular:** hardware back button subscribeWithPriority triggers change detection ([#18962](https://github.com/ionic-team/ionic/issues/18962)) ([3a22105](https://github.com/ionic-team/ionic/commit/3a22105)), closes [#18959](https://github.com/ionic-team/ionic/issues/18959)
* **angular:** nested inputs no longer conflict with each other ([#18976](https://github.com/ionic-team/ionic/issues/18976)) ([6bbdb80](https://github.com/ionic-team/ionic/commit/6bbdb80)), closes [#18248](https://github.com/ionic-team/ionic/issues/18248)
* **range:** ion-range value now submitted with form ([#19008](https://github.com/ionic-team/ionic/issues/19008)) ([8f7853c](https://github.com/ionic-team/ionic/commit/8f7853c))
* **reorder:** only move item if reorder happens ([#19007](https://github.com/ionic-team/ionic/issues/19007)) ([d237e80](https://github.com/ionic-team/ionic/commit/d237e80))
* **router:** partial swipe to go back gesture no longer breaks view([#18977](https://github.com/ionic-team/ionic/issues/18977)) ([713ea8a](https://github.com/ionic-team/ionic/commit/713ea8a)), closes [#18462](https://github.com/ionic-team/ionic/issues/18462)
* **toast:** allow loading ion-icon from asset path ([#18969](https://github.com/ionic-team/ionic/issues/18969)) ([23f327e](https://github.com/ionic-team/ionic/commit/23f327e))
* **vue:** rename swipeEnable to swipeGesture ([#17346](https://github.com/ionic-team/ionic/issues/17346)) ([c2348f7](https://github.com/ionic-team/ionic/commit/c2348f7)), closes [#16002](https://github.com/ionic-team/ionic/issues/16002)
## [4.7.1](https://github.com/ionic-team/ionic/compare/v4.7.0...v4.7.1) (2019-07-26)
### Bug Fixes
* **angular:** ensure change detection fires properly ([#18896](https://github.com/ionic-team/ionic/issues/18896)) ([962783b](https://github.com/ionic-team/ionic/commit/962783b)), closes [#18894](https://github.com/ionic-team/ionic/issues/18894)
# [4.7.0 Nitrogen](https://github.com/ionic-team/ionic/compare/v4.6.2...v4.7.0) (2019-07-24)
### Angular 8 Support
With this version comes support for Angular 8! Follow the below steps to update.
1. Update `@ionic/angular` and `@ionic/angular-toolkit` to the latest releases:
```shell
$ npm install @ionic/angular@4.7.0
$ npm install @ionic/angular-toolkit@2.0.0 -D
```
2. Update `@angular/core` and `@angular/cli`:
```shell
$ npx ng update @angular/core @angular/cli
```
3. Update `@angular-devkit` dependencies:
```shell
$ npm i @angular-devkit/architect@latest @angular-devkit/build-angular@latest @angular-devkit/core@latest @angular-devkit/schematics@latest
```
View our [Angular 8 Update Guide](https://docs.google.com/document/d/1QOpQeDifPSg6F9WycDLcbQnpqjN96ew-Ap0_CB7CcCQ/edit?usp=sharing) for tips on potential issues!
### Bug Fixes
* **angular:** copy input form classes to parent ion-item ([#18820](https://github.com/ionic-team/ionic/issues/18820)) ([53179c4](https://github.com/ionic-team/ionic/commit/53179c4)), closes [#18800](https://github.com/ionic-team/ionic/issues/18800)
* **angular:** add the swipeGesture method for enabling or disabling the ability to swipe open a menu ([#18806](https://github.com/ionic-team/ionic/issues/18806)) ([fbfc076](https://github.com/ionic-team/ionic/commit/fbfc076)), closes [#16002](https://github.com/ionic-team/ionic/issues/16002)
* **angular:** webview "pause", "resume", and "resize" events now trigger change detection ([#18853](https://github.com/ionic-team/ionic/issues/18853)) ([544e550](https://github.com/ionic-team/ionic/commit/544e550)), closes [#18831](https://github.com/ionic-team/ionic/issues/18831)
* **core:** apply translucent if backdrop-filter is supported ([#18832](https://github.com/ionic-team/ionic/issues/18832)) ([6b5a59d](https://github.com/ionic-team/ionic/commit/6b5a59d)), closes [ionic-team/ionic-docs#666](https://github.com/ionic-team/ionic-docs/issues/666)
* **datetime:** allow AM/PM to be changed ([#18684](https://github.com/ionic-team/ionic/issues/18684)) ([b7761fe](https://github.com/ionic-team/ionic/commit/b7761fe)), closes [#18585](https://github.com/ionic-team/ionic/issues/18585)
* **datetime:** properly apply disabled classes when updating columns ([#18875](https://github.com/ionic-team/ionic/issues/18875)) ([7ba718c](https://github.com/ionic-team/ionic/commit/7ba718c)), closes [#18793](https://github.com/ionic-team/ionic/issues/18793)
* **hardware-back-button:** hardware back button no longer erroneously restarts app ([#18794](https://github.com/ionic-team/ionic/issues/18794)) ([978cc39](https://github.com/ionic-team/ionic/commit/978cc39)), closes [#18792](https://github.com/ionic-team/ionic/issues/18792)
* **ripple-effect:** ensure ripple is removed from components after pointer release ([#18854](https://github.com/ionic-team/ionic/issues/18854)) ([71137a2](https://github.com/ionic-team/ionic/commit/71137a2)), closes [#18836](https://github.com/ionic-team/ionic/issues/18836)
* **searchbar:** add aria and role for improved accessibility ([#18797](https://github.com/ionic-team/ionic/issues/18797)) ([798103b](https://github.com/ionic-team/ionic/commit/798103b)), closes [#18796](https://github.com/ionic-team/ionic/issues/18796)
* **ssr:** avoid window reference ([#18865](https://github.com/ionic-team/ionic/issues/18865)) ([23ce6fa](https://github.com/ionic-team/ionic/commit/23ce6fa))
* **ssr:** check for client runtime method ([#18866](https://github.com/ionic-team/ionic/issues/18866)) ([c52b3b4](https://github.com/ionic-team/ionic/commit/c52b3b4))
* **textarea:** autogrow now resets textarea back to original number of rows when text is cleared ([#18822](https://github.com/ionic-team/ionic/issues/18822)) ([26e6d6f](https://github.com/ionic-team/ionic/commit/26e6d6f)), closes [#18744](https://github.com/ionic-team/ionic/issues/18744)
* **theming:** update components to use the proper colors for dark themes ([#18735](https://github.com/ionic-team/ionic/issues/18735)) ([045bc59](https://github.com/ionic-team/ionic/commit/045bc59)), closes [#18713](https://github.com/ionic-team/ionic/issues/18713)
* **virtual-scroll:** card rendering is no longer distorted ([#18877](https://github.com/ionic-team/ionic/issues/18877)) ([3ef6ecf](https://github.com/ionic-team/ionic/commit/3ef6ecf)), closes [#18870](https://github.com/ionic-team/ionic/issues/18870)
* **virtual-scroll:** element dimensions are recalculated on resize ([#18878](https://github.com/ionic-team/ionic/issues/18878)) ([c91819c](https://github.com/ionic-team/ionic/commit/c91819c))
### Features
* **core:** add support for Stackblitz ([#18846](https://github.com/ionic-team/ionic/issues/18846)) ([fb18f3b](https://github.com/ionic-team/ionic/commit/fb18f3b))
* **ssr:** add @ionic/core/hydrate app ([#18867](https://github.com/ionic-team/ionic/issues/18867)) ([815fa2e](https://github.com/ionic-team/ionic/commit/815fa2e))
* **navigation:** add experimental shadow to iOS page transitions ([#18695](https://github.com/ionic-team/ionic/issues/18695)) ([9b075ef](https://github.com/ionic-team/ionic/commit/9b075ef)), closes [#18661](https://github.com/ionic-team/ionic/issues/18661)
* **virtual-scroll:** adds headerHeight and footerHeight to help prevent flickering ([#18851](https://github.com/ionic-team/ionic/issues/18851)) ([0089111](https://github.com/ionic-team/ionic/commit/0089111)), closes [#17540](https://github.com/ionic-team/ionic/issues/17540)
### Performance
* **angular:** attach entering view before first change detection and detach leaving page ([#18821](https://github.com/ionic-team/ionic/issues/18821)) ([97fec92](https://github.com/ionic-team/ionic/commit/97fec92))
## [4.6.2](https://github.com/ionic-team/ionic/compare/v4.6.1...v4.6.2) (2019-07-10)
### Bug Fixes
* **menu-button:** hide menu button when auto hide or split pane ([#18702](https://github.com/ionic-team/ionic/issues/18702)) ([24840d4](https://github.com/ionic-team/ionic/commit/24840d4)), closes [#18666](https://github.com/ionic-team/ionic/issues/18666)
* **menu-button:** move font-size to host for easier customization ([#18699](https://github.com/ionic-team/ionic/issues/18699)) ([876ab41](https://github.com/ionic-team/ionic/commit/876ab41)), closes [#18667](https://github.com/ionic-team/ionic/issues/18667)
* **overlays:** fallback to step color if overlay background variable is unset ([#18709](https://github.com/ionic-team/ionic/issues/18709)) ([f16b118](https://github.com/ionic-team/ionic/commit/f16b118)), closes [#18658](https://github.com/ionic-team/ionic/issues/18658)
* **virtual-scroll:** remove runOutsideAngular error ([#18752](https://github.com/ionic-team/ionic/issues/18752)) ([8beeff2](https://github.com/ionic-team/ionic/commit/8beeff2)), closes [#18746](https://github.com/ionic-team/ionic/issues/18746)
* **vue:** update imports for types and ionicons ([f56fea6](https://github.com/ionic-team/ionic/commit/f56fea6)), closes [#18701](https://github.com/ionic-team/ionic/issues/18701)
### Performance Improvements
* **all:** minify better by using arrow functions ([#18730](https://github.com/ionic-team/ionic/issues/18730)) ([03c1d19](https://github.com/ionic-team/ionic/commit/03c1d19))
## [4.6.1](https://github.com/ionic-team/ionic/compare/v4.6.0...v4.6.1) (2019-07-09)
### Bug Fixes
* **app:** add hydrated to hide white screen with multiple ionic dependencies ([#18649](https://github.com/ionic-team/ionic/issues/18649))
* **datetime:** datetime no longer reports having a value if none is set ([#18541](https://github.com/ionic-team/ionic/issues/18541)) ([92e0f98](https://github.com/ionic-team/ionic/commit/92e0f98)), closes [#17979](https://github.com/ionic-team/ionic/issues/17979) [#18540](https://github.com/ionic-team/ionic/issues/18540)
* **fab-button:** set opacity on disabled fab button ([#18685](https://github.com/ionic-team/ionic/issues/18685)) ([6042b39](https://github.com/ionic-team/ionic/commit/6042b39)), closes [#18682](https://github.com/ionic-team/ionic/issues/18682)
* **icon:** load icons properly with baseHref ([#18650](https://github.com/ionic-team/ionic/issues/18650)), ([#18637](https://github.com/ionic-team/ionic/issues/18637))
* **icon:** bind icon name properly ([#18707](https://github.com/ionic-team/ionic/issues/18707))
* **infinite-scroll:** fix scroll listener ([0d58101](https://github.com/ionic-team/ionic/commit/0d58101))
* **item:** do not disable entire item if there are multiple inputs ([#18696](https://github.com/ionic-team/ionic/issues/18696)) ([dfa2b13](https://github.com/ionic-team/ionic/commit/dfa2b13)), closes [#18655](https://github.com/ionic-team/ionic/issues/18655) [#18670](https://github.com/ionic-team/ionic/issues/18670)
* **router-link:** add missing target prop ([#18659](https://github.com/ionic-team/ionic/issues/18659)) ([1f51ab2](https://github.com/ionic-team/ionic/commit/1f51ab2)), closes [#18655](https://github.com/ionic-team/ionic/issues/18655)
* **router-outlet:** fix swipe to go back ([b69fb69](https://github.com/ionic-team/ionic/commit/b69fb69))
* **scss:** copy all scss files ([36a58df](https://github.com/ionic-team/ionic/commit/36a58df))
* **searchbar:** proper styling after navigating ([#18642](https://github.com/ionic-team/ionic/issues/18642))
* **slides:** use correct order for pushing slides dynamically ([#18633](https://github.com/ionic-team/ionic/issues/18633))
* **tabs:** select proper tab by default and do not emit tab change if selectedTab is undefined ([03c834c](https://github.com/ionic-team/ionic/commit/03c834c))
* **overlay:** make create opts optional ([44c88ad](https://github.com/ionic-team/ionic/commit/44c88ad))
### Performance Improvements
* **angular:** skip zone ([e059fc8](https://github.com/ionic-team/ionic/commit/e059fc8))
# [4.6.0 Carbon](https://github.com/ionic-team/ionic/compare/v4.5.0...v4.6.0) (2019-06-26)

View File

@@ -13,7 +13,7 @@ Ionic is based on [Web Components](https://www.webcomponents.org/introduction) a
| **Core** | [`@ionic/core`](https://www.npmjs.com/package/@ionic/core) | [![version](https://img.shields.io/npm/v/@ionic/core/latest.svg)](https://www.npmjs.com/package/@ionic/core) | [`README.md`](core/README.md)
| **Angular** | [`@ionic/angular`](https://www.npmjs.com/package/@ionic/angular) | [![version](https://img.shields.io/npm/v/@ionic/angular/latest.svg)](https://www.npmjs.com/package/@ionic/angular) | [`README.md`](angular/README.md)
| **Vue** | [`@ionic/vue`](https://www.npmjs.com/package/@ionic/vue) | [![version](https://img.shields.io/npm/v/@ionic/vue/latest.svg)](https://www.npmjs.com/package/@ionic/vue) | [`README.md`](vue/README.md)
| **React** | [`@ionic/react`](https://www.npmjs.com/package/@ionic/react) | [![version](https://img.shields.io/npm/v/@ionic/react/latest.svg)](https://www.npmjs.com/package/@ionic/react) | [`README.md`](react/README.md)
| **React** | [`@ionic/react`](https://www.npmjs.com/package/@ionic/react) | [![version](https://img.shields.io/npm/v/@ionic/react/latest.svg)](https://www.npmjs.com/package/@ionic/react) | [`README.md`](packages/react/README.md)
Looking for the `ionic-angular` package? Ionic 3 has been moved to the [`ionic-v3`](https://github.com/ionic-team/ionic-v3) repo. See [Earlier Versions](#earlier-versions).

View File

@@ -62,7 +62,7 @@ A list of the breaking changes introduced to each component in Ionic Angular v4.
## Action Sheet
The `title`, `subTitle` and `enableBackdropDismiss` properties has been renamed to `header`, `subHeader` and `backdropDismiss` respectively.
The `title`, `subTitle` and `enableBackdropDismiss` properties have been renamed to `header`, `subHeader` and `backdropDismiss` respectively.
**Old Usage Example:**
@@ -89,7 +89,7 @@ await actionSheet.present();
## Alert
The `title`, `subTitle` and `enableBackdropDismiss` properties has been renamed to `header`, `subHeader` and `backdropDismiss` respectively.
The `title`, `subTitle` and `enableBackdropDismiss` properties have been renamed to `header`, `subHeader` and `backdropDismiss` respectively.
**Old Usage Example:**
@@ -498,7 +498,7 @@ The `<ion-fab>` container was previously placed inside of the fixed content by d
### Markup Changed
The Grid has been refactored in order to support css variables and a dynamic number of columns. The following column attributes have been changed.
The Grid has been refactored in order to support CSS variables and a dynamic number of columns. The following column attributes have been changed.
_In the following examples, `{breakpoint}` refers to the optional screen breakpoint (xs, sm, md, lg, xl) and `{value}` refers to the number of columns (`auto` or a number between `1` and `12`)._
@@ -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/content/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/master/src/content/layout/grid.md).
## Icon
@@ -1092,7 +1092,7 @@ openLoading() {
```javascript
async openLoading() {
let loading = this.loadingCtrl.create({
content: 'Loading...'
message: 'Loading...'
});
await loading.present();
@@ -1798,7 +1798,7 @@ To include the stylesheet for testing such as in a Plunker, Codepen, or anywhere
#### Production
To use the css in production, we recommend importing it into a global file, such as `app/global.scss`:
To use the CSS in production, we recommend importing it into a global file, such as `app/global.scss`:
```css
/** Basic CSS for Ionic Apps */

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/angular",
"version": "4.6.0",
"version": "4.11.13",
"description": "Angular specific wrappers for @ionic/core",
"keywords": [
"ionic",
@@ -19,6 +19,10 @@
"type": "git",
"url": "https://github.com/ionic-team/ionic.git"
},
"bugs": {
"url": "https://github.com/ionic-team/ionic/issues"
},
"homepage": "https://ionicframework.com/",
"scripts": {
"build": "npm run clean && npm run build.core && npm run build.ng && npm run clean-generated",
"build.core": "node scripts/build-core.js",
@@ -38,29 +42,29 @@
"validate": "npm i && npm run lint && npm run test && npm run build"
},
"module": "dist/fesm5.js",
"main": "dist/fesm5.js",
"main": "dist/fesm5.cjs.js",
"types": "dist/core.d.ts",
"files": [
"dist/",
"css/"
],
"dependencies": {
"@ionic/core": "4.6.0",
"@ionic/core": "4.11.13",
"tslib": "^1.9.3"
},
"peerDependencies": {
"@angular-devkit/core": "^7.2.1",
"@angular-devkit/schematics": "^7.2.1",
"@angular/core": "^7.2.1",
"@angular/common": "^7.2.1",
"@angular/forms": "^7.2.1",
"@angular/router": "^7.2.1",
"@angular/compiler": "^7.2.1",
"@angular/compiler-cli": "^7.2.1",
"@angular/platform-browser": "^7.2.1",
"@angular/platform-browser-dynamic": "^7.2.1",
"@angular-devkit/core": "7.2.1 - 8",
"@angular-devkit/schematics": "7.2.1 - 8",
"@angular/core": "7.2.1 - 8",
"@angular/common": "7.2.1 - 8",
"@angular/forms": "7.2.1 - 8",
"@angular/router": "7.2.1 - 8",
"@angular/compiler": "7.2.1 - 8",
"@angular/compiler-cli": "7.2.1 - 8",
"@angular/platform-browser": "7.2.1 - 8",
"@angular/platform-browser-dynamic": "7.2.1 - 8",
"rxjs": ">=6.2.0",
"zone.js": "^0.8.26"
"zone.js": ">=0.8.26"
},
"devDependencies": {
"@angular-devkit/core": "^7.2.1",
@@ -73,17 +77,17 @@
"@angular/platform-browser": "^7.2.1",
"@angular/platform-browser-dynamic": "^7.2.1",
"@angular/router": "^7.2.1",
"@types/node": "~10.12.0",
"@types/node": "~12.0.12",
"fs-extra": "^7.0.0",
"glob": "^7.1.3",
"rollup": "^1.1.2",
"rollup-plugin-node-resolve": "^4.0.0",
"rxjs": "^6.2.0",
"glob": "^7.1.4",
"rollup": "~1.17.0",
"rollup-plugin-node-resolve": "~5.2.0",
"rxjs": "^6.5.2",
"tsickle": "^0.34.0",
"tslint": "^5.12.1",
"tslint-ionic-rules": "0.0.21",
"typescript": "3.2.4",
"zone.js": "^0.8.28"
"typescript": "~3.2.2",
"zone.js": "~0.8.26"
},
"schematics": "./dist/schematics/collection.json"
}

View File

@@ -15,3 +15,7 @@
npm run build.link ../ionic-conference-app
When the command above is ran from the `angular` directory, it will build `@ionic/angular` and copy the `dist` directory to the correct location of another local project. In the example above, the end result is that it copies the `dist` directory to `../ionic-conference-app/node_modules/@ionic/angular/dist`. The path given should be relative to the root of this mono repo.
## package.json note
The `package.json` file in this directory references __Ionic 3__ and is in here to get GitHub to properly show the Used By counts on the repo. __Do not remove it!__

View File

@@ -1,12 +1,12 @@
const fs = require('fs-extra');
const path = require('path');
const ROOT_DIR = path.join(__dirname, '..');
const cleanDirs = [
'dist'
path.join(ROOT_DIR, 'dist')
];
cleanDirs.forEach(dir => {
const cleanDir = path.join(__dirname, '../', dir);
fs.removeSync(cleanDir);
fs.emptyDirSync(dir);
});

View File

@@ -0,0 +1,16 @@
{
"name": "ionic-angular",
"version": "`gulp package` generates dist/package.json from this template using the root ./package.json",
"description": "",
"keywords": [],
"repository": {
"type": "git",
"url": "https://github.com/ionic-team/ionic.git"
},
"license": "MIT",
"main": "umd/index.js",
"module": "index.js",
"es2015": "es2015/index.js",
"peerDependencies": {
}
}

View File

@@ -2,10 +2,12 @@ import resolve from 'rollup-plugin-node-resolve';
export default {
input: 'build/es2015/core.js',
output: {
file: 'dist/fesm2015.js',
format: 'es'
},
output: [
{
file: 'dist/fesm2015.js',
format: 'es'
}
],
external: (id) => {
// anything else is external
// Windows: C:\xxxxxx\xxx

View File

@@ -4,6 +4,15 @@ const newConfig = {
...config,
input: 'build/es5/core.js',
};
newConfig.output.file = 'dist/fesm5.js';
newConfig.output = [
{
file: 'dist/fesm5.js',
format: 'es'
},
{
file: 'dist/fesm5.cjs.js',
format: 'cjs'
}
];
export { newConfig as default };

View File

@@ -1,56 +1,45 @@
import { NgZone } from '@angular/core';
import { applyPolyfills, defineCustomElements } from '@ionic/core/loader';
import { Config } from './providers/config';
import { IonicWindow } from './types/interfaces';
import { raf } from './util/util';
export function appInitialize(config: Config, doc: Document) {
let didInitialize = false;
export const appInitialize = (config: Config, doc: Document, zone: NgZone) => {
return (): any => {
const win: IonicWindow | undefined = doc.defaultView as any;
if (win) {
if (didInitialize) {
console.warn('Ionic Angular was already initialized. Make sure IonicModule.forRoot() is just called once.');
}
didInitialize = true;
const Ionic = win.Ionic = win.Ionic || {};
Ionic.config = config;
Ionic.config = {
...config,
_zoneGate: (h: any) => zone.run(h)
};
const aelFn = '__zone_symbol__addEventListener' in (doc.body as any)
? '__zone_symbol__addEventListener'
: 'addEventListener';
return applyPolyfills().then(() => {
return defineCustomElements(win, {
exclude: ['ion-tabs', 'ion-tab'],
syncQueue: true,
raf: h => (win.__zone_symbol__requestAnimationFrame) ? win.__zone_symbol__requestAnimationFrame(h) : requestAnimationFrame(h),
raf,
jmp: (h: any) => zone.runOutsideAngular(h),
ael(elm, eventName, cb, opts) {
if ((elm as any).__zone_symbol__addEventListener && skipZone(eventName)) {
(elm as any).__zone_symbol__addEventListener(eventName, cb, opts);
} else {
elm.addEventListener(eventName, cb, opts);
}
(elm as any)[aelFn](eventName, cb, opts);
},
rel(elm, eventName, cb, opts) {
if ((elm as any).__zone_symbol__removeEventListener && skipZone(eventName)) {
(elm as any).__zone_symbol__removeEventListener(eventName, cb, opts);
} else {
elm.removeEventListener(eventName, cb, opts);
}
elm.removeEventListener(eventName, cb, opts);
}
});
});
}
};
}
const SKIP_ZONE = [
'scroll',
'resize',
'touchstart',
'touchmove',
'touchend',
'mousedown',
'mousemove',
'mouseup',
'ionStyle',
];
function skipZone(eventName: string) {
return SKIP_ZONE.indexOf(eventName) >= 0;
}
};

View File

@@ -25,8 +25,8 @@ export class BooleanValueAccessor extends ValueAccessor {
setIonicClasses(this.el);
}
@HostListener('ionChange', ['$event.target.checked'])
_handleIonChange(value: any) {
this.handleChangeEvent(value);
@HostListener('ionChange', ['$event.target'])
_handleIonChange(el: any) {
this.handleChangeEvent(el, el.checked);
}
}

View File

@@ -20,9 +20,9 @@ export class NumericValueAccessor extends ValueAccessor {
super(el);
}
@HostListener('ionChange', ['$event.target.value'])
_handleIonChange(value: any) {
this.handleChangeEvent(value);
@HostListener('ionChange', ['$event.target'])
_handleIonChange(el: any) {
this.handleChangeEvent(el, el.value);
}
registerOnChange(fn: (_: number | null) => void) {

View File

@@ -20,8 +20,8 @@ export class RadioValueAccessor extends ValueAccessor {
super(el);
}
@HostListener('ionSelect', ['$event.target.checked'])
_handleIonSelect(value: any) {
this.handleChangeEvent(value);
@HostListener('ionSelect', ['$event.target'])
_handleIonSelect(el: any) {
this.handleChangeEvent(el, el.checked);
}
}

View File

@@ -20,8 +20,8 @@ export class SelectValueAccessor extends ValueAccessor {
super(el);
}
@HostListener('ionChange', ['$event.target.value'])
_handleChangeEvent(value: any) {
this.handleChangeEvent(value);
@HostListener('ionChange', ['$event.target'])
_handleChangeEvent(el: any) {
this.handleChangeEvent(el, el.value);
}
}

View File

@@ -20,8 +20,8 @@ export class TextValueAccessor extends ValueAccessor {
super(el);
}
@HostListener('ionChange', ['$event.target.value'])
_handleInputEvent(value: any) {
this.handleChangeEvent(value);
@HostListener('ionChange', ['$event.target'])
_handleInputEvent(el: any) {
this.handleChangeEvent(el, el.value);
}
}

View File

@@ -1,6 +1,8 @@
import { ElementRef, HostListener } from '@angular/core';
import { ControlValueAccessor } from '@angular/forms';
import { raf } from '../../util/util';
export class ValueAccessor implements ControlValueAccessor {
private onChange: (value: any) => void = () => {/**/};
@@ -14,18 +16,22 @@ export class ValueAccessor implements ControlValueAccessor {
setIonicClasses(this.el);
}
handleChangeEvent(value: any) {
if (value !== this.lastValue) {
this.lastValue = value;
this.onChange(value);
handleChangeEvent(el: HTMLElement, value: any) {
if (el === this.el.nativeElement) {
if (value !== this.lastValue) {
this.lastValue = value;
this.onChange(value);
}
setIonicClasses(this.el);
}
setIonicClasses(this.el);
}
@HostListener('ionBlur')
_handleBlurEvent() {
this.onTouched();
setIonicClasses(this.el);
@HostListener('ionBlur', ['$event.target'])
_handleBlurEvent(el: any) {
if (el === this.el.nativeElement) {
this.onTouched();
setIonicClasses(this.el);
}
}
registerOnChange(fn: (value: any) => void) {
@@ -41,8 +47,8 @@ export class ValueAccessor implements ControlValueAccessor {
}
}
export function setIonicClasses(element: ElementRef) {
requestAnimationFrame(() => {
export const setIonicClasses = (element: ElementRef) => {
raf(() => {
const input = element.nativeElement as HTMLElement;
const classes = getClasses(input);
setClasses(input, classes);
@@ -52,9 +58,9 @@ export function setIonicClasses(element: ElementRef) {
setClasses(item, classes);
}
});
}
};
function getClasses(element: HTMLElement) {
const getClasses = (element: HTMLElement) => {
const classList = element.classList;
const classes = [];
for (let i = 0; i < classList.length; i++) {
@@ -64,22 +70,22 @@ function getClasses(element: HTMLElement) {
}
}
return classes;
}
};
function setClasses(element: HTMLElement, classes: string[]) {
const setClasses = (element: HTMLElement, classes: string[]) => {
const classList = element.classList;
classList.remove(
[
'ion-valid',
'ion-invalid',
'ion-touched',
'ion-untouched',
'ion-dirty',
'ion-pristine'
);
classList.add(...classes);
}
].forEach(c => classList.remove(c));
function startsWith(input: string, search: string): boolean {
classes.forEach(c => classList.add(c));
};
const startsWith = (input: string, search: string): boolean => {
return input.substr(0, search.length) === search;
}
};

View File

@@ -0,0 +1,134 @@
import { Directive, ElementRef } from '@angular/core';
@Directive({
selector: '[align-self-start], [align-self-end], [align-self-center], [align-self-stretch], [align-self-baseline], [align-self-auto], [wrap-reverse], [justify-content-start], [justify-content-center], [justify-content-end], [justify-content-around], [justify-content-between], [justify-content-evenly], [align-items-start], [align-items-center], [align-items-end], [align-items-stretch], [align-items-baseline], [float-left], [float-right], [float-start], [float-end], [float-sm-left], [float-sm-right], [float-sm-start], [float-sm-end], [float-md-left], [float-md-right], [float-md-start], [float-md-end], [float-lg-left], [float-lg-right], [float-lg-start], [float-lg-end], [float-xl-left], [float-xl-right], [float-xl-start], [float-xl-end], [text-center], [text-justify], [text-start], [text-end], [text-left], [text-right], [text-nowrap], [text-wrap], [text-sm-center], [text-sm-justify], [text-sm-start], [text-sm-end], [text-sm-left], [text-sm-right], [text-sm-nowrap], [text-sm-wrap], [text-md-center], [text-md-justify], [text-md-start], [text-md-end], [text-md-left], [text-md-right], [text-md-nowrap], [text-md-wrap], [text-lg-center], [text-lg-justify], [text-lg-start], [text-lg-end], [text-lg-left], [text-lg-right], [text-lg-nowrap], [text-lg-wrap], [text-xl-center], [text-xl-justify], [text-xl-start], [text-xl-end], [text-xl-left], [text-xl-right], [text-xl-nowrap], [text-xl-wrap], [text-uppercase], [text-lowercase], [text-capitalize], [text-sm-uppercase], [text-sm-lowercase], [text-sm-capitalize], [text-md-uppercase], [text-md-lowercase], [text-md-capitalize], [text-lg-uppercase], [text-lg-lowercase], [text-lg-capitalize], [text-xl-uppercase], [text-xl-lowercase], [text-xl-capitalize], [no-padding], [padding], [padding-top], [padding-bottom], [padding-start], [padding-end], [padding-vertical], [padding-horizontal], [no-margin], [margin], [margin-top], [margin-bottom], [margin-start], [margin-end], [margin-vertical], [margin-horizontal]',
})
export class CssUtilsDeprecations {
constructor(ref: ElementRef) {
const el = (ref.nativeElement as HTMLElement);
const attributes = Array.from(el.attributes)
.map(a => a.name)
.filter(n => DEPRECATED_ATTRIBUTES.includes(n));
if (attributes.length > 0) {
console.warn(`[DEPRECATED][CSS] Ionic CSS attributes are deprecated.
Replace:
'<${el.tagName.toLowerCase()} ${attributes.map(n => `${n}`).join(' ')}>'
With:
'<${el.tagName.toLowerCase()} class="${attributes.map(n => `ion-${n}`).join(' ')}">'
`);
}
}
}
const DEPRECATED_ATTRIBUTES = [
'align-self-start',
'align-self-end',
'align-self-center',
'align-self-stretch',
'align-self-baseline',
'align-self-auto',
'wrap-reverse',
'justify-content-start',
'justify-content-center',
'justify-content-end',
'justify-content-around',
'justify-content-between',
'justify-content-evenly',
'align-items-start',
'align-items-center',
'align-items-end',
'align-items-stretch',
'align-items-baseline',
'float-left',
'float-right',
'float-start',
'float-end',
'float-sm-left',
'float-sm-right',
'float-sm-start',
'float-sm-end',
'float-md-left',
'float-md-right',
'float-md-start',
'float-md-end',
'float-lg-left',
'float-lg-right',
'float-lg-start',
'float-lg-end',
'float-xl-left',
'float-xl-right',
'float-xl-start',
'float-xl-end',
'text-center',
'text-justify',
'text-start',
'text-end',
'text-left',
'text-right',
'text-nowrap',
'text-wrap',
'text-sm-center',
'text-sm-justify',
'text-sm-start',
'text-sm-end',
'text-sm-left',
'text-sm-right',
'text-sm-nowrap',
'text-sm-wrap',
'text-md-center',
'text-md-justify',
'text-md-start',
'text-md-end',
'text-md-left',
'text-md-right',
'text-md-nowrap',
'text-md-wrap',
'text-lg-center',
'text-lg-justify',
'text-lg-start',
'text-lg-end',
'text-lg-left',
'text-lg-right',
'text-lg-nowrap',
'text-lg-wrap',
'text-xl-center',
'text-xl-justify',
'text-xl-start',
'text-xl-end',
'text-xl-left',
'text-xl-right',
'text-xl-nowrap',
'text-xl-wrap',
'text-uppercase',
'text-lowercase',
'text-capitalize',
'text-sm-uppercase',
'text-sm-lowercase',
'text-sm-capitalize',
'text-md-uppercase',
'text-md-lowercase',
'text-md-capitalize',
'text-lg-uppercase',
'text-lg-lowercase',
'text-lg-capitalize',
'text-xl-uppercase',
'text-xl-lowercase',
'text-xl-capitalize',
'no-padding',
'padding',
'padding-top',
'padding-bottom',
'padding-start',
'padding-end',
'padding-vertical',
'padding-horizontal',
'no-margin',
'margin',
'margin-top',
'margin-bottom',
'margin-start',
'margin-end',
'margin-vertical',
'margin-horizontal'
];

View File

@@ -1,5 +1,5 @@
import { Location } from '@angular/common';
import { Attribute, ChangeDetectorRef, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, Injector, NgZone, OnDestroy, OnInit, Optional, Output, SkipSelf, ViewContainerRef } from '@angular/core';
import { Attribute, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, Injector, NgZone, OnDestroy, OnInit, Optional, Output, SkipSelf, ViewContainerRef } from '@angular/core';
import { ActivatedRoute, ChildrenOutletContexts, OutletContext, PRIMARY_OUTLET, Router } from '@angular/router';
import { BehaviorSubject, Observable } from 'rxjs';
import { distinctUntilChanged, filter, switchMap } from 'rxjs/operators';
@@ -57,7 +57,6 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
private resolver: ComponentFactoryResolver,
@Attribute('name') name: string,
@Optional() @Attribute('tabs') tabs: string,
private changeDetector: ChangeDetectorRef,
private config: Config,
private navCtrl: NavController,
commonLocation: Location,
@@ -210,8 +209,6 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
// Store references to the proxy by component
this.proxyMap.set(cmpRef.instance, activatedRouteProxy);
this.currentActivatedRoute$.next({ component: cmpRef.instance, activatedRoute });
this.changeDetector.markForCheck();
}
this.activatedView = enteringView;

View File

@@ -31,7 +31,7 @@ export class StackController {
createView(ref: ComponentRef<any>, activatedRoute: ActivatedRoute): RouteView {
const url = getUrl(this.router, activatedRoute);
const element = (ref && ref.location && ref.location.nativeElement) as HTMLElement;
const unlistenEvents = bindLifecycleEvents(ref.instance, element);
const unlistenEvents = bindLifecycleEvents(this.zone, ref.instance, element);
return {
id: this.nextId++,
stackId: computeStackId(this.tabsPrefix, url),
@@ -59,6 +59,7 @@ export class StackController {
direction = 'back';
animation = undefined;
}
const viewsSnapshot = this.views.slice();
let currentNavigation;
@@ -94,16 +95,36 @@ export class StackController {
}
}
const reused = this.views.includes(enteringView);
const views = this.insertView(enteringView, direction);
return this.wait(async () => {
await this.transition(enteringView, leavingView, animation, this.canGoBack(1), false);
await cleanupAsync(enteringView, views, viewsSnapshot, this.location);
return {
enteringView,
direction,
animation,
tabSwitch
};
// Trigger change detection before transition starts
// This will call ngOnInit() the first time too, just after the view
// was attached to the dom, but BEFORE the transition starts
if (!reused) {
enteringView.ref.changeDetectorRef.detectChanges();
}
// Wait until previous transitions finish
return this.zone.runOutsideAngular(() => {
return this.wait(() => {
// disconnect leaving page from change detection to
// reduce jank during the page transition
if (leavingView) {
leavingView.ref.changeDetectorRef.detach();
}
// In case the enteringView is the same as the leavingPage we need to reattach()
enteringView.ref.changeDetectorRef.reattach();
return this.transition(enteringView, leavingView, animation, this.canGoBack(1), false)
.then(() => cleanupAsync(enteringView, views, viewsSnapshot, this.location))
.then(() => ({
enteringView,
direction,
animation,
tabSwitch
}));
});
});
}
@@ -138,28 +159,30 @@ export class StackController {
});
}
async startBackTransition() {
startBackTransition() {
const leavingView = this.activeView;
if (leavingView) {
const views = this.getStack(leavingView.stackId);
const enteringView = views[views.length - 2];
enteringView.ref.changeDetectorRef.reattach();
await this.wait(() => {
return this.wait(() => {
return this.transition(
enteringView, // entering view
leavingView, // leaving view
'back',
true,
this.canGoBack(2),
true
);
});
}
return Promise.resolve();
}
endBackTransition(shouldComplete: boolean) {
if (shouldComplete) {
this.skipTransition = true;
this.pop(1);
} else if (this.activeView) {
cleanup(this.activeView, this.views, this.views, this.location);
}
}
@@ -189,7 +212,7 @@ export class StackController {
return this.views.slice();
}
private async transition(
private transition(
enteringView: RouteView | undefined,
leavingView: RouteView | undefined,
direction: 'forward' | 'back' | undefined,
@@ -198,26 +221,32 @@ export class StackController {
) {
if (this.skipTransition) {
this.skipTransition = false;
return;
return Promise.resolve(false);
}
if (leavingView === enteringView) {
return Promise.resolve(false);
}
const enteringEl = enteringView ? enteringView.element : undefined;
const leavingEl = leavingView ? leavingView.element : undefined;
const containerEl = this.containerEl;
if (enteringEl && enteringEl !== leavingEl) {
enteringEl.classList.add('ion-page', 'ion-page-invisible');
enteringEl.classList.add('ion-page');
enteringEl.classList.add('ion-page-invisible');
if (enteringEl.parentElement !== containerEl) {
containerEl.appendChild(enteringEl);
}
await containerEl.componentOnReady();
await containerEl.commit(enteringEl, leavingEl, {
deepWait: true,
duration: direction === undefined ? 0 : undefined,
direction,
showGoBack,
progressAnimation
});
if ((containerEl as any).commit) {
return containerEl.commit(enteringEl, leavingEl, {
deepWait: true,
duration: direction === undefined ? 0 : undefined,
direction,
showGoBack,
progressAnimation
});
}
}
return Promise.resolve(false);
}
private async wait<T>(task: () => Promise<T>): Promise<T> {
@@ -230,22 +259,24 @@ export class StackController {
}
}
function cleanupAsync(activeRoute: RouteView, views: RouteView[], viewsSnapshot: RouteView[], location: Location) {
return new Promise(resolve => {
requestAnimationFrame(() => {
cleanup(activeRoute, views, viewsSnapshot, location);
resolve();
const cleanupAsync = (activeRoute: RouteView, views: RouteView[], viewsSnapshot: RouteView[], location: Location) => {
if (typeof (requestAnimationFrame as any) === 'function') {
return new Promise<any>(resolve => {
requestAnimationFrame(() => {
cleanup(activeRoute, views, viewsSnapshot, location);
resolve();
});
});
});
}
}
return Promise.resolve();
};
function cleanup(activeRoute: RouteView, views: RouteView[], viewsSnapshot: RouteView[], location: Location) {
const cleanup = (activeRoute: RouteView, views: RouteView[], viewsSnapshot: RouteView[], location: Location) => {
viewsSnapshot
.filter(view => !views.includes(view))
.forEach(destroyView);
views.forEach(view => {
/**
* In the event that a user navigated multiple
* times in rapid succession, we want to make sure
@@ -265,4 +296,4 @@ function cleanup(activeRoute: RouteView, views: RouteView[], viewsSnapshot: Rout
view.ref.changeDetectorRef.detach();
}
});
}
};

View File

@@ -2,7 +2,7 @@ import { ComponentRef } from '@angular/core';
import { ActivatedRoute, NavigationExtras, Router } from '@angular/router';
import { NavDirection, RouterDirection } from '@ionic/core';
export function insertView(views: RouteView[], view: RouteView, direction: RouterDirection) {
export const insertView = (views: RouteView[], view: RouteView, direction: RouterDirection) => {
if (direction === 'root') {
return setRoot(views, view);
} else if (direction === 'forward') {
@@ -10,15 +10,15 @@ export function insertView(views: RouteView[], view: RouteView, direction: Route
} else {
return setBack(views, view);
}
}
};
function setRoot(views: RouteView[], view: RouteView) {
const setRoot = (views: RouteView[], view: RouteView) => {
views = views.filter(v => v.stackId !== view.stackId);
views.push(view);
return views;
}
};
function setForward(views: RouteView[], view: RouteView) {
const setForward = (views: RouteView[], view: RouteView) => {
const index = views.indexOf(view);
if (index >= 0) {
views = views.filter(v => v.stackId !== view.stackId || v.id <= view.id);
@@ -26,30 +26,30 @@ function setForward(views: RouteView[], view: RouteView) {
views.push(view);
}
return views;
}
};
function setBack(views: RouteView[], view: RouteView) {
const setBack = (views: RouteView[], view: RouteView) => {
const index = views.indexOf(view);
if (index >= 0) {
return views.filter(v => v.stackId !== view.stackId || v.id <= view.id);
} else {
return setRoot(views, view);
}
}
};
export function getUrl(router: Router, activatedRoute: ActivatedRoute) {
export const getUrl = (router: Router, activatedRoute: ActivatedRoute) => {
const urlTree = router.createUrlTree(['.'], { relativeTo: activatedRoute });
return router.serializeUrl(urlTree);
}
};
export function isTabSwitch(enteringView: RouteView, leavingView: RouteView | undefined) {
export const isTabSwitch = (enteringView: RouteView, leavingView: RouteView | undefined) => {
if (!leavingView) {
return true;
}
return enteringView.stackId !== leavingView.stackId;
}
};
export function computeStackId(prefixUrl: string[] | undefined, url: string) {
export const computeStackId = (prefixUrl: string[] | undefined, url: string) => {
if (!prefixUrl) {
return undefined;
}
@@ -63,22 +63,22 @@ export function computeStackId(prefixUrl: string[] | undefined, url: string) {
}
}
return undefined;
}
};
export function toSegments(path: string): string[] {
export const toSegments = (path: string) => {
return path
.split('/')
.map(s => s.trim())
.filter(s => s !== '');
}
};
export function destroyView(view: RouteView | undefined) {
export const destroyView = (view: RouteView | undefined) => {
if (view) {
// TODO lifecycle event
view.ref.destroy();
view.unlistenEvents();
}
}
};
export interface StackEvent {
enteringView: RouteView;

View File

@@ -43,6 +43,7 @@ d.IonApp,
d.IonMenuButton,
d.IonMenuToggle,
d.IonNav,
d.IonNavLink,
d.IonNavPop,
d.IonNavPush,
d.IonNavSetRoot,

View File

@@ -1,26 +1,28 @@
/* tslint:disable */
import { fromEvent } from 'rxjs';
export function proxyInputs(Cmp: any, inputs: string[]) {
export const proxyInputs = (Cmp: any, inputs: string[]) => {
const Prototype = Cmp.prototype;
inputs.forEach(item => {
Object.defineProperty(Prototype, item, {
get() { return this.el[item]; },
set(val: any) { this.el[item] = val; },
set(val: any) {
this.z.runOutsideAngular(() => this.el[item] = val);
},
});
});
}
};
export function proxyMethods(Cmp: any, methods: string[]) {
export const proxyMethods = (Cmp: any, methods: string[]) => {
const Prototype = Cmp.prototype;
methods.forEach(methodName => {
Prototype[methodName] = function() {
const args = arguments;
return this.el.componentOnReady().then((el: any) => el[methodName].apply(el, args));
return this.z.runOutsideAngular(() => this.el[methodName].apply(this.el, args));
};
});
}
};
export function proxyOutputs(instance: any, el: any, events: string[]) {
export const proxyOutputs = (instance: any, el: any, events: string[]) => {
events.forEach(eventName => instance[eventName] = fromEvent(el, eventName));
}
};

View File

@@ -1,15 +1,15 @@
/* tslint:disable */
/* auto-generated angular directive proxies */
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter } from '@angular/core';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, NgZone } from '@angular/core';
import { proxyInputs, proxyMethods, proxyOutputs } from './proxies-utils';
import { Components } from '@ionic/core'
import { Components } from '@ionic/core';
export declare interface IonApp extends Components.IonApp {}
@Component({ selector: 'ion-app', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>' })
export class IonApp {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -19,7 +19,7 @@ export declare interface IonAvatar extends Components.IonAvatar {}
@Component({ selector: 'ion-avatar', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>' })
export class IonAvatar {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -29,7 +29,7 @@ export declare interface IonBackButton extends Components.IonBackButton {}
@Component({ selector: 'ion-back-button', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'defaultHref', 'disabled', 'icon', 'mode', 'text', 'type'] })
export class IonBackButton {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -41,7 +41,7 @@ export declare interface IonBackdrop extends Components.IonBackdrop {}
export class IonBackdrop {
ionBackdropTap!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionBackdropTap']);
@@ -53,7 +53,7 @@ export declare interface IonBadge extends Components.IonBadge {}
@Component({ selector: 'ion-badge', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
export class IonBadge {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -66,7 +66,7 @@ export class IonButton {
ionFocus!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionFocus', 'ionBlur']);
@@ -75,20 +75,21 @@ export class IonButton {
proxyInputs(IonButton, ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'href', 'mode', 'rel', 'routerDirection', 'shape', 'size', 'strong', 'target', 'type']);
export declare interface IonButtons extends Components.IonButtons {}
@Component({ selector: 'ion-buttons', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>' })
@Component({ selector: 'ion-buttons', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['collapse'] })
export class IonButtons {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
}
proxyInputs(IonButtons, ['collapse']);
export declare interface IonCard extends Components.IonCard {}
@Component({ selector: 'ion-card', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['button', 'color', 'disabled', 'download', 'href', 'mode', 'rel', 'routerDirection', 'target', 'type'] })
export class IonCard {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -99,7 +100,7 @@ export declare interface IonCardContent extends Components.IonCardContent {}
@Component({ selector: 'ion-card-content', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['mode'] })
export class IonCardContent {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -110,7 +111,7 @@ export declare interface IonCardHeader extends Components.IonCardHeader {}
@Component({ selector: 'ion-card-header', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'translucent'] })
export class IonCardHeader {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -121,7 +122,7 @@ export declare interface IonCardSubtitle extends Components.IonCardSubtitle {}
@Component({ selector: 'ion-card-subtitle', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
export class IonCardSubtitle {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -132,7 +133,7 @@ export declare interface IonCardTitle extends Components.IonCardTitle {}
@Component({ selector: 'ion-card-title', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
export class IonCardTitle {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -146,7 +147,7 @@ export class IonCheckbox {
ionFocus!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionChange', 'ionFocus', 'ionBlur']);
@@ -158,7 +159,7 @@ export declare interface IonChip extends Components.IonChip {}
@Component({ selector: 'ion-chip', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'outline'] })
export class IonChip {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -169,7 +170,7 @@ export declare interface IonCol extends Components.IonCol {}
@Component({ selector: 'ion-col', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['offset', 'offsetLg', 'offsetMd', 'offsetSm', 'offsetXl', 'offsetXs', 'pull', 'pullLg', 'pullMd', 'pullSm', 'pullXl', 'pullXs', 'push', 'pushLg', 'pushMd', 'pushSm', 'pushXl', 'pushXs', 'size', 'sizeLg', 'sizeMd', 'sizeSm', 'sizeXl', 'sizeXs'] })
export class IonCol {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -183,7 +184,7 @@ export class IonContent {
ionScroll!: EventEmitter<CustomEvent>;
ionScrollEnd!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionScrollStart', 'ionScroll', 'ionScrollEnd']);
@@ -200,7 +201,7 @@ export class IonDatetime {
ionFocus!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionCancel', 'ionChange', 'ionFocus', 'ionBlur']);
@@ -213,7 +214,7 @@ export declare interface IonFab extends Components.IonFab {}
@Component({ selector: 'ion-fab', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['activated', 'edge', 'horizontal', 'vertical'] })
export class IonFab {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -227,7 +228,7 @@ export class IonFabButton {
ionFocus!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionFocus', 'ionBlur']);
@@ -239,7 +240,7 @@ export declare interface IonFabList extends Components.IonFabList {}
@Component({ selector: 'ion-fab-list', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['activated', 'side'] })
export class IonFabList {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -250,7 +251,7 @@ export declare interface IonFooter extends Components.IonFooter {}
@Component({ selector: 'ion-footer', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['mode', 'translucent'] })
export class IonFooter {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -261,7 +262,7 @@ export declare interface IonGrid extends Components.IonGrid {}
@Component({ selector: 'ion-grid', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['fixed'] })
export class IonGrid {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -269,21 +270,21 @@ export class IonGrid {
proxyInputs(IonGrid, ['fixed']);
export declare interface IonHeader extends Components.IonHeader {}
@Component({ selector: 'ion-header', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['mode', 'translucent'] })
@Component({ selector: 'ion-header', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['collapse', 'mode', 'translucent'] })
export class IonHeader {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
}
proxyInputs(IonHeader, ['mode', 'translucent']);
proxyInputs(IonHeader, ['collapse', 'mode', 'translucent']);
export declare interface IonIcon extends Components.IonIcon {}
@Component({ selector: 'ion-icon', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['ariaLabel', 'color', 'flipRtl', 'icon', 'ios', 'lazy', 'md', 'mode', 'name', 'size', 'src'] })
export class IonIcon {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -297,7 +298,7 @@ export class IonImg {
ionImgDidLoad!: EventEmitter<CustomEvent>;
ionError!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionImgWillLoad', 'ionImgDidLoad', 'ionError']);
@@ -310,7 +311,7 @@ export declare interface IonInfiniteScroll extends Components.IonInfiniteScroll
export class IonInfiniteScroll {
ionInfinite!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionInfinite']);
@@ -323,7 +324,7 @@ export declare interface IonInfiniteScrollContent extends Components.IonInfinite
@Component({ selector: 'ion-infinite-scroll-content', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['loadingSpinner', 'loadingText'] })
export class IonInfiniteScrollContent {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -338,7 +339,7 @@ export class IonInput {
ionBlur!: EventEmitter<CustomEvent>;
ionFocus!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionInput', 'ionChange', 'ionBlur', 'ionFocus']);
@@ -351,7 +352,7 @@ export declare interface IonItem extends Components.IonItem {}
@Component({ selector: 'ion-item', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['button', 'color', 'detail', 'detailIcon', 'disabled', 'download', 'href', 'lines', 'mode', 'rel', 'routerDirection', 'target', 'type'] })
export class IonItem {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -362,7 +363,7 @@ export declare interface IonItemDivider extends Components.IonItemDivider {}
@Component({ selector: 'ion-item-divider', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'sticky'] })
export class IonItemDivider {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -373,7 +374,7 @@ export declare interface IonItemGroup extends Components.IonItemGroup {}
@Component({ selector: 'ion-item-group', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>' })
export class IonItemGroup {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -383,7 +384,7 @@ export declare interface IonItemOption extends Components.IonItemOption {}
@Component({ selector: 'ion-item-option', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'disabled', 'download', 'expandable', 'href', 'mode', 'rel', 'target', 'type'] })
export class IonItemOption {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -395,7 +396,7 @@ export declare interface IonItemOptions extends Components.IonItemOptions {}
export class IonItemOptions {
ionSwipe!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionSwipe']);
@@ -408,7 +409,7 @@ export declare interface IonItemSliding extends Components.IonItemSliding {}
export class IonItemSliding {
ionDrag!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionDrag']);
@@ -421,7 +422,7 @@ export declare interface IonLabel extends Components.IonLabel {}
@Component({ selector: 'ion-label', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'position'] })
export class IonLabel {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -432,7 +433,7 @@ export declare interface IonList extends Components.IonList {}
@Component({ selector: 'ion-list', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['inset', 'lines', 'mode'] })
export class IonList {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -444,7 +445,7 @@ export declare interface IonListHeader extends Components.IonListHeader {}
@Component({ selector: 'ion-list-header', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
export class IonListHeader {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -459,7 +460,7 @@ export class IonMenu {
ionDidOpen!: EventEmitter<CustomEvent>;
ionDidClose!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionWillOpen', 'ionWillClose', 'ionDidOpen', 'ionDidClose']);
@@ -472,7 +473,7 @@ export declare interface IonMenuButton extends Components.IonMenuButton {}
@Component({ selector: 'ion-menu-button', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['autoHide', 'color', 'disabled', 'menu', 'type'] })
export class IonMenuButton {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -483,7 +484,7 @@ export declare interface IonMenuToggle extends Components.IonMenuToggle {}
@Component({ selector: 'ion-menu-toggle', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['autoHide', 'menu'] })
export class IonMenuToggle {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -496,7 +497,7 @@ export class IonNav {
ionNavWillChange!: EventEmitter<CustomEvent>;
ionNavDidChange!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionNavWillChange', 'ionNavDidChange']);
@@ -505,11 +506,22 @@ export class IonNav {
proxyMethods(IonNav, ['push', 'insert', 'insertPages', 'pop', 'popTo', 'popToRoot', 'removeIndex', 'setRoot', 'setPages', 'getActive', 'getByIndex', 'canGoBack', 'getPrevious']);
proxyInputs(IonNav, ['animated', 'animation', 'root', 'rootParams', 'swipeGesture']);
export declare interface IonNavLink extends Components.IonNavLink {}
@Component({ selector: 'ion-nav-link', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['component', 'componentProps', 'routerDirection'] })
export class IonNavLink {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
}
proxyInputs(IonNavLink, ['component', 'componentProps', 'routerDirection']);
export declare interface IonNavPop extends Components.IonNavPop {}
@Component({ selector: 'ion-nav-pop', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>' })
export class IonNavPop {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -519,7 +531,7 @@ export declare interface IonNavPush extends Components.IonNavPush {}
@Component({ selector: 'ion-nav-push', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['component', 'componentProps'] })
export class IonNavPush {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -530,7 +542,7 @@ export declare interface IonNavSetRoot extends Components.IonNavSetRoot {}
@Component({ selector: 'ion-nav-set-root', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['component', 'componentProps'] })
export class IonNavSetRoot {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -541,7 +553,7 @@ export declare interface IonNote extends Components.IonNote {}
@Component({ selector: 'ion-note', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
export class IonNote {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -552,7 +564,7 @@ export declare interface IonProgressBar extends Components.IonProgressBar {}
@Component({ selector: 'ion-progress-bar', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['buffer', 'color', 'mode', 'reversed', 'type', 'value'] })
export class IonProgressBar {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -566,7 +578,7 @@ export class IonRadio {
ionFocus!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionSelect', 'ionFocus', 'ionBlur']);
@@ -579,7 +591,7 @@ export declare interface IonRadioGroup extends Components.IonRadioGroup {}
export class IonRadioGroup {
ionChange!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionChange']);
@@ -594,7 +606,7 @@ export class IonRange {
ionFocus!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionChange', 'ionFocus', 'ionBlur']);
@@ -609,7 +621,7 @@ export class IonRefresher {
ionPull!: EventEmitter<CustomEvent>;
ionStart!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionRefresh', 'ionPull', 'ionStart']);
@@ -622,7 +634,7 @@ export declare interface IonRefresherContent extends Components.IonRefresherCont
@Component({ selector: 'ion-refresher-content', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['pullingIcon', 'pullingText', 'refreshingSpinner', 'refreshingText'] })
export class IonRefresherContent {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -633,7 +645,7 @@ export declare interface IonReorder extends Components.IonReorder {}
@Component({ selector: 'ion-reorder', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>' })
export class IonReorder {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -644,7 +656,7 @@ export declare interface IonReorderGroup extends Components.IonReorderGroup {}
export class IonReorderGroup {
ionItemReorder!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionItemReorder']);
@@ -657,7 +669,7 @@ export declare interface IonRippleEffect extends Components.IonRippleEffect {}
@Component({ selector: 'ion-ripple-effect', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['type'] })
export class IonRippleEffect {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -669,14 +681,14 @@ export declare interface IonRow extends Components.IonRow {}
@Component({ selector: 'ion-row', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>' })
export class IonRow {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
}
export declare interface IonSearchbar extends Components.IonSearchbar {}
@Component({ selector: 'ion-searchbar', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['animated', 'autocomplete', 'autocorrect', 'cancelButtonIcon', 'cancelButtonText', 'clearIcon', 'color', 'debounce', 'disabled', 'mode', 'placeholder', 'searchIcon', 'showCancelButton', 'spellcheck', 'type', 'value'] })
@Component({ selector: 'ion-searchbar', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['animated', 'autocomplete', 'autocorrect', 'cancelButtonIcon', 'cancelButtonText', 'clearIcon', 'color', 'debounce', 'disabled', 'inputmode', 'mode', 'placeholder', 'searchIcon', 'showCancelButton', 'spellcheck', 'type', 'value'] })
export class IonSearchbar {
ionInput!: EventEmitter<CustomEvent>;
ionChange!: EventEmitter<CustomEvent>;
@@ -685,25 +697,24 @@ export class IonSearchbar {
ionBlur!: EventEmitter<CustomEvent>;
ionFocus!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionInput', 'ionChange', 'ionCancel', 'ionClear', 'ionBlur', 'ionFocus']);
}
}
proxyMethods(IonSearchbar, ['setFocus', 'getInputElement']);
proxyInputs(IonSearchbar, ['animated', 'autocomplete', 'autocorrect', 'cancelButtonIcon', 'cancelButtonText', 'clearIcon', 'color', 'debounce', 'disabled', 'mode', 'placeholder', 'searchIcon', 'showCancelButton', 'spellcheck', 'type', 'value']);
proxyInputs(IonSearchbar, ['animated', 'autocomplete', 'autocorrect', 'cancelButtonIcon', 'cancelButtonText', 'clearIcon', 'color', 'debounce', 'disabled', 'inputmode', 'mode', 'placeholder', 'searchIcon', 'showCancelButton', 'spellcheck', 'type', 'value']);
export declare interface IonSegment extends Components.IonSegment {}
@Component({ selector: 'ion-segment', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'disabled', 'mode', 'scrollable', 'value'] })
export class IonSegment {
ionChange!: EventEmitter<CustomEvent>;
ionStyle!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionChange', 'ionStyle']);
proxyOutputs(this, this.el, ['ionChange']);
}
}
proxyInputs(IonSegment, ['color', 'disabled', 'mode', 'scrollable', 'value']);
@@ -713,7 +724,7 @@ export declare interface IonSegmentButton extends Components.IonSegmentButton {}
export class IonSegmentButton {
ionSelect!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionSelect']);
@@ -729,7 +740,7 @@ export class IonSelect {
ionFocus!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionChange', 'ionCancel', 'ionFocus', 'ionBlur']);
@@ -742,7 +753,7 @@ export declare interface IonSelectOption extends Components.IonSelectOption {}
@Component({ selector: 'ion-select-option', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['disabled', 'selected', 'value'] })
export class IonSelectOption {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -753,7 +764,7 @@ export declare interface IonSkeletonText extends Components.IonSkeletonText {}
@Component({ selector: 'ion-skeleton-text', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['animated', 'width'] })
export class IonSkeletonText {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -764,7 +775,7 @@ export declare interface IonSlide extends Components.IonSlide {}
@Component({ selector: 'ion-slide', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>' })
export class IonSlide {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -790,20 +801,20 @@ export class IonSlides {
ionSlideTouchStart!: EventEmitter<CustomEvent>;
ionSlideTouchEnd!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionSlidesDidLoad', 'ionSlideTap', 'ionSlideDoubleTap', 'ionSlideWillChange', 'ionSlideDidChange', 'ionSlideNextStart', 'ionSlidePrevStart', 'ionSlideNextEnd', 'ionSlidePrevEnd', 'ionSlideTransitionStart', 'ionSlideTransitionEnd', 'ionSlideDrag', 'ionSlideReachStart', 'ionSlideReachEnd', 'ionSlideTouchStart', 'ionSlideTouchEnd']);
}
}
proxyMethods(IonSlides, ['update', 'updateAutoHeight', 'slideTo', 'slideNext', 'slidePrev', 'getActiveIndex', 'getPreviousIndex', 'length', 'isEnd', 'isBeginning', 'startAutoplay', 'stopAutoplay', 'lockSwipeToNext', 'lockSwipeToPrev', 'lockSwipes']);
proxyMethods(IonSlides, ['update', 'updateAutoHeight', 'slideTo', 'slideNext', 'slidePrev', 'getActiveIndex', 'getPreviousIndex', 'length', 'isEnd', 'isBeginning', 'startAutoplay', 'stopAutoplay', 'lockSwipeToNext', 'lockSwipeToPrev', 'lockSwipes', 'getSwiper']);
proxyInputs(IonSlides, ['mode', 'options', 'pager', 'scrollbar']);
export declare interface IonSpinner extends Components.IonSpinner {}
@Component({ selector: 'ion-spinner', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'duration', 'name', 'paused'] })
export class IonSpinner {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -815,7 +826,7 @@ export declare interface IonSplitPane extends Components.IonSplitPane {}
export class IonSplitPane {
ionSplitPaneVisible!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionSplitPaneVisible']);
@@ -827,7 +838,7 @@ export declare interface IonTabBar extends Components.IonTabBar {}
@Component({ selector: 'ion-tab-bar', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'selectedTab', 'translucent'] })
export class IonTabBar {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -838,7 +849,7 @@ export declare interface IonTabButton extends Components.IonTabButton {}
@Component({ selector: 'ion-tab-button', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['disabled', 'download', 'href', 'layout', 'mode', 'rel', 'selected', 'tab', 'target'] })
export class IonTabButton {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -849,7 +860,7 @@ export declare interface IonText extends Components.IonText {}
@Component({ selector: 'ion-text', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
export class IonText {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
@@ -864,7 +875,7 @@ export class IonTextarea {
ionBlur!: EventEmitter<CustomEvent>;
ionFocus!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionChange', 'ionInput', 'ionBlur', 'ionFocus']);
@@ -877,22 +888,22 @@ export declare interface IonThumbnail extends Components.IonThumbnail {}
@Component({ selector: 'ion-thumbnail', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>' })
export class IonThumbnail {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
}
export declare interface IonTitle extends Components.IonTitle {}
@Component({ selector: 'ion-title', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color'] })
@Component({ selector: 'ion-title', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'size'] })
export class IonTitle {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
}
proxyInputs(IonTitle, ['color']);
proxyInputs(IonTitle, ['color', 'size']);
export declare interface IonToggle extends Components.IonToggle {}
@Component({ selector: 'ion-toggle', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['checked', 'color', 'disabled', 'mode', 'name', 'value'] })
@@ -901,7 +912,7 @@ export class IonToggle {
ionFocus!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionChange', 'ionFocus', 'ionBlur']);
@@ -913,7 +924,7 @@ export declare interface IonToolbar extends Components.IonToolbar {}
@Component({ selector: 'ion-toolbar', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
export class IonToolbar {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}

View File

@@ -1,5 +1,5 @@
import { ChangeDetectionStrategy, Component, ContentChild, ElementRef, EmbeddedViewRef, IterableDiffer, IterableDiffers, NgZone, SimpleChanges, TrackByFunction } from '@angular/core';
import { Cell, CellType, HeaderFn, ItemHeightFn } from '@ionic/core';
import { Cell, CellType, FooterHeightFn, HeaderFn, HeaderHeightFn, ItemHeightFn } from '@ionic/core';
import { proxyInputs, proxyMethods } from '../proxies-utils';
@@ -75,7 +75,7 @@ export declare interface IonVirtualScroll {
/**
* An optional function that maps each item within their height.
* When this function is provides, heavy optimizations and fast path can be taked by
* When this function is provided, heavy optimizations and fast path can be taked by
* `ion-virtual-scroll` leading to massive performance improvements.
*
* This function allows to skip all DOM reads, which can be Doing so leads
@@ -83,6 +83,16 @@ export declare interface IonVirtualScroll {
*/
itemHeight?: ItemHeightFn;
/**
* An optional function that maps each item header within their height.
*/
headerHeight?: HeaderHeightFn;
/**
* An optional function that maps each item footer within their height.
*/
footerHeight?: FooterHeightFn;
/**
* Same as `ngForTrackBy` which can be used on `ngFor`.
*/
@@ -114,6 +124,8 @@ export declare interface IonVirtualScroll {
'footerFn',
'items',
'itemHeight',
'headerHeight',
'footerHeight',
'trackBy'
]
})
@@ -128,7 +140,7 @@ export class IonVirtualScroll {
@ContentChild(VirtualFooter) ftrTmp!: VirtualFooter;
constructor(
private zone: NgZone,
private z: NgZone,
private iterableDiffers: IterableDiffers,
elementRef: ElementRef,
) {
@@ -162,7 +174,7 @@ export class IonVirtualScroll {
}
private nodeRender(el: HTMLElement | null, cell: Cell, index: number): HTMLElement {
return this.zone.run(() => {
return this.z.run(() => {
let node: EmbeddedViewRef<VirtualContext>;
if (!el) {
node = this.itmTmp.viewContainer.createEmbeddedView(
@@ -194,7 +206,7 @@ export class IonVirtualScroll {
}
}
function getElement(view: EmbeddedViewRef<VirtualContext>): HTMLElement {
const getElement = (view: EmbeddedViewRef<VirtualContext>): HTMLElement => {
const rootNodes = view.rootNodes;
for (let i = 0; i < rootNodes.length; i++) {
if (rootNodes[i].nodeType === 1) {
@@ -202,7 +214,7 @@ function getElement(view: EmbeddedViewRef<VirtualContext>): HTMLElement {
}
}
throw new Error('virtual element was not created');
}
};
proxyInputs(IonVirtualScroll, [
'approxItemHeight',
@@ -211,7 +223,9 @@ proxyInputs(IonVirtualScroll, [
'headerFn',
'footerFn',
'items',
'itemHeight'
'itemHeight',
'headerHeight',
'footerHeight'
]);
proxyMethods(IonVirtualScroll, [

View File

@@ -14,6 +14,7 @@ export { IonVirtualScroll } from './directives/virtual-scroll/virtual-scroll';
export { VirtualItem } from './directives/virtual-scroll/virtual-item';
export { VirtualHeader } from './directives/virtual-scroll/virtual-header';
export { VirtualFooter } from './directives/virtual-scroll/virtual-footer';
export { CssUtilsDeprecations } from './directives/css-utils-deprecations';
export * from './directives/proxies';
// PROVIDERS

View File

@@ -1,5 +1,5 @@
import { CommonModule, DOCUMENT } from '@angular/common';
import { APP_INITIALIZER, ModuleWithProviders, NgModule } from '@angular/core';
import { APP_INITIALIZER, ModuleWithProviders, NgModule, NgZone } from '@angular/core';
import { IonicConfig } from '@ionic/core';
import { appInitialize } from './app-initialize';
@@ -8,12 +8,13 @@ import { NumericValueAccessor } from './directives/control-value-accessors/numer
import { RadioValueAccessor } from './directives/control-value-accessors/radio-value-accessor';
import { SelectValueAccessor } from './directives/control-value-accessors/select-value-accessor';
import { TextValueAccessor } from './directives/control-value-accessors/text-value-accessor';
import { CssUtilsDeprecations } from './directives/css-utils-deprecations';
import { IonBackButtonDelegate } from './directives/navigation/ion-back-button';
import { IonRouterOutlet } from './directives/navigation/ion-router-outlet';
import { IonTabs } from './directives/navigation/ion-tabs';
import { NavDelegate } from './directives/navigation/nav-delegate';
import { RouterLinkDelegate } from './directives/navigation/router-link-delegate';
import { IonApp, IonAvatar, IonBackButton, IonBackdrop, IonBadge, IonButton, IonButtons, IonCard, IonCardContent, IonCardHeader, IonCardSubtitle, IonCardTitle, IonCheckbox, IonChip, IonCol, IonContent, IonDatetime, IonFab, IonFabButton, IonFabList, IonFooter, IonGrid, IonHeader, IonIcon, IonImg, IonInfiniteScroll, IonInfiniteScrollContent, IonInput, IonItem, IonItemDivider, IonItemGroup, IonItemOption, IonItemOptions, IonItemSliding, IonLabel, IonList, IonListHeader, IonMenu, IonMenuButton, IonMenuToggle, IonNav, IonNavPop, IonNavPush, IonNavSetRoot, IonNote, IonProgressBar, IonRadio, IonRadioGroup, IonRange, IonRefresher, IonRefresherContent, IonReorder, IonReorderGroup, IonRippleEffect, IonRow, IonSearchbar, IonSegment, IonSegmentButton, IonSelect, IonSelectOption, IonSkeletonText, IonSlide, IonSlides, IonSpinner, IonSplitPane, IonTabBar, IonTabButton, IonText, IonTextarea, IonThumbnail, IonTitle, IonToggle, IonToolbar } from './directives/proxies';
import { IonApp, IonAvatar, IonBackButton, IonBackdrop, IonBadge, IonButton, IonButtons, IonCard, IonCardContent, IonCardHeader, IonCardSubtitle, IonCardTitle, IonCheckbox, IonChip, IonCol, IonContent, IonDatetime, IonFab, IonFabButton, IonFabList, IonFooter, IonGrid, IonHeader, IonIcon, IonImg, IonInfiniteScroll, IonInfiniteScrollContent, IonInput, IonItem, IonItemDivider, IonItemGroup, IonItemOption, IonItemOptions, IonItemSliding, IonLabel, IonList, IonListHeader, IonMenu, IonMenuButton, IonMenuToggle, IonNav, IonNavLink, IonNavPop, IonNavPush, IonNavSetRoot, IonNote, IonProgressBar, IonRadio, IonRadioGroup, IonRange, IonRefresher, IonRefresherContent, IonReorder, IonReorderGroup, IonRippleEffect, IonRow, IonSearchbar, IonSegment, IonSegmentButton, IonSelect, IonSelectOption, IonSkeletonText, IonSlide, IonSlides, IonSpinner, IonSplitPane, IonTabBar, IonTabButton, IonText, IonTextarea, IonThumbnail, IonTitle, IonToggle, IonToolbar } from './directives/proxies';
import { VirtualFooter } from './directives/virtual-scroll/virtual-footer';
import { VirtualHeader } from './directives/virtual-scroll/virtual-header';
import { VirtualItem } from './directives/virtual-scroll/virtual-item';
@@ -66,6 +67,7 @@ const DECLARATIONS = [
IonMenuButton,
IonMenuToggle,
IonNav,
IonNavLink,
IonNavPop,
IonNavPush,
IonNavSetRoot,
@@ -118,7 +120,10 @@ const DECLARATIONS = [
VirtualFooter,
VirtualHeader,
VirtualItem,
IonVirtualScroll
IonVirtualScroll,
// Deprecations
CssUtilsDeprecations
];
@NgModule({
@@ -142,7 +147,8 @@ export class IonicModule {
multi: true,
deps: [
ConfigToken,
DOCUMENT
DOCUMENT,
NgZone
]
}
]

View File

@@ -34,10 +34,10 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
) {}
attachViewToDom(container: any, component: any, params?: any, cssClasses?: string[]): Promise<any> {
return new Promise(resolve => {
this.zone.run(() => {
return this.zone.run(() => {
return new Promise(resolve => {
const el = attachView(
this.resolver, this.injector, this.location, this.appRef,
this.zone, this.resolver, this.injector, this.location, this.appRef,
this.elRefMap, this.elEventsMap,
container, component, params, cssClasses
);
@@ -47,8 +47,8 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
}
removeViewFromDom(_container: any, component: any): Promise<void> {
return new Promise(resolve => {
this.zone.run(() => {
return this.zone.run(() => {
return new Promise(resolve => {
const componentRef = this.elRefMap.get(component);
if (componentRef) {
componentRef.destroy();
@@ -65,7 +65,8 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
}
}
export function attachView(
export const attachView = (
zone: NgZone,
resolver: ComponentFactoryResolver,
injector: Injector,
location: ViewContainerRef | undefined,
@@ -73,7 +74,7 @@ export function attachView(
elRefMap: WeakMap<HTMLElement, any>,
elEventsMap: WeakMap<HTMLElement, () => void>,
container: any, component: any, params: any, cssClasses: string[] | undefined
) {
) => {
const factory = resolver.resolveComponentFactory(component);
const childInjector = Injector.create({
providers: getProviders(params),
@@ -93,7 +94,7 @@ export function attachView(
hostElement.classList.add(clazz);
}
}
const unbindEvents = bindLifecycleEvents(instance, hostElement);
const unbindEvents = bindLifecycleEvents(zone, instance, hostElement);
container.appendChild(hostElement);
if (!location) {
@@ -103,7 +104,7 @@ export function attachView(
elRefMap.set(hostElement, componentRef);
elEventsMap.set(hostElement, unbindEvents);
return hostElement;
}
};
const LIFECYCLES = [
LIFECYCLE_WILL_ENTER,
@@ -113,26 +114,22 @@ const LIFECYCLES = [
LIFECYCLE_WILL_UNLOAD
];
export function bindLifecycleEvents(instance: any, element: HTMLElement) {
const unregisters = LIFECYCLES.map(eventName => {
const handler = (ev: any) => {
if (typeof instance[eventName] === 'function') {
instance[eventName](ev.detail);
}
};
element.addEventListener(eventName, handler);
return () => {
element.removeEventListener(eventName, handler);
};
export const bindLifecycleEvents = (zone: NgZone, instance: any, element: HTMLElement) => {
return zone.run(() => {
const unregisters = LIFECYCLES
.filter(eventName => typeof instance[eventName] === 'function')
.map(eventName => {
const handler = (ev: any) => instance[eventName](ev.detail);
element.addEventListener(eventName, handler);
return () => element.removeEventListener(eventName, handler);
});
return () => unregisters.forEach(fn => fn());
});
return () => {
unregisters.forEach(fn => fn());
};
}
};
const NavParamsToken = new InjectionToken<any>('NavParamsToken');
function getProviders(params: {[key: string]: any}) {
const getProviders = (params: {[key: string]: any}) => {
return [
{
provide: NavParamsToken, useValue: params
@@ -141,8 +138,8 @@ function getProviders(params: {[key: string]: any}) {
provide: NavParams, useFactory: provideNavParamsInjectable, deps: [NavParamsToken]
}
];
}
};
function provideNavParamsInjectable(params: {[key: string]: any}) {
const provideNavParamsInjectable = (params: {[key: string]: any}) => {
return new NavParams(params);
}
};

View File

@@ -33,6 +33,7 @@ export class Config {
}
set(key: keyof IonicConfig, value?: any) {
console.warn(`[DEPRECATION][Config]: The Config.set() method is deprecated and will be removed in Ionic Framework 6.0. Please see https://ionicframework.com/docs/angular/config for alternatives.`);
const c = getConfig();
if (c) {
c.set(key, value);
@@ -42,12 +43,12 @@ export class Config {
export const ConfigToken = new InjectionToken<any>('USERCONFIG');
function getConfig(): CoreConfig | null {
const getConfig = (): CoreConfig | null => {
if (typeof (window as any) !== 'undefined') {
const Ionic = (window as IonicWindow).Ionic;
const Ionic = (window as any as IonicWindow).Ionic;
if (Ionic && Ionic.config) {
return Ionic.config;
}
}
return null;
}
};

View File

@@ -22,7 +22,7 @@ export class DomController {
}
}
function getQueue() {
const getQueue = () => {
const win = typeof (window as any) !== 'undefined' ? window : null as any;
if (win != null) {
@@ -41,6 +41,6 @@ function getQueue() {
read: (cb: any) => cb(),
write: (cb: any) => cb()
};
}
};
export type RafCallback = (timeStamp?: number) => void;

View File

@@ -7,6 +7,11 @@ export type EventHandler = (...args: any[]) => any;
export class Events {
private c = new Map<string, EventHandler[]>();
constructor() {
console.warn(`[DEPRECATION][Events]: The Events provider is deprecated and it will be removed in the next major release.
- Use "Observables" for a similar pub/sub architecture: https://angular.io/guide/observables
- Use "Redux" for advanced state management: https://ngrx.io`);
}
/**
* Subscribe to an event topic. Events that get posted to that topic will trigger the provided handler.
*

View File

@@ -1,24 +1,18 @@
import { DOCUMENT } from '@angular/common';
import { Inject, Injectable } from '@angular/core';
import { Injectable } from '@angular/core';
import { menuController } from '@ionic/core';
import { proxyMethod } from '../util/util';
const CTRL = 'ion-menu-controller';
@Injectable({
providedIn: 'root',
})
export class MenuController {
constructor(@Inject(DOCUMENT) private doc: any) {
}
/**
* Programmatically open the Menu.
* @param [menuId] Optionally get the menu by its id, or side.
* @return returns a promise when the menu is fully opened
*/
open(menuId?: string): Promise<boolean> {
return proxyMethod(CTRL, this.doc, 'open', menuId);
open(menuId?: string) {
return menuController.open(menuId);
}
/**
@@ -28,8 +22,8 @@ export class MenuController {
* @param [menuId] Optionally get the menu by its id, or side.
* @return returns a promise when the menu is fully closed
*/
close(menuId?: string): Promise<boolean> {
return proxyMethod(CTRL, this.doc, 'close', menuId);
close(menuId?: string) {
return menuController.close(menuId);
}
/**
@@ -38,8 +32,8 @@ export class MenuController {
* @param [menuId] Optionally get the menu by its id, or side.
* @return returns a promise when the menu has been toggled
*/
toggle(menuId?: string): Promise<boolean> {
return proxyMethod(CTRL, this.doc, 'toggle', menuId);
toggle(menuId?: string) {
return menuController.toggle(menuId);
}
/**
@@ -50,8 +44,20 @@ export class MenuController {
* @param [menuId] Optionally get the menu by its id, or side.
* @return Returns the instance of the menu, which is useful for chaining.
*/
enable(shouldEnable: boolean, menuId?: string): Promise<HTMLIonMenuElement> {
return proxyMethod(CTRL, this.doc, 'enable', shouldEnable, menuId);
enable(shouldEnable: boolean, menuId?: string) {
return menuController.enable(shouldEnable, menuId);
}
/**
* Used to enable or disable the ability to swipe open the menu.
* @param shouldEnable True if it should be swipe-able, false if not.
* @param [menuId] Optionally get the menu by its id, or side.
* @return Returns the instance of the menu, which is useful for chaining.
* @deprecated Use swipeGesture() instead.
*/
swipeEnable(shouldEnable: boolean, menuId?: string) {
console.warn('[DEPRECATED][ion-menu-controller] swipeEnable() is deprecated. Use MenuController.swipeGesture() instead');
return this.swipeGesture(shouldEnable, menuId);
}
/**
@@ -60,8 +66,8 @@ export class MenuController {
* @param [menuId] Optionally get the menu by its id, or side.
* @return Returns the instance of the menu, which is useful for chaining.
*/
swipeEnable(shouldEnable: boolean, menuId?: string): Promise<HTMLIonMenuElement> {
return proxyMethod(CTRL, this.doc, 'swipeEnable', shouldEnable, menuId);
swipeGesture(shouldEnable: boolean, menuId?: string) {
return menuController.swipeGesture(shouldEnable, menuId);
}
/**
@@ -69,16 +75,16 @@ export class MenuController {
* @return Returns true if the specified menu is currently open, otherwise false.
* If the menuId is not specified, it returns true if ANY menu is currenly open.
*/
isOpen(menuId?: string): Promise<boolean> {
return proxyMethod(CTRL, this.doc, 'isOpen', menuId);
isOpen(menuId?: string) {
return menuController.isOpen(menuId);
}
/**
* @param [menuId] Optionally get the menu by its id, or side.
* @return Returns true if the menu is currently enabled, otherwise false.
*/
isEnabled(menuId?: string): Promise<boolean> {
return proxyMethod(CTRL, this.doc, 'isEnabled', menuId);
isEnabled(menuId?: string) {
return menuController.isEnabled(menuId);
}
/**
@@ -90,21 +96,21 @@ export class MenuController {
* @param [menuId] Optionally get the menu by its id, or side.
* @return Returns the instance of the menu if found, otherwise `null`.
*/
get(menuId?: string): Promise<HTMLIonMenuElement> {
return proxyMethod(CTRL, this.doc, 'get', menuId);
get(menuId?: string) {
return menuController.get(menuId);
}
/**
* @return Returns the instance of the menu already opened, otherwise `null`.
*/
getOpen(): Promise<HTMLIonMenuElement> {
return proxyMethod(CTRL, this.doc, 'getOpen');
getOpen() {
return menuController.getOpen();
}
/**
* @return Returns an array of all menu instances.
*/
getMenus(): Promise<HTMLIonMenuElement[]> {
return proxyMethod(CTRL, this.doc, 'getMenus');
getMenus() {
return menuController.getMenus();
}
}

View File

@@ -50,12 +50,12 @@ export class NavController {
/**
* This method uses Angular's [Router](https://angular.io/api/router/Router) under the hood,
* it's equivalent to call `this.router.navigateByUrl()`, but it's explicit about the **direction** of the transition.
* it's equivalent to calling `this.router.navigateByUrl()`, but it's explicit about the **direction** of the transition.
*
* Going **forward** means that a new page it's going to be pushed to the stack of the outlet (ion-router-outlet),
* Going **forward** means that a new page is going to be pushed to the stack of the outlet (ion-router-outlet),
* and that it will show a "forward" animation by default.
*
* Navigating forward can also be trigger in a declarative manner by using the `[routerDirection]` directive:
* Navigating forward can also be triggered in a declarative manner by using the `[routerDirection]` directive:
*
* ```html
* <a routerLink="/path/to/page" routerDirection="forward">Link</a>
@@ -68,17 +68,17 @@ export class NavController {
/**
* This method uses Angular's [Router](https://angular.io/api/router/Router) under the hood,
* it's equivalent to call:
* it's equivalent to calling:
*
* ```ts
* this.navController.setDirection('back');
* this.router.navigateByUrl(path);
* ```
*
* Going **back** means that all the pages in the stack until the navigated page is found will be pop,
* Going **back** means that all the pages in the stack until the navigated page is found will be popped,
* and that it will show a "back" animation by default.
*
* Navigating back can also be trigger in a declarative manner by using the `[routerDirection]` directive:
* Navigating back can also be triggered in a declarative manner by using the `[routerDirection]` directive:
*
* ```html
* <a routerLink="/path/to/page" routerDirection="back">Link</a>
@@ -91,7 +91,7 @@ export class NavController {
/**
* This method uses Angular's [Router](https://angular.io/api/router/Router) under the hood,
* it's equivalent to call:
* it's equivalent to calling:
*
* ```ts
* this.navController.setDirection('root');
@@ -101,7 +101,7 @@ export class NavController {
* Going **root** means that all existing pages in the stack will be removed,
* and the navigated page will become the single page in the stack.
*
* Navigating root can also be trigger in a declarative manner by using the `[routerDirection]` directive:
* Navigating root can also be triggered in a declarative manner by using the `[routerDirection]` directive:
*
* ```html
* <a routerLink="/path/to/page" routerDirection="root">Link</a>
@@ -114,7 +114,8 @@ export class NavController {
/**
* Same as [Location](https://angular.io/api/common/Location)'s back() method.
* It will use the standard `window.history.back()` under the hood, but featuring a `back` animation.
* It will use the standard `window.history.back()` under the hood, but featuring a `back` animation
* by default.
*/
back(options: AnimationOptions = { animated: true, animationDirection: 'back' }) {
this.setDirection('back', options.animated, options.animationDirection);
@@ -122,9 +123,9 @@ export class NavController {
}
/**
* This methods goes back in the context of ionic's stack navigation.
* This methods goes back in the context of Ionic's stack navigation.
*
* It recursivelly finds the top active `ion-router-outlet` and calls `pop()`.
* It recursively finds the top active `ion-router-outlet` and calls `pop()`.
* This is the recommended way to go back when you are using `ion-router-outlet`.
*/
async pop() {
@@ -140,11 +141,11 @@ export class NavController {
}
/**
* This methods specifies the direction of the next navigation performed by the angular router.
* This methods specifies the direction of the next navigation performed by the Angular router.
*
* `setDirection()` does not trigger any transition, it just sets a set of flags to be consumed by `ion-router-outlet`.
* `setDirection()` does not trigger any transition, it just sets some flags to be consumed by `ion-router-outlet`.
*
* It's recommended to use `navigateForward()`, `navigateBack()` and `navigateBack()` instead of `setDirection()`.
* It's recommended to use `navigateForward()`, `navigateBack()` and `navigateRoot()` instead of `setDirection()`.
*/
setDirection(direction: RouterDirection, animated?: boolean, animationDirection?: 'forward' | 'back') {
this.direction = direction;
@@ -212,7 +213,7 @@ export class NavController {
}
}
function getAnimation(direction: RouterDirection, animated: boolean | undefined, animationDirection: 'forward' | 'back' | undefined): NavDirection | undefined {
const getAnimation = (direction: RouterDirection, animated: boolean | undefined, animationDirection: 'forward' | 'back' | undefined): NavDirection | undefined => {
if (animated === false) {
return undefined;
}
@@ -225,7 +226,7 @@ function getAnimation(direction: RouterDirection, animated: boolean | undefined,
return 'forward';
}
return undefined;
}
};
const DEFAULT_DIRECTION = 'auto';
const DEFAULT_ANIMATED = undefined;

View File

@@ -1,5 +1,5 @@
import { DOCUMENT } from '@angular/common';
import { Inject, Injectable } from '@angular/core';
import { Inject, Injectable, NgZone } from '@angular/core';
import { BackButtonEventDetail, Platforms, getPlatforms, isPlatform } from '@ionic/core';
import { Subject, Subscription } from 'rxjs';
@@ -42,29 +42,30 @@ export class Platform {
*/
resize = new Subject<void>();
constructor(@Inject(DOCUMENT) private doc: any) {
this.win = doc.defaultView;
constructor(@Inject(DOCUMENT) private doc: any, zone: NgZone) {
zone.run(() => {
this.win = doc.defaultView;
this.backButton.subscribeWithPriority = function(priority, callback) {
return this.subscribe(ev => (
ev.register(priority, () => zone.run(callback))
));
};
this.backButton.subscribeWithPriority = function(priority, callback) {
return this.subscribe(ev => {
ev.register(priority, callback);
});
};
proxyEvent(this.pause, doc, 'pause');
proxyEvent(this.resume, doc, 'resume');
proxyEvent(this.backButton, doc, 'ionBackButton');
proxyEvent(this.resize, this.win, 'resize');
proxyEvent(this.pause, doc, 'pause');
proxyEvent(this.resume, doc, 'resume');
proxyEvent(this.backButton, doc, 'ionBackButton');
proxyEvent(this.resize, this.win, 'resize');
let readyResolve: (value: string) => void;
this._readyPromise = new Promise(res => { readyResolve = res; });
if (this.win && this.win['cordova']) {
doc.addEventListener('deviceready', () => {
readyResolve('cordova');
}, { once: true });
} else {
readyResolve!('dom');
}
let readyResolve: (value: string) => void;
this._readyPromise = new Promise(res => { readyResolve = res; });
if (this.win && this.win['cordova']) {
doc.addEventListener('deviceready', () => {
readyResolve('cordova');
}, { once: true });
} else {
readyResolve!('dom');
}
});
}
/**

View File

@@ -25,9 +25,6 @@ export class IonicRouteStrategy implements RouteReuseStrategy {
if (future.routeConfig !== curr.routeConfig) {
return false;
}
if (future.component !== curr.component) {
return false;
}
// checking router params
const futureParams = future.params;

View File

@@ -11,8 +11,9 @@ export class OverlayBaseController<Opts, Overlay> implements ControllerShape<Opt
/**
* Creates a new overlay
*/
create(opts: Opts) {
return this.ctrl.create(opts);
create(opts?: Opts) {
// TODO: next major release opts is not optional
return this.ctrl.create((opts || {}) as any);
}
/**

View File

@@ -1,16 +1,13 @@
import { HTMLStencilElement } from '../types/interfaces';
export function proxyMethod(ctrlName: string, doc: Document, methodName: string, ...args: any[]) {
const controller = ensureElementInBody(ctrlName, doc);
return controller.componentOnReady()
.then(() => (controller as any)[methodName].apply(controller, args));
}
declare const __zone_symbol__requestAnimationFrame: any;
declare const requestAnimationFrame: any;
export function ensureElementInBody(elementName: string, doc: Document) {
let element = doc.querySelector(elementName);
if (!element) {
element = doc.createElement(elementName);
doc.body.appendChild(element);
export const raf = (h: any) => {
if (typeof __zone_symbol__requestAnimationFrame === 'function') {
return __zone_symbol__requestAnimationFrame(h);
}
return element as HTMLStencilElement;
}
if (typeof requestAnimationFrame === 'function') {
return requestAnimationFrame(h);
}
return setTimeout(h);
};

View File

@@ -13,11 +13,11 @@
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/test-app",
"outputPath": "dist/browser",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"tsConfig": "tsconfig.app.json",
"assets": [
"src/favicon.ico",
{
@@ -31,9 +31,7 @@
"output": "./svg"
}
],
"styles": [
"src/styles.css"
],
"styles": ["src/styles.css"],
"scripts": []
},
"configurations": {
@@ -86,37 +84,13 @@
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"src/styles.css"
],
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"styles": ["src/styles.css"],
"scripts": [],
"assets": [
"src/favicon.ico",
"src/assets"
]
"assets": ["src/favicon.ico", "src/assets"]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"test-app-e2e": {
"root": "e2e/",
"projectType": "application",
"prefix": "",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
@@ -126,20 +100,39 @@
"configurations": {
"production": {
"devServerTarget": "test-app:serve:production"
},
"ci": {
"devServerTarget": "test-app:serve:ci"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
]
"tsConfig": ["tsconfig.app.json", "tsconfig.spec.json"],
"exclude": ["**/node_modules/**"]
}
},
"server": {
"builder": "@angular-devkit/build-angular:server",
"options": {
"outputPath": "dist/server",
"main": "src/main.server.ts",
"tsConfig": "tsconfig.server.json"
},
"configurations": {
"production": {
"fileReplacements": [
{
"src": "src/environments/environment.ts",
"replaceWith": "src/environments/environment.prod.ts"
}
]
}
}
}
}
}
},
"defaultProject": "test-app"
}
}

View File

@@ -0,0 +1,12 @@
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# You can see what browsers were selected by your queries by running:
# npx browserslist
> 0.5%
last 2 versions
Firefox ESR
not dead
not IE 9-11 # For IE 9-11 support, remove 'not'.

View File

@@ -1,32 +1,35 @@
// @ts-check
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter } = require('jasmine-spec-reporter');
/**
* @type { import("protractor").Config }
*/
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./**/*.e2e-spec.ts'
'./src/**/*.e2e-spec.ts'
],
capabilities: {
browserName: 'chrome',
chromeOptions: {
args: [ "--headless", "--disable-gpu", "--window-size=400,1000", "--start-maximized" ]
}
'browserName': 'chrome'
},
chromeOptions: {
args: [ "--headless", "--disable-gpu", "--window-size=400,1000", "--start-maximized" ]
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
defaultTimeoutInterval: 70000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.e2e.json')
project: require('path').join(__dirname, './tsconfig.json')
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};
};

View File

@@ -4,7 +4,7 @@ import { handleErrorMessages, setProperty, getText, waitTime } from './utils';
describe('form', () => {
afterEach(() => {
handleErrorMessages();
return handleErrorMessages();
});
describe('change', () => {

View File

@@ -8,7 +8,7 @@ describe('inputs', () => {
await waitTime(30);
});
afterEach(() => {
handleErrorMessages();
return handleErrorMessages();
});
it('should have default value', async () => {
@@ -60,4 +60,10 @@ describe('inputs', () => {
expect(await element(by.css('#select-note')).getText()).toEqual('playstation');
expect(await element(by.css('#range-note')).getText()).toEqual('20');
});
it('nested components should not interfere with NgModel', async () => {
expect(await element(by.css('#range-note')).getText()).toEqual('10');
await element(by.css('#nested-toggle')).click();
expect(await element(by.css('#range-note')).getText()).toEqual('10');
});
});

View File

@@ -8,7 +8,7 @@ describe('modals', () => {
await waitTime(30);
});
afterEach(() => {
handleErrorMessages();
return handleErrorMessages();
});
it('should open standalone modal and close', async () => {

View File

@@ -4,9 +4,44 @@ import { handleErrorMessages, waitTime, testStack } from './utils';
describe('navigation', () => {
afterEach(() => {
handleErrorMessages();
return handleErrorMessages();
});
// TODO: Fix flaky tests
xit ('should swipe and abort', async () => {
await browser.get('/router-link?ionic:mode=ios');
await waitTime(500);
await element(by.css('#routerLink')).click();
await waitTime(500);
await swipeLeft(5);
await waitTime(500);
const pageHidden = element(by.css('app-router-link'));
expect(await pageHidden.getAttribute('aria-hidden')).toEqual('true');
expect(await pageHidden.getAttribute('class')).toEqual('ion-page ion-page-hidden');
const pageVisible = element(by.css('app-router-link-page'));
expect(await pageVisible.getAttribute('aria-hidden')).toEqual(null);
expect(await pageVisible.getAttribute('class')).toEqual('ion-page can-go-back');
});
xit ('should swipe and go back', async () => {
await browser.get('/router-link?ionic:mode=ios');
await waitTime(500);
await element(by.css('#routerLink')).click();
await waitTime(500);
await testStack('ion-router-outlet', ['app-router-link', 'app-router-link-page']);
await swipeLeft(300);
await waitTime(1000);
await testStack('ion-router-outlet', ['app-router-link']);
const page = element(by.css('app-router-link'));
expect(await page.getAttribute('aria-hidden')).toEqual(null);
expect(await page.getAttribute('class')).toEqual('ion-page');
})
it('should navigate correctly', async () => {
await browser.get('/navigation/page1');
await waitTime(2000);
@@ -22,3 +57,17 @@ describe('navigation', () => {
});
});
function swipeLeft(end: number) {
return browser.driver.touchActions()
.tapAndHold({x: 5, y: 1})
.move({x: 6, y: 1})
.move({x: 7, y: 1})
.move({x: 8, y: 1})
.move({x: 30, y: 1})
.move({x: 300, y: 1})
.move({x: end, y: 1})
.move({x: end, y: 1})
.release({x: end, y: 1})
.perform();
}

View File

@@ -4,7 +4,7 @@ import { waitTime, handleErrorMessages, goBack } from './utils';
describe('nested-outlet', () => {
afterEach(() => {
handleErrorMessages();
return handleErrorMessages();
});
it('should navigate correctly', async () => {

View File

@@ -4,7 +4,7 @@ import { handleErrorMessages, waitTime } from './utils';
describe('providers', () => {
afterEach(() => {
handleErrorMessages();
return handleErrorMessages();
});
it('should load all providers', async () => {
@@ -12,6 +12,9 @@ describe('providers', () => {
expect(await element(by.css('#is-loaded')).getText()).toEqual('true');
expect(await element(by.css('#is-ready')).getText()).toEqual('true');
expect(await element(by.css('#is-paused')).getText()).toEqual('true');
expect(await element(by.css('#is-resumed')).getText()).toEqual('true');
expect(await element(by.css('#is-resized')).getText()).toEqual('true');
expect(await element(by.css('#is-testing')).getText()).toEqual('false');
expect(await element(by.css('#is-desktop')).getText()).toEqual('true');
expect(await element(by.css('#is-mobile')).getText()).toEqual('false');

View File

@@ -1,5 +1,5 @@
import { browser, element, by, protractor } from 'protractor';
import { waitTime, testStack, testLifeCycle, handleErrorMessages } from './utils';
import { waitTime, testStack, testLifeCycle, handleErrorMessages, getText } from './utils';
const EC = protractor.ExpectedConditions;
@@ -9,7 +9,7 @@ describe('router-link params and fragments', () => {
const id = 'MyPageID==';
afterEach(() => {
handleErrorMessages();
return handleErrorMessages();
});
it('should go to a page with properly encoded values', async () => {
@@ -23,12 +23,13 @@ describe('router-link params and fragments', () => {
it('should return to a page with preserved query param and fragment', async () => {
await browser.get('/router-link?ionic:_testing=true');
await waitTime(30);
await element(by.css('#queryParamsFragment')).click();
await waitTime(200);
await waitTime(400);
await element(by.css('#goToPage3')).click();
browser.wait(EC.urlContains('router-link-page3'), 5000);
await waitTime(200);
await waitTime(400);
await element(by.css('#goBackFromPage3')).click();
@@ -38,6 +39,7 @@ describe('router-link params and fragments', () => {
it('should preserve query param and fragment with defaultHref string', async () => {
await browser.get('/router-link-page3?ionic:_testing=true');
await waitTime(30);
await element(by.css('#goBackFromPage3')).click();
@@ -53,7 +55,7 @@ describe('router-link', () => {
await waitTime(30);
});
afterEach(() => {
handleErrorMessages();
return handleErrorMessages();
});
@@ -71,18 +73,6 @@ describe('router-link', () => {
it('should go forward with ion-button[routerLink]', async () => {
await element(by.css('#routerLink')).click();
await testForward();
// test go back
await element(by.css('ion-back-button')).click();
await waitTime(500);
await testStack('ion-router-outlet', ['app-router-link']);
await testLifeCycle('app-router-link', {
ionViewWillEnter: 2,
ionViewDidEnter: 2,
ionViewWillLeave: 1,
ionViewDidLeave: 1,
});
});
it('should go forward with a[routerLink]', async () => {
@@ -123,7 +113,6 @@ describe('router-link', () => {
it('should go back with ion-button[routerLink][routerDirection=back]', async () => {
await element(by.css('#routerLink-back')).click();
await testBack();
});
it('should go back with a[routerLink][routerDirection=back]', async () => {
@@ -139,21 +128,25 @@ describe('router-link', () => {
});
async function testForward() {
await waitTime(500);
await waitTime(2500);
await testStack('ion-router-outlet', ['app-router-link', 'app-router-link-page']);
await testLifeCycle('app-router-link', {
ionViewWillEnter: 1,
ionViewDidEnter: 1,
ionViewWillLeave: 1,
ionViewDidLeave: 1,
});
await testLifeCycle('app-router-link-page', {
ionViewWillEnter: 1,
ionViewDidEnter: 1,
ionViewWillLeave: 0,
ionViewDidLeave: 0,
});
expect(await getText(`app-router-link-page #canGoBack`)).toEqual('true');
await browser.navigate().back();
await waitTime(100);
await testStack('ion-router-outlet', ['app-router-link']);
await testLifeCycle('app-router-link', {
ionViewWillEnter: 2,
ionViewDidEnter: 2,
ionViewWillLeave: 1,
ionViewDidLeave: 1,
});
}
async function testRoot() {
@@ -165,6 +158,17 @@ async function testRoot() {
ionViewWillLeave: 0,
ionViewDidLeave: 0,
});
expect(await getText(`app-router-link-page #canGoBack`)).toEqual('false');
await browser.navigate().back();
await waitTime(100);
await testStack('ion-router-outlet', ['app-router-link']);
await testLifeCycle('app-router-link', {
ionViewWillEnter: 1,
ionViewDidEnter: 1,
ionViewWillLeave: 0,
ionViewDidLeave: 0,
});
}
async function testBack() {
@@ -176,4 +180,15 @@ async function testBack() {
ionViewWillLeave: 0,
ionViewDidLeave: 0,
});
expect(await getText(`app-router-link-page #canGoBack`)).toEqual('false');
await browser.navigate().back();
await waitTime(100);
await testStack('ion-router-outlet', ['app-router-link']);
await testLifeCycle('app-router-link', {
ionViewWillEnter: 1,
ionViewDidEnter: 1,
ionViewWillLeave: 0,
ionViewDidLeave: 0,
});
}

View File

@@ -8,7 +8,7 @@ describe('slides', () => {
await waitTime(30);
});
afterEach(() => {
handleErrorMessages();
return handleErrorMessages();
});
it('should change index on slide change', async () => {

View File

@@ -3,7 +3,7 @@ import { waitTime, testStack, handleErrorMessages } from './utils';
describe('tabs', () => {
afterEach(() => {
handleErrorMessages();
return handleErrorMessages();
});
describe('entry url - /tabs', () => {
beforeEach(async () => {
@@ -17,10 +17,19 @@ describe('tabs', () => {
await testState(1, 'account');
});
it('should navigate between tabs and ionChange events should be dispatched ', async () => {
let tab = await testTabTitle('Tab 1 - Page 1');
expect(await tab.$('.segment-changed').getText()).toEqual('false');
await element(by.css('#tab-button-contact')).click();
tab = await testTabTitle('Tab 2 - Page 1');
expect(await tab.$('.segment-changed').getText()).toEqual('false');
});
it('should simulate stack + double tab click', async () => {
let tab = await getSelectedTab() as ElementFinder;
await tab.$('#goto-tab1-page2').click();
await testTabTitle('Tab 1 - Page 2');
await testTabTitle('Tab 1 - Page 2 (1)');
await testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1', 'app-tabs-tab1-nested']);
await testState(1, 'account');
expect(await tab.$('ion-back-button').isDisplayed()).toBe(true);
@@ -31,7 +40,7 @@ describe('tabs', () => {
await testState(2, 'contact');
await element(by.css('#tab-button-account')).click();
tab = await testTabTitle('Tab 1 - Page 2');
tab = await testTabTitle('Tab 1 - Page 2 (1)');
await testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1', 'app-tabs-tab1-nested', 'app-tabs-tab2']);
await testState(3, 'account');
expect(await tab.$('ion-back-button').isDisplayed()).toBe(true);
@@ -45,7 +54,7 @@ describe('tabs', () => {
it('should simulate stack + back button click', async () => {
const tab = await getSelectedTab();
await tab.$('#goto-tab1-page2').click();
await testTabTitle('Tab 1 - Page 2');
await testTabTitle('Tab 1 - Page 2 (1)');
await testState(1, 'account');
await element(by.css('#tab-button-contact')).click();
@@ -53,7 +62,7 @@ describe('tabs', () => {
await testState(2, 'contact');
await element(by.css('#tab-button-account')).click();
await testTabTitle('Tab 1 - Page 2');
await testTabTitle('Tab 1 - Page 2 (1)');
await testState(3, 'account');
await element(by.css('ion-back-button')).click();
@@ -62,6 +71,33 @@ describe('tabs', () => {
await testState(3, 'account');
});
it('should navigate deep then go home', async () => {
let tab = await getSelectedTab();
await tab.$('#goto-tab1-page2').click();
tab = await testTabTitle('Tab 1 - Page 2 (1)');
await tab.$('#goto-next').click();
tab = await testTabTitle('Tab 1 - Page 2 (2)');
await element(by.css('#tab-button-contact')).click();
tab = await testTabTitle('Tab 2 - Page 1');
await element(by.css('#tab-button-account')).click();
await testTabTitle('Tab 1 - Page 2 (2)');
await testStack('ion-tabs ion-router-outlet', [
'app-tabs-tab1',
'app-tabs-tab1-nested',
'app-tabs-tab1-nested',
'app-tabs-tab2'
]);
await element(by.css('#tab-button-account')).click();
await testTabTitle('Tab 1 - Page 1');
await testStack('ion-tabs ion-router-outlet', [
'app-tabs-tab1',
'app-tabs-tab2'
]);
});
it('should switch tabs and go back', async () => {
await element(by.css('#tab-button-contact')).click();
const tab = await testTabTitle('Tab 2 - Page 1');
@@ -76,7 +112,7 @@ describe('tabs', () => {
const tab = await testTabTitle('Tab 2 - Page 1');
await tab.$('#goto-tab1-page2').click();
await testTabTitle('Tab 1 - Page 2');
await testTabTitle('Tab 1 - Page 2 (1)');
await testStack('ion-tabs ion-router-outlet', ['app-tabs-tab2', 'app-tabs-tab1-nested']);
});
@@ -97,14 +133,14 @@ describe('tabs', () => {
});
});
describe('entry url - /tabs/account/nested/12', () => {
describe('entry url - /tabs/account/nested/1', () => {
beforeEach(async () => {
await browser.get('/tabs/account/nested/12');
await browser.get('/tabs/account/nested/1');
await waitTime(30);
});
it('should only display the back-button when there is a page in the stack', async () => {
let tab = await testTabTitle('Tab 1 - Page 2') as ElementFinder;
let tab = await testTabTitle('Tab 1 - Page 2 (1)') as ElementFinder;
await testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1-nested']);
expect(await tab.$('ion-back-button').isDisplayed()).toBe(false);
@@ -112,9 +148,32 @@ describe('tabs', () => {
tab = await testTabTitle('Tab 1 - Page 1');
await tab.$('#goto-tab1-page2').click();
tab = await testTabTitle('Tab 1 - Page 2');
tab = await testTabTitle('Tab 1 - Page 2 (1)');
expect(await tab.$('ion-back-button').isDisplayed()).toBe(true);
});
it('should not reuse the same page', async () => {
let tab = await testTabTitle('Tab 1 - Page 2 (1)') as ElementFinder;
await tab.$('#goto-next').click();
tab = await testTabTitle('Tab 1 - Page 2 (2)');
await tab.$('#goto-next').click();
tab = await testTabTitle('Tab 1 - Page 2 (3)');
await testStack('ion-tabs ion-router-outlet',[
'app-tabs-tab1-nested',
'app-tabs-tab1-nested',
'app-tabs-tab1-nested'
]);
await tab.$('ion-back-button').click();
tab = await testTabTitle('Tab 1 - Page 2 (2)');
await tab.$('ion-back-button').click();
tab = await testTabTitle('Tab 1 - Page 2 (1)');
expect(await tab.$('ion-back-button').isDisplayed()).toBe(false);
await testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1-nested']);
});
});
describe('entry url - /tabs/lazy', () => {
@@ -128,7 +187,7 @@ describe('tabs', () => {
await testStack('ion-tabs ion-router-outlet', ['app-tabs-tab3']);
await tab.$('#goto-tab1-page2').click();
tab = await testTabTitle('Tab 1 - Page 2');
tab = await testTabTitle('Tab 1 - Page 2 (1)');
await testStack('ion-tabs ion-router-outlet', ['app-tabs-tab3', 'app-tabs-tab1-nested']);
expect(await tab.$('ion-back-button').isDisplayed()).toBe(false);
});

View File

@@ -37,29 +37,30 @@ export interface LifeCycleCount {
}
export function handleErrorMessages() {
browser.manage().logs().get('browser').then(function(browserLog) {
let severWarnings = false;
for (let i; i <= browserLog.length - 1; i++) {
if (browserLog[i].level.name === 'SEVERE') {
console.log('\n' + browserLog[i].level.name);
console.log('(Possibly exception) \n' + browserLog[i].message);
severWarnings = true;
}
return browser.manage().logs().get('browser').then(function (browserLog) {
for (let i = 0; i <= browserLog.length - 1; i++) {
if (browserLog[i].level.name_ === 'SEVERE') {
fail(browserLog[i].message);
}
}
expect(severWarnings).toBe(false);
});
}
export async function testLifeCycle(selector: string, expected: LifeCycleCount) {
await waitTime(50);
expect(await getText(`${selector} #ngOnInit`)).toEqual('1');
expect(await getText(`${selector} #ionViewWillEnter`)).toEqual(expected.ionViewWillEnter.toString());
expect(await getText(`${selector} #ionViewDidEnter`)).toEqual(expected.ionViewDidEnter.toString());
expect(await getText(`${selector} #ionViewWillLeave`)).toEqual(expected.ionViewWillLeave.toString());
expect(await getText(`${selector} #ionViewDidLeave`)).toEqual(expected.ionViewDidLeave.toString());
const results = await Promise.all([
getText(`${selector} #ngOnInit`),
getText(`${selector} #ionViewWillEnter`),
getText(`${selector} #ionViewDidEnter`),
getText(`${selector} #ionViewWillLeave`),
getText(`${selector} #ionViewDidLeave`),
]);
expect(results[0]).toEqual('1');
expect(results[1]).toEqual(expected.ionViewWillEnter.toString());
expect(results[2]).toEqual(expected.ionViewDidEnter.toString());
expect(results[3]).toEqual(expected.ionViewWillLeave.toString());
expect(results[4]).toEqual(expected.ionViewDidLeave.toString());
}
export async function testStack(selector: string, expected: string[]) {

View File

@@ -8,7 +8,7 @@ describe('view-child', () => {
await waitTime(30);
});
afterEach(() => {
handleErrorMessages();
return handleErrorMessages();
});
it('should get a reference to all children', async () => {

View File

@@ -0,0 +1,18 @@
import { browser, element, by } from 'protractor';
import { waitTime, handleErrorMessages } from './utils';
describe('virtual-scroll', () => {
afterEach(() => {
return handleErrorMessages();
});
beforeEach(async () => {
await browser.get('/virtual-scroll');
await waitTime(30);
});
it('should open virtual-scroll', () => {
const virtualElements = element.all(by.css('ion-virtual-scroll > *'));
expect(virtualElements.count()).toBeGreaterThan(0);
});
});

View File

@@ -8,8 +8,6 @@ module.exports = function (config) {
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,51 +1,60 @@
{
"name": "test-app",
"name": "ionic-angular-test-app",
"version": "0.0.0",
"private": true,
"scripts": {
"ng": "ng",
"start": "npm run sync && ng serve",
"sync:build": "sh scripts/build-ionic.sh",
"sync": "sh scripts/sync.sh",
"build": "ng build --prod --no-progress",
"build": "npm run sync && ng build --prod --no-progress",
"test": "ng e2e --prod",
"test.dev": "npm run sync && ng e2e",
"lint": "ng lint",
"postinstall": "npm run sync"
"postinstall": "npm run sync",
"compile:server": "webpack --config webpack.server.config.js --progress --colors",
"serve:ssr": "node dist/server",
"build:ssr": "npm run build:client-and-server-bundles && npm run compile:server",
"build:client-and-server-bundles": "npm run build && ng run test-app:server:production --bundleDependencies all"
},
"private": true,
"dependencies": {
"@angular/animations": "~7.2.1",
"@angular/common": "~7.2.1",
"@angular/compiler": "~7.2.1",
"@angular/core": "~7.2.1",
"@angular/forms": "~7.2.1",
"@angular/platform-browser": "~7.2.1",
"@angular/platform-browser-dynamic": "~7.2.1",
"@angular/router": "~7.2.1",
"@ionic/angular": "^4.0.0-rc.1",
"@angular/animations": "^8.2.8",
"@angular/common": "^8.2.8",
"@angular/compiler": "^8.2.8",
"@angular/core": "^8.2.8",
"@angular/forms": "^8.2.8",
"@angular/platform-browser": "^8.2.8",
"@angular/platform-browser-dynamic": "^8.2.8",
"@angular/platform-server": "^8.2.8",
"@angular/router": "^8.2.8",
"@ionic/angular": "^4.7.0",
"@ionic/angular-server": "^0.0.2",
"@nguniversal/express-engine": "~8.1.1",
"@nguniversal/module-map-ngfactory-loader": "~8.1.1",
"core-js": "^2.6.2",
"rxjs": "~6.3.3",
"express": "^4.15.2",
"rxjs": "^6.5.3",
"tslib": "^1.9.0",
"zone.js": "~0.8.26"
"zone.js": "~0.9.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.12.2",
"@angular/cli": "~7.2.1",
"@angular/compiler-cli": "~7.2.1",
"@angular/language-service": "~7.2.1",
"@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4",
"codelyzer": "~4.5.0",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~3.1.4",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~1.1.2",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.4.2",
"ts-node": "~7.0.0",
"tslint": "~5.12.1",
"typescript": "~3.2.4"
"@angular-devkit/build-angular": "^0.803.6",
"@angular/cli": "^8.3.6",
"@angular/compiler-cli": "^8.2.8",
"@angular/language-service": "^8.2.8",
"@types/jasmine": "3.4.1",
"@types/node": "12.7.8",
"codelyzer": "^5.1.2",
"jasmine-core": "3.5.0",
"jasmine-spec-reporter": "4.2.1",
"karma": "4.3.0",
"karma-chrome-launcher": "3.1.0",
"karma-jasmine": "2.0.1",
"protractor": "5.4.2",
"ts-loader": "^6.1.2",
"ts-node": "8.4.1",
"tslint": "~5.18.0",
"typescript": "~3.5.3",
"webpack-cli": "^3.3.9"
}
}

View File

@@ -10,6 +10,14 @@ popd
pushd angular
npm link @ionic/core
npm run build
npm link
popd
# Build angular-server
pushd packages/angular-server
npm link @ionic/core
npm link @ionic/angular
npm run build
popd
popd

View File

@@ -1,15 +1,25 @@
# Copy angular dist
rm -rf node_modules/@ionic/angular/dist
rm -rf node_modules/@ionic/angular
mkdir node_modules/@ionic/angular
cp -a ../../dist node_modules/@ionic/angular/dist
cp -a ../../css node_modules/@ionic/angular/css
cp -a ../../package.json node_modules/@ionic/angular/package.json
# Copy core dist
rm -rf node_modules/@ionic/core/dist
rm -rf node_modules/@ionic/core/loader
# Copy angular server
rm -rf node_modules/@ionic/angular-server
mkdir node_modules/@ionic/angular-server
cp -a ../../../packages/angular-server/dist node_modules/@ionic/angular-server/dist
cp -a ../../../packages/angular-server/package.json node_modules/@ionic/angular-server/package.json
# # Copy core dist
rm -rf node_modules/@ionic/core
mkdir node_modules/@ionic/core
cp -a ../../../core/css node_modules/@ionic/core/css
cp -a ../../../core/dist node_modules/@ionic/core/dist
cp -a ../../../core/hydrate node_modules/@ionic/core/hydrate
cp -a ../../../core/loader node_modules/@ionic/core/loader
cp -a ../../../core/package.json node_modules/@ionic/core/package.json
# Copy ionicons
# # Copy ionicons
rm -rf node_modules/ionicons
cp -a ../../../core/node_modules/ionicons node_modules/ionicons

View File

@@ -0,0 +1,58 @@
/**
* *** NOTE ON IMPORTING FROM ANGULAR AND NGUNIVERSAL IN THIS FILE ***
*
* If your application uses third-party dependencies, you'll need to
* either use Webpack or the Angular CLI's `bundleDependencies` feature
* in order to adequately package them for use on the server without a
* node_modules directory.
*
* However, due to the nature of the CLI's `bundleDependencies`, importing
* Angular in this file will create a different instance of Angular than
* the version in the compiled application code. This leads to unavoidable
* conflicts. Therefore, please do not explicitly import from @angular or
* @nguniversal in this file. You can export any needed resources
* from your application's main.server.ts file, as seen below with the
* import for `ngExpressEngine`.
*/
import 'zone.js/dist/zone-node';
import * as express from 'express';
import {join} from 'path';
// Express server
const app = express();
const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist/browser');
// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const {AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModuleMap} = require('./dist/server/main');
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine('html', ngExpressEngine({
bootstrap: AppServerModuleNgFactory,
providers: [
provideModuleMap(LAZY_MODULE_MAP)
]
}));
app.set('view engine', 'html');
app.set('views', DIST_FOLDER);
// Example Express Rest API endpoints
// app.get('/api/**', (req, res) => { });
// Serve static files from /browser
app.get('*.*', express.static(DIST_FOLDER, {
maxAge: '1y'
}));
// All regular routes use the Universal engine
app.get('*', (req, res) => {
res.render('index', { req });
});
// Start up the Node server
app.listen(PORT, () => {
console.log(`Node Express server listening on http://localhost:${PORT}`);
});

View File

@@ -1,10 +1,10 @@
<ion-header>
<ion-toolbar>
<ion-title>
Modal test
Alert test
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-button (click)="openAlert()" id="action-button">Open Alert</ion-button>
<ion-content>
<p>Change Detections: <span id="counter">{{counter()}}</span></p>
</ion-content>

View File

@@ -8,14 +8,31 @@ import { NavComponent } from '../nav/nav.component';
})
export class AlertComponent {
changes = 0;
constructor(
private alertCtrl: AlertController
) { }
counter() {
this.changes++;
return Math.floor(this.changes / 2);
}
async openAlert() {
const alert = await this.alertCtrl.create({
header: 'Hello',
message: 'Some text'
message: 'Some text',
buttons: [
{
role: 'cancel',
text: 'Cancel',
handler: () => {
console.log(NgZone.isInAngularZone());
NgZone.assertInAngularZone();
}
}
]
});
await alert.present();
}

View File

@@ -7,10 +7,6 @@ import { RouterLinkPageComponent } from './router-link-page/router-link-page.com
import { RouterLinkPage2Component } from './router-link-page2/router-link-page2.component';
import { RouterLinkPage3Component } from './router-link-page3/router-link-page3.component';
import { HomePageComponent } from './home-page/home-page.component';
import { TabsComponent } from './tabs/tabs.component';
import { TabsTab1Component } from './tabs-tab1/tabs-tab1.component';
import { TabsTab1NestedComponent } from './tabs-tab1-nested/tabs-tab1-nested.component';
import { TabsTab2Component } from './tabs-tab2/tabs-tab2.component';
import { VirtualScrollComponent } from './virtual-scroll/virtual-scroll.component';
import { VirtualScrollDetailComponent } from './virtual-scroll-detail/virtual-scroll-detail.component';
import { NestedOutletComponent } from './nested-outlet/nested-outlet.component';
@@ -51,40 +47,7 @@ const routes: Routes = [
},
{
path: 'tabs',
component: TabsComponent,
children: [
{
path: 'account',
children: [
{
path: 'nested/:id',
component: TabsTab1NestedComponent
},
{
path: '',
component: TabsTab1Component
}
]
},
{
path: 'contact',
children: [
{
path: 'one',
component: TabsTab2Component
},
{
path: '',
redirectTo: 'one',
pathMatch: 'full'
}
]
},
{
path: 'lazy',
loadChildren: './tabs-lazy/tabs-lazy.module#TabsLazyModule'
}
]
loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule)
},
{
path: 'nested-outlet',

View File

@@ -1,10 +1,11 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { RouteReuseStrategy } from '@angular/router';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { IonicModule } from '@ionic/angular';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { FormsModule } from '@angular/forms';
import { InputsComponent } from './inputs/inputs.component';
import { ModalComponent } from './modal/modal.component';
@@ -14,10 +15,6 @@ import { RouterLinkPageComponent } from './router-link-page/router-link-page.com
import { RouterLinkPage2Component } from './router-link-page2/router-link-page2.component';
import { RouterLinkPage3Component } from './router-link-page3/router-link-page3.component';
import { HomePageComponent } from './home-page/home-page.component';
import { TabsComponent } from './tabs/tabs.component';
import { TabsTab1Component } from './tabs-tab1/tabs-tab1.component';
import { TabsTab2Component } from './tabs-tab2/tabs-tab2.component';
import { TabsTab1NestedComponent } from './tabs-tab1-nested/tabs-tab1-nested.component';
import { VirtualScrollComponent } from './virtual-scroll/virtual-scroll.component';
import { VirtualScrollDetailComponent } from './virtual-scroll-detail/virtual-scroll-detail.component';
import { VirtualScrollInnerComponent } from './virtual-scroll-inner/virtual-scroll-inner.component';
@@ -45,10 +42,6 @@ import { AlertComponent } from './alert/alert.component';
RouterLinkPage2Component,
RouterLinkPage3Component,
HomePageComponent,
TabsComponent,
TabsTab1Component,
TabsTab2Component,
TabsTab1NestedComponent,
VirtualScrollComponent,
VirtualScrollDetailComponent,
VirtualScrollInnerComponent,
@@ -66,7 +59,7 @@ import { AlertComponent } from './alert/alert.component';
AlertComponent
],
imports: [
BrowserModule,
BrowserModule.withServerTransition({ appId: 'serverApp' }),
AppRoutingModule,
FormsModule,
ReactiveFormsModule,
@@ -76,7 +69,9 @@ import { AlertComponent } from './alert/alert.component';
ModalExampleComponent,
NavComponent
],
providers: [],
providers: [
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
],
bootstrap: [AppComponent]
})
export class AppModule { }

View File

@@ -0,0 +1,19 @@
import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { IonicServerModule } from '@ionic/angular-server';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';
@NgModule({
imports: [
AppModule,
ServerModule,
ModuleMapLoaderModule,
IonicServerModule
],
bootstrap: [AppComponent],
})
export class AppServerModule {}

View File

@@ -20,7 +20,9 @@ export class FormComponent {
input2: ['Default Value'],
checkbox: [false],
range: [5, Validators.min(10)],
}, {updateOn: window.location.hash === '#blur' ? 'blur' : 'change'});
}, {
updateOn: typeof (window as any) !== 'undefined' && window.location.hash === '#blur' ? 'blur' : 'change'
});
}
onSubmit(_ev) {

View File

@@ -6,6 +6,7 @@
</ion-toolbar>
</ion-header>
<ion-content>
<p>Change Detections: <span id="counter">{{counter()}}</span></p>
<ion-list>
<ion-item>
@@ -89,10 +90,12 @@
<ion-range [(ngModel)]="range"></ion-range>
<ion-note slot="end" id="range-note">{{range}}</ion-note>
</ion-item>
<ion-item color="dark">
<ion-label>Range Mirror</ion-label>
<ion-range [(ngModel)]="range"></ion-range>
<ion-range [(ngModel)]="range">
<ion-toggle slot="start" id="nested-toggle" [(ngModel)]="toggle"></ion-toggle>
</ion-range>
<ion-note slot="end">{{range}}</ion-note>
</ion-item>

View File

@@ -12,6 +12,7 @@ export class InputsComponent {
toggle = true;
select = 'nes';
range = 10;
changes = 0;
setValues() {
console.log('set values');
@@ -32,4 +33,8 @@ export class InputsComponent {
this.select = undefined;
this.range = undefined;
}
counter() {
this.changes++;
return Math.floor(this.changes / 2);
}
}

View File

@@ -8,7 +8,7 @@
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-content class="ion-padding">
<h1>Value</h1>
<h2>{{value}}</h2>
<h3>{{valueFromParams}}</h3>

View File

@@ -5,7 +5,7 @@
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-content class="ion-padding">
<ion-button (click)="openModal()" id="action-button">Open Modal</ion-button>
<ion-button (click)="openNav()" id="action-button-2">Open Nav in Modal</ion-button>
<p>

View File

@@ -5,13 +5,22 @@
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-content class="ion-padding">
<p>
isLoaded: <span id="is-loaded">{{isLoaded}}</span>
</p>
<p>
isReady: <span id="is-ready">{{isReady}}</span>
</p>
<p>
isResumed: <span id="is-resumed">{{isResumed}}</span>
</p>
<p>
isPaused: <span id="is-paused">{{isPaused}}</span>
</p>
<p>
isResized: <span id="is-resized">{{isResized}}</span>
</p>
<p>
isTesting: <span id="is-testing">{{isTesting}}</span>
</p>

View File

@@ -1,4 +1,4 @@
import { Component } from '@angular/core';
import { Component, NgZone } from '@angular/core';
import {
Platform, ModalController, AlertController, ActionSheetController,
PopoverController, ToastController, Events, PickerController, MenuController,
@@ -14,6 +14,9 @@ export class ProvidersComponent {
isLoaded = false;
isReady = false;
isEvent = false;
isResumed = false;
isPaused = false;
isResized = false;
isTesting: boolean = undefined;
isDesktop: boolean = undefined;
isMobile: boolean = undefined;
@@ -32,7 +35,8 @@ export class ProvidersComponent {
toastCtrl: ToastController,
navCtrl: NavController,
domCtrl: DomController,
config: Config
config: Config,
zone: NgZone
) {
// test all providers load
if (
@@ -44,15 +48,31 @@ export class ProvidersComponent {
// test platform ready()
platform.ready().then(() => {
NgZone.assertInAngularZone();
this.isReady = true;
});
platform.resume.subscribe(() => {
console.log('platform:resume');
NgZone.assertInAngularZone();
this.isResumed = true;
});
platform.pause.subscribe(() => {
console.log('platform:pause');
NgZone.assertInAngularZone();
this.isPaused = true;
});
platform.resize.subscribe(() => {
console.log('platform:resize');
NgZone.assertInAngularZone();
this.isResized = true;
});
this.isDesktop = platform.is('desktop');
this.isMobile = platform.is('mobile');
// test events
events.subscribe('topic', () => {
this.isEvent = true;
NgZone.assertInAngularZone();
});
events.publish('topic');
@@ -60,5 +80,11 @@ export class ProvidersComponent {
this.isTesting = config.getBoolean('_testing');
config.set('keyboardHeight', 12345);
this.keyboardHeight = config.getNumber('keyboardHeight');
zone.runOutsideAngular(() => {
document.dispatchEvent(new CustomEvent('pause'));
document.dispatchEvent(new CustomEvent('resume'));
window.dispatchEvent(new CustomEvent('resize'));
});
}
}

View File

@@ -7,8 +7,9 @@
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-content class="ion-padding">
<p>ngOnInit: <span id="ngOnInit">{{onInit}}</span></p>
<p>canGoBack: <span id="canGoBack">{{canGoBack}}</span></p>
<p>ionViewWillEnter: <span id="ionViewWillEnter">{{willEnter}}</span></p>
<p>ionViewDidEnter: <span id="ionViewDidEnter">{{didEnter}}</span></p>
<p>ionViewWillLeave: <span id="ionViewWillLeave">{{willLeave}}</span></p>

View File

@@ -1,4 +1,5 @@
import { Component, OnInit, NgZone } from '@angular/core';
import { IonRouterOutlet } from '@ionic/angular';
@Component({
selector: 'app-router-link-page',
@@ -11,9 +12,15 @@ export class RouterLinkPageComponent implements OnInit {
didEnter = 0;
willLeave = 0;
didLeave = 0;
canGoBack: boolean = null;
constructor(
private ionRouterOutlet: IonRouterOutlet
) {}
ngOnInit() {
NgZone.assertInAngularZone();
this.canGoBack = this.ionRouterOutlet.canGoBack();
this.onInit++;
}
@@ -21,10 +28,16 @@ export class RouterLinkPageComponent implements OnInit {
if (this.onInit !== 1) {
throw new Error('ngOnInit was not called');
}
if (this.canGoBack !== this.ionRouterOutlet.canGoBack()) {
throw new Error('canGoBack() changed');
}
NgZone.assertInAngularZone();
this.willEnter++;
}
ionViewDidEnter() {
if (this.canGoBack !== this.ionRouterOutlet.canGoBack()) {
throw new Error('canGoBack() changed');
}
NgZone.assertInAngularZone();
this.didEnter++;
}

View File

@@ -7,6 +7,6 @@
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-content class="ion-padding">
<ion-button routerLink="/router-link-page3" id="goToPage3">Go to Page 3</ion-button>
</ion-content>

View File

@@ -7,6 +7,6 @@
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-content class="ion-padding">
Page 3
</ion-content>

View File

@@ -5,12 +5,13 @@
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-content class="ion-padding">
<p>ngOnInit: <span id="ngOnInit">{{onInit}}</span></p>
<p>ionViewWillEnter: <span id="ionViewWillEnter">{{willEnter}}</span></p>
<p>ionViewDidEnter: <span id="ionViewDidEnter">{{didEnter}}</span></p>
<p>ionViewWillLeave: <span id="ionViewWillLeave">{{willLeave}}</span></p>
<p>ionViewDidLeave: <span id="ionViewDidLeave">{{didLeave}}</span></p>
<p>Change Detections: <span id="counter">{{counter()}}</span></p>
<p>
<ion-button routerLink="/router-link-page" expand="block" color="dark" id="routerLink">ion-button[routerLink]</ion-button>
@@ -26,7 +27,7 @@
<p><button (click)="navigateForward()" id="button-forward">navigateForward</button></p>
<p><button (click)="navigateRoot()" id="button-root">navigateForward</button></p>
<p><button (click)="navigateBack()" id="button-back">navigateBack</button></p>
<p><button id="queryParamsFragment" routerLink="/router-link-page2/MyPageID==" [queryParams]="{ token: 'A&=#Y' }" fragment="myDiv1">Query Params and Fragment</button></p>
</ion-content>

View File

@@ -13,6 +13,7 @@ export class RouterLinkComponent implements OnInit {
didEnter = 0;
willLeave = 0;
didLeave = 0;
changes = 0;
constructor(
private navCtrl: NavController,
@@ -35,6 +36,11 @@ export class RouterLinkComponent implements OnInit {
this.navCtrl.navigateRoot('/router-link-page');
}
counter() {
this.changes++;
return Math.floor(this.changes / 2);
}
ngOnInit() {
NgZone.assertInAngularZone();
this.onInit++;

View File

@@ -1,4 +1,4 @@
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
import { AfterViewInit, Component, ViewChild } from '@angular/core';
import { IonSlides } from '@ionic/angular';
@Component({
@@ -6,7 +6,7 @@ import { IonSlides } from '@ionic/angular';
templateUrl: './slides.component.html',
})
export class SlidesComponent implements AfterViewInit {
@ViewChild(IonSlides) slides: IonSlides;
@ViewChild(IonSlides, { static: true }) slides: IonSlides;
slideIndex = 0;
slideIndex2 = 0;

View File

@@ -7,9 +7,9 @@
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-content class="ion-padding">
<p>
<ion-button routerLink="/tabs/account" id="goto-tab1-page1">Go to Tab 1 - Page 1</ion-button>
<ion-button routerLink="/tabs/account/nested/12" id="goto-tab1-page2">Go to Tab 1 - Page 2</ion-button>
<ion-button routerLink="/tabs/account/nested/1" id="goto-tab1-page2">Go to Tab 1 - Page 2</ion-button>
</p>
</ion-content>

View File

@@ -4,11 +4,11 @@
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-content class="ion-padding">
<h1>LAZY LOADED TAB</h1>
<p>
<ion-button routerLink="/tabs/account" id="goto-tab1-page1">Go to Tab 1 - Page 1</ion-button>
<ion-button routerLink="/tabs/account/nested/12" id="goto-tab1-page2">Go to Tab 1 - Page 2</ion-button>
<ion-button routerLink="/tabs/account/nested/1" id="goto-tab1-page2">Go to Tab 1 - Page 2</ion-button>
<ion-button routerLink="/tabs/lazy/nested" id="goto-tab3-page2">Go to Tab 3 - Page 2</ion-button>
</p>

View File

@@ -1,16 +1,17 @@
<ion-header>
<ion-toolbar>
<ion-title>Tab 1 - Page 2</ion-title>
<ion-title>Tab 1 - Page 2 ({{id}})</ion-title>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content padding>
<h1>Welcome to NESTED PAGE</h1>
<ion-content class="ion-padding">
<h1>Welcome to NESTED PAGE {{id}}</h1>
<p>
<ion-button routerLink="/tabs/account" id="goto-tab1-page1">Go to Tab 1 - Page 1</ion-button>
<ion-button routerLink="/tabs/contact" id="goto-tab2-page1">Go to Tab 2 - Page 1</ion-button>
<ion-button routerLink="/tabs/account/nested/{{next()}}" id="goto-next">Go to Next</ion-button>
</p>
</ion-content>

View File

@@ -1,7 +1,21 @@
import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-tabs-tab1-nested',
templateUrl: './tabs-tab1-nested.component.html',
})
export class TabsTab1NestedComponent { }
export class TabsTab1NestedComponent {
id = '';
constructor(
private route: ActivatedRoute,
) {}
ngOnInit() {
this.id = this.route.snapshot.paramMap.get('id');
}
next() {
return parseInt(this.id, 10) + 1;
}
}

View File

@@ -1,13 +1,20 @@
<ion-header>
<ion-toolbar>
<ion-title>Tab 1 - Page 1</ion-title>
<ion-title>{{title}}</ion-title>
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-content class="ion-padding">
<h1>Welcome to Tab1</h1>
<ion-segment [(ngModel)]="segment" (ionChange)="segmentChanged($event)">
<ion-segment-button value="one">One</ion-segment-button>
<ion-segment-button value="two">Two</ion-segment-button>
</ion-segment>
<p>
<ion-button routerLink="/tabs/account/nested/12" id="goto-tab1-page2">Go to Page 2</ion-button>
Segment changed: <span class="segment-changed">{{changed}}</span>
</p>
<p>
<ion-button routerLink="/tabs/account/nested/1" id="goto-tab1-page2">Go to Page 2</ion-button>
<ion-button routerLink="/tabs/lazy/nested" id="goto-tab3-page2">Go to Tab 3 - Page 2</ion-button>
<ion-button routerLink="/nested-outlet/page" id="goto-nested-page1">Go to nested</ion-button>
</p>

View File

@@ -1,7 +1,24 @@
import { Component } from '@angular/core';
import { Component, NgZone } from '@angular/core';
@Component({
selector: 'app-tabs-tab1',
templateUrl: './tabs-tab1.component.html',
})
export class TabsTab1Component { }
export class TabsTab1Component {
title = 'ERROR';
segment = 'one';
changed = 'false';
ionViewWillEnter() {
NgZone.assertInAngularZone();
setTimeout(() => {
NgZone.assertInAngularZone();
this.title = 'Tab 1 - Page 1';
});
}
segmentChanged(ev: any) {
console.log('Segment changed', ev);
this.changed = 'true';
}
}

View File

@@ -1,14 +1,21 @@
<ion-header>
<ion-toolbar>
<ion-title>Tab 2 - Page 1</ion-title>
<ion-title>{{title}}</ion-title>
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-content class="ion-padding">
<h1>Welcome to Tab 2</h1>
<ion-segment [(ngModel)]="segment" (ionChange)="segmentChanged($event)">
<ion-segment-button value="one">One</ion-segment-button>
<ion-segment-button value="two">Two</ion-segment-button>
</ion-segment>
<p>
Segment changed: <span class="segment-changed">{{changed}}</span>
</p>
<p>
<ion-button routerLink="/tabs/account" id="goto-tab1-page1">Go to Tab 1 - Page 1</ion-button>
<ion-button routerLink="/tabs/account/nested/12" id="goto-tab1-page2">Go to Tab 1 - Page 2</ion-button>
<ion-button routerLink="/tabs/account/nested/1" id="goto-tab1-page2">Go to Tab 1 - Page 2</ion-button>
<ion-button routerLink="/nested-outlet/page" id="goto-nested-page1">Go to nested</ion-button>
</p>
</ion-content>

View File

@@ -1,7 +1,24 @@
import { Component } from '@angular/core';
import { Component, NgZone } from '@angular/core';
@Component({
selector: 'app-tabs-tab2',
templateUrl: './tabs-tab2.component.html',
})
export class TabsTab2Component { }
export class TabsTab2Component {
title = 'ERROR';
segment = 'two';
changed = 'false';
ngOnInit() {
NgZone.assertInAngularZone();
setTimeout(() => {
NgZone.assertInAngularZone();
this.title = 'Tab 2 - Page 1';
});
}
segmentChanged(ev: any) {
console.log('Segment changed', ev);
this.changed = 'true';
}
}

View File

@@ -0,0 +1,27 @@
import { IonicModule } from '@ionic/angular';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { TabsPageRoutingModule } from './tabs.router.module';
import { TabsComponent } from './tabs.component';
import { TabsTab1Component } from '../tabs-tab1/tabs-tab1.component';
import { TabsTab2Component } from '../tabs-tab2/tabs-tab2.component';
import { TabsTab1NestedComponent } from '../tabs-tab1-nested/tabs-tab1-nested.component';
@NgModule({
imports: [
IonicModule,
CommonModule,
FormsModule,
TabsPageRoutingModule
],
declarations: [
TabsComponent,
TabsTab1Component,
TabsTab2Component,
TabsTab1NestedComponent
]
})
export class TabsPageModule {}

View File

@@ -0,0 +1,52 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { TabsComponent } from './tabs.component';
import { TabsTab1NestedComponent } from '../tabs-tab1-nested/tabs-tab1-nested.component';
import { TabsTab1Component } from '../tabs-tab1/tabs-tab1.component';
import { TabsTab2Component } from '../tabs-tab2/tabs-tab2.component';
const routes: Routes = [
{
path: '',
component: TabsComponent,
children: [
{
path: 'account',
children: [
{
path: 'nested/:id',
component: TabsTab1NestedComponent
},
{
path: '',
component: TabsTab1Component
}
]
},
{
path: 'contact',
children: [
{
path: 'one',
component: TabsTab2Component
},
{
path: '',
redirectTo: 'one',
pathMatch: 'full'
}
]
},
{
path: 'lazy',
loadChildren: () => import('../tabs-lazy/tabs-lazy.module').then(m => m.TabsLazyModule)
}
]
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class TabsPageRoutingModule {}

View File

@@ -5,7 +5,7 @@
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-content class="ion-padding">
<ion-slides>
<ion-slide #slide>
<ion-button id="color-button">Hello! it's a button</ion-button>

View File

@@ -7,11 +7,11 @@ import { IonTabs, IonButton, IonSlides, IonSlide } from '@ionic/angular';
})
export class ViewChildComponent implements AfterViewInit {
@ViewChild(IonSlides) slides: IonSlides;
@ViewChild(IonButton) button: IonButton;
@ViewChild(IonTabs) tabs: IonTabs;
@ViewChild('div') div: ElementRef;
@ViewChild('slide') slide: IonSlide;
@ViewChild(IonSlides, { static: true }) slides: IonSlides;
@ViewChild(IonButton, { static: true }) button: IonButton;
@ViewChild(IonTabs, { static: true }) tabs: IonTabs;
@ViewChild('div', { static: true }) div: ElementRef;
@ViewChild('slide', { static: true }) slide: IonSlide;
ngAfterViewInit() {
const loaded = !!(this.slides && this.button && this.tabs && this.div && this.slide);

View File

@@ -7,7 +7,7 @@
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-content class="ion-padding">
<h1>Item {{itemNu}}</h1>
<p>ngOnInit: <span id="ngOnInit">{{onInit}}</span></p>
<p>ionViewWillEnter: <span id="ionViewWillEnter">{{willEnter}}</span></p>

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