Compare commits

..

333 Commits

Author SHA1 Message Date
Manu Mtz.-Almeida
85245b6a97 4.0.0-alpha.3 2018-04-23 17:51:23 +02:00
Manu Mtz.-Almeida
51ac33192b chore(): update to latest stencil 2018-04-23 17:46:44 +02:00
Manu Mtz.-Almeida
d5129df970 fix(all): strong typed events 2018-04-23 17:26:10 +02:00
Brandy Carney
b8c87c453a docs(breaking): add navbar and back button, alphabetize 2018-04-22 14:11:57 -04:00
Manu Mtz.-Almeida
ae0541a465 chore(): update dependencies 2018-04-22 20:08:02 +02:00
Manu Mtz.-Almeida
3f8fcda366 test(toggle): adds unit tests 2018-04-22 20:03:10 +02:00
Manu Mtz.-Almeida
c929dad2e9 fix(angular): adds missing events 2018-04-22 17:01:29 +02:00
Manu Mtz.-Almeida
822f60f603 test(angular): adds test for explicit routerDirection 2018-04-20 17:20:13 +02:00
Manu Mtz.-Almeida
c87f0c561e fix(angular): Config provider 2018-04-20 17:06:35 +02:00
Manu Mtz.-Almeida
2b3c14b608 fix(angular): platform ready() 2018-04-20 16:08:38 +02:00
Manu Mtz.-Almeida
4ea8881f33 refactor(all): enable strictPropertyInitialization 2018-04-19 18:48:38 +02:00
Manu Mtz.-Almeida
78bd146ad2 fix(prerender): local references to window/document 2018-04-19 13:26:49 +02:00
Manu Mtz.-Almeida
86a6cde4a1 perf(platform): remove from critical path 2018-04-18 23:06:56 +02:00
Manu Mtz.-Almeida
861ce49363 chore(): update to latest stencil 2018-04-18 21:42:18 +02:00
Brandy Carney
20a8eec992 docs(item): update item documentation and add usage 2018-04-18 11:58:21 -06:00
Brandy Carney
2aa2e6f3ca docs(components): update grammar and docs 2018-04-18 11:58:21 -06:00
Josh Thomas
cccdb42fbd chore(): change usage of Build.isDev so that buble does not act out. 2018-04-17 13:53:34 -05:00
Manu Mtz.-Almeida
43d7538e66 fix(overlay): cssClasses applied to overlay 2018-04-17 18:58:28 +02:00
Manu Mtz.-Almeida
099b3edda3 feat(angular): animation is explicit 2018-04-16 21:01:33 +02:00
Manu Mtz.-Almeida
c1cbbc52d2 fix(virtual-scroll): queue.write 2018-04-14 11:45:08 +02:00
Manu Mtz.-Almeida
ab2e124528 4.0.0-alpha.2 2018-04-14 01:41:44 +02:00
Manu Mtz.-Almeida
9436723a8c chore(): update package-lock 2018-04-14 01:37:09 +02:00
Adam Bradley
a47f138b31 chore(angular): update angular proxy 2018-04-13 15:10:22 -05:00
Adam Bradley
3f0d6f1871 chore(package): update to stencil 0.7.24 2018-04-13 14:54:15 -05:00
Manu Mtz.-Almeida
9c11155732 test(tabs): update tests 2018-04-13 18:35:14 +02:00
Manu Mtz.-Almeida
fde878baf3 fix(label): inline position by default 2018-04-13 17:36:33 +02:00
Manu Mtz.-Almeida
b1ee4b8e3a fix(label): using prop for position
also fixes #14288
2018-04-13 17:03:46 +02:00
Manu Mtz.-Almeida
641113f161 chore(): update to latest stencil 2018-04-13 15:02:40 +02:00
Manu Mtz.-Almeida
8ad3df9736 fix(angular): viewContainer in overlays 2018-04-13 15:01:17 +02:00
Manu Mtz.-Almeida
db5313e45b fix(angular): icon proxy 2018-04-13 15:01:17 +02:00
Manu Mtz.-Almeida
47e6009901 WIP 2018-04-13 15:01:16 +02:00
Adam Bradley
c8071dd2ed docs(): update auto-generated docs 2018-04-12 11:13:07 -05:00
Adam Bradley
91ccc86a52 chore(components): update components.d.ts 2018-04-12 11:12:35 -05:00
Adam Bradley
bceece7bc1 feat(DomController): add DomController provider using stencil queue 2018-04-12 11:12:12 -05:00
ghybs
b1778102fc docs(item-sliding): readme replace side values
in description sides "left" and "right" are now "start" and "end".
Add a link to `ion-item-options` where the exact effect of those values is described.
2018-04-12 00:09:53 +02:00
ghybs
3df6e94650 docs(item-options): readme add table for side
description and replace "left" and "right" obsolete values by new "start" and "end" values.
2018-04-12 00:09:53 +02:00
ghybs
27fae3b70d docs(item-options): side values renamed start/end
instead of left/right.
2018-04-12 00:09:53 +02:00
mhartington
b6348ca075 chore(): bump angular 2018-04-11 23:59:04 +02:00
mhartington
5899b0392d feat(router): dont reuse the component if the params are different
This matches v3 functionality
2018-04-11 23:59:04 +02:00
Manu Mtz.-Almeida
54d7a12bea feat(routerDirection): refactors goBack 2018-04-11 22:47:15 +02:00
Adam Bradley
d623b3b71f feat(queue): use stencil's queue controller for dom read/writes 2018-04-11 15:24:49 -05:00
Manu Mtz.-Almeida
6a31f3960a feat(angular): adds DomController
fix #14286
2018-04-11 21:39:14 +02:00
Manu Mtz.-Almeida
12a27bc9d0 fix(angular): using es2017 types 2018-04-11 21:16:01 +02:00
Manu Mtz.-Almeida
02c1e83096 fix(angular): emit es5 code 2018-04-11 21:13:44 +02:00
Manu Mtz.-Almeida
a203534b27 fix(fab): fix fab activation 2018-04-11 20:58:01 +02:00
Brandy Carney
49e5b7e016 docs(app): add documentation for ion-app 2018-04-11 13:08:07 -04:00
Brandy Carney
229ee845da chore(stencil): update to latest 2018-04-11 11:26:34 -04:00
Brandy Carney
3a2c90416c docs(breaking): add item options breaking changes 2018-04-11 11:26:00 -04:00
Kevin Groat
e40a6b0e94 fix(react): FrameworkDelegate matches API 2018-04-11 16:31:07 +02:00
Brandy Carney
2c9d485d2d docs(buttons): add documentation and usage 2018-04-10 18:26:56 -04:00
Brandy Carney
89b46ac52f docs(button): match style guide and add usage 2018-04-10 18:26:56 -04:00
Brandy Carney
9b9aab9f2b docs(badge): add usage 2018-04-10 18:26:56 -04:00
Manu Mtz.-Almeida
850d7fc74d fix(angular): change detection in deep ViewContainers 2018-04-10 23:51:59 +02:00
Manu Mtz.-Almeida
4d23cba8a0 feat(angular): push/setRoot/pop 2018-04-10 23:51:36 +02:00
Manu Mtz.-Almeida
81dc67dda4 chore(): update to stencil 0.7.20 2018-04-10 19:16:32 +02:00
Manu Mtz.-Almeida
5c91101949 fix(angular): router-outlet uses stack by default 2018-04-10 19:15:35 +02:00
Manu Mtz.-Almeida
fd5c957787 refactor(all): enable ts strict 2018-04-10 02:43:48 +02:00
Manu Mtz.-Almeida
ea24ad677d fix(props): update stencil 2018-04-10 00:14:10 +02:00
Manu Mtz.-Almeida
22ebbce57f fix(angular): add NavParams 2018-04-10 00:14:09 +02:00
mhartington
d98421461e fix(toast): account for safe-area on ios 2018-04-09 15:35:19 -04:00
Brandy Carney
e02f9902a5 style(item): add spacing 2018-04-09 11:25:36 -04:00
Brandy Carney
2bfcc4f0a9 docs(breaking): fix markdown to use bold properly 2018-04-09 11:25:36 -04:00
Brandy Carney
eba40e8961 docs(back-button): update the main docs and add usage 2018-04-09 11:25:36 -04:00
Brandy Carney
5f4250b8b5 fix(back-button): get the back button color working
refactors the structure / classes of back button to match the default
button more
2018-04-09 11:25:35 -04:00
Manu Mtz.-Almeida
5f9b74ca38 refactor(haptic): pure module 2018-04-08 17:18:07 +02:00
Adam Bradley
fcb08e1642 fix(mode): set mode css class on ion-app 2018-04-06 22:46:10 -05:00
Manu Mtz.-Almeida
a1a3c7d37d 4.0.0-alpha.1 2018-04-06 17:34:10 +02:00
Manu Mtz.-Almeida
d85e17c730 chore(package): lock 2018-04-06 17:28:07 +02:00
Manu Mtz.-Almeida
b1de56a41c chore(): update to latest stencil 2018-04-06 17:21:59 +02:00
Manu Mtz.-Almeida
64a9497f72 fix(angular): proxy outputs 2018-04-06 16:58:27 +02:00
Manu Mtz.-Almeida
5e98939a70 chore(): update to latest stencil 2018-04-06 16:39:07 +02:00
Manu Mtz.-Almeida
79ba6391d6 fix(angular): change detection 2018-04-06 16:19:32 +02:00
Manu Mtz.-Almeida
a3cd5db3a7 fix(menu): prerender 2018-04-06 11:33:09 +02:00
Manu Mtz.-Almeida
c6e962c387 fix(split-pane): prerender 2018-04-06 11:33:09 +02:00
Manu Mtz.-Almeida
5153da458c fix(angular): proxy methods 2018-04-06 11:33:09 +02:00
Brandy Carney
b7395d5f0e docs(backdrop): spell propagation correctly 2018-04-05 15:40:28 -04:00
Brandy Carney
80a94401fb docs(backdrop): update docs and add usage 2018-04-05 15:38:18 -04:00
Brandy Carney
b5f5812bb4 docs(breaking): add a file to redirect to the new directory 2018-04-05 13:10:52 -04:00
Brandy Carney
dc326c3887 chore(angular): move breaking changes document to angular directory 2018-04-05 13:03:35 -04:00
Brandy Carney
6072a6e5ac docs(usage): add usage docs for avatar, text, thumbnail 2018-04-05 13:02:52 -04:00
Brandy Carney
5e0965260f docs(segment): add usage for segment and segment button 2018-04-05 11:33:04 -04:00
Manu Mtz.-Almeida
2c5f5b3fe1 0.2.2 2018-04-05 15:44:49 +02:00
Manu Mtz.-Almeida
ddf2f2220d chore(scripts): using npm ci 2018-04-05 15:41:20 +02:00
Manu Mtz.-Almeida
2215c6aaa1 fix(scripts): improve script 2018-04-05 15:24:50 +02:00
Manu Mtz.-Almeida
3ba506c513 chore(angular): update proxies 2018-04-05 15:03:20 +02:00
Manu Mtz.-Almeida
1bbd73cada chore(): update some dependencies 2018-04-05 14:32:18 +02:00
Manu Mtz.-Almeida
25c852c2c8 fix(ripple-effect): animation 2018-04-05 14:28:43 +02:00
Adam Bradley
f3b8ddb69d chore(package): update to stencil 0.7.15 2018-04-04 21:34:29 -05:00
Manu Mtz.-Almeida
1db75aa72c chore(): update dependencies 2018-04-05 01:58:43 +02:00
Ken Sodemann
9eb315fc05 chore(bot): fix spelling error 2018-04-04 17:21:10 -05:00
Ken Sodemann
8d13940188 chore(bot): add tasks for moving issues to other repos 2018-04-04 16:56:13 -05:00
Brandy Carney
d07246d7a0 style(sass): fix lint errors 2018-04-04 16:19:52 -04:00
Ross Gerbasi
3471dd66f7 fix(sass): add missing alert css properties (#14269)
fixes #14258
2018-04-04 16:15:33 -04:00
Mike Hartington
57fbf6c396 fix(back-button): fix menu and back button alignment (#14268)
* fix(): fix menu and back button alignment

* fix(button): remove button-text span
2018-04-04 15:39:35 -04:00
Brandy Carney
c15772651a test(back-button): add a page with a menu and back button 2018-04-04 15:38:32 -04:00
Manu Mtz.-Almeida
a436fdf201 Merge branch 'master' of github.com:ionic-team/ionic 2018-04-04 21:19:08 +02:00
Manu Mtz.-Almeida
d23108a16c fix(script): release script pushes tags 2018-04-04 21:18:42 +02:00
Brandy Carney
2e5a6d6120 docs(select): update select readme and add usage docs 2018-04-04 13:02:00 -04:00
Brandy Carney
0a0959b3a7 fix(select): wrap the text for the message in a popover 2018-04-04 13:02:00 -04:00
Brandy Carney
219589598d fix(select): pass header and subHeader to interfaces 2018-04-04 13:02:00 -04:00
Manu Mtz.-Almeida
6ecbe03b4f 0.2.1 2018-04-04 17:40:23 +02:00
Manu Mtz.-Almeida
904af3901b chore(scripts): fix script 2018-04-04 16:57:55 +02:00
Manu Mtz.-Almeida
974b949754 fix(scripts): update dep version 2018-04-04 16:52:01 +02:00
Manu Mtz.-Almeida
bb46b5f7b9 fix(angular): back-button does not push view 2018-04-04 16:33:20 +02:00
Manu Mtz.-Almeida
4db687ea17 fix(angular): back button prevents default 2018-04-04 00:06:38 +02:00
Manu Mtz.-Almeida
7e97006753 fix(angular): tabs flickering 2018-04-04 00:06:38 +02:00
Brandy Carney
11cb42facb fix(app): hide elements 2018-04-03 16:59:18 -04:00
Brandy Carney
6c8960abdd docs(toolbar): update readme and add usage 2018-04-03 16:59:18 -04:00
Manu Mtz.-Almeida
09e6b7e4a2 feat(angular): href integration 2018-04-03 18:51:32 +02:00
Manu Mtz.-Almeida
926c8859ce docs(breaking): alert, actionsheet 2018-04-03 18:49:53 +02:00
Manu Mtz.-Almeida
ae2cae635d refactor(tabs): rename [tabTitle] -> [label] 2018-04-03 13:37:18 +02:00
Manu Mtz.-Almeida
1f78390c84 fix(angular): back-button 2018-04-03 13:37:17 +02:00
Brandy Carney
685d5a166c docs(overlays): add usage by framework 2018-04-02 18:37:33 -04:00
Manu Mtz.-Almeida
3d6a6bad8f 0.2.0 2018-04-02 22:14:31 +02:00
Manu Mtz.-Almeida
14fedb9a44 fix(angular): URL based tabs 2018-04-02 21:20:59 +02:00
Manu Mtz.-Almeida
5878ad9587 0.1.6 2018-04-02 20:31:31 +02:00
Manu Mtz.-Almeida
14f01177f9 test(nav): fix tests 2018-04-02 20:26:50 +02:00
Manu Mtz.-Almeida
a5e5403068 refactor(overlays): [title] -> [header] 2018-04-02 20:22:15 +02:00
Manu Mtz.-Almeida
acd411dd6c fix(angular): modal and popover 2018-04-02 18:34:42 +02:00
Manu Mtz.-Almeida
af240a9ffa refactor(animation): strict ts 2018-04-02 17:52:55 +02:00
Peter Blazejewicz
7aa5d059ad docs(readme): fix minor typos in readmes (#14259) 2018-04-02 10:11:27 -04:00
Manu Mtz.-Almeida
f237b7f3a9 Merge branch 'master' of github.com:ionic-team/ionic 2018-04-01 18:10:42 +02:00
Manu Mtz.-Almeida
853e55388b refactor(nav): simplify ViewController 2018-04-01 18:09:26 +02:00
Adam Bradley
0793d2bf5e test(ngIf): add angular ngIf test 2018-03-31 20:37:50 -05:00
Manu Mtz.-Almeida
ff06dab3c0 fix(router-outlet): mutable prop 2018-03-31 16:15:13 +02:00
Manu Mtz.-Almeida
0d44253da1 fix(router-outlet): enteringEl !== leavingEl 2018-03-31 00:00:05 +02:00
Manu Mtz.-Almeida
ff1ed888f0 fix(angular): tabs angular tests 2018-03-30 23:30:31 +02:00
Manu Mtz.-Almeida
230823915c fix(angular): proxies 2018-03-30 22:33:58 +02:00
Manu Mtz.-Almeida
cece447092 fix(angular): module exports 2018-03-30 21:54:46 +02:00
Brandy Carney
b35f95a4d8 refactor(app): use font-smoothing mixin 2018-03-30 12:53:20 -04:00
Daniel Sogl
238b7f9877 chore(angular): bump deps 2018-03-30 18:50:17 +02:00
Brandy Carney
31de300256 chore(sass): update the sass lint task and change warnings to error 2018-03-30 12:46:36 -04:00
Manu Mtz.-Almeida
062641d8ca fix(angular): lifecycles 2018-03-30 18:45:48 +02:00
Brandy Carney
f1987b6403 Revert "style(app): add empty function to break tslint"
This reverts commit 94646fc81e.
2018-03-30 12:27:36 -04:00
Brandy Carney
7923b55b84 chore(lint): use && in the lint task 2018-03-30 12:24:30 -04:00
Brandy Carney
3aa55bec17 chore(lint): remove the -q flag from sass-lint 2018-03-30 11:30:58 -04:00
Brandy Carney
94646fc81e style(app): add empty function to break tslint 2018-03-30 11:25:24 -04:00
Ross Gerbasi
6c6f867ce4 refactor(sass): tweaks to the alpha css variables (#14223)
* alpha tweaks

* added alpha-input
cleanup for theme-builder

* removed global variables

* style(searchbar): fix indentation

closes #14196
2018-03-30 10:27:58 -04:00
Masahiko Sakakibara
7887550166 chore(github): add Ionic version 4.x to PR template (#14219) 2018-03-29 16:31:37 -04:00
Brandy Carney
aa085248b9 test(button): this is why you should be careful using find and replace 2018-03-29 16:26:17 -04:00
Masahiko Sakakibara
1508af4df8 refactor(app): remove negative margin from headings 2018-03-29 16:26:17 -04:00
Manu Mtz.-Almeida
172cf25380 chore(scripts): fix release scripts 2018-03-29 20:59:04 +02:00
Manu Mtz.-Almeida
d11bb1ed61 0.1.5 2018-03-29 20:57:46 +02:00
Manu Mtz.-Almeida
9c789ceac4 fix(angular): ion-back-button 2018-03-29 20:46:13 +02:00
Manu Mtz.-Almeida
7b9a00e433 fix(angular): goback navigation 2018-03-29 18:41:56 +02:00
Manu Mtz.-Almeida
a36913e9db refactor(all): data -> componentProps 2018-03-29 18:41:56 +02:00
Adam Bradley
ce500858fe chore(docs): add build docs script 2018-03-29 09:28:19 -05:00
Manu Mtz.-Almeida
1f74d8dcd7 refactor(tap-click): remove duplicated method 2018-03-29 16:17:33 +02:00
Manu Mtz.-Almeida
74e4b323ac refactor(item): [tappable] -> [button] 2018-03-29 16:17:16 +02:00
Brandy Carney
9caeec7fcf fix(components): add font-smoothing to mixing components 2018-03-28 19:57:25 -04:00
Brandy Carney
d9d7462d87 chore(lint): update lint tasks 2018-03-28 18:26:14 -04:00
Brandy Carney
a1346a9e89 style(sass): update sass linters and fix lint errors 2018-03-28 18:24:05 -04:00
Brandy Carney
88752dea51 style(sass): move font smooth to mixin and remove webkit properties
autoprefixer is adding the backdrop-filter for us now
2018-03-28 18:24:04 -04:00
Brandy Carney
54558c92af fix(thumbnail): adjust wide images to fill instead of squish 2018-03-28 18:24:04 -04:00
Brandy Carney
b0f8ca544d fix(avatar): adjust wide images to fill instead of squish 2018-03-28 18:24:04 -04:00
Brandy Carney
093feac6e4 docs(alert): add javascript and angular example docs 2018-03-28 18:24:04 -04:00
Adam Bradley
2fa4623506 chore(package): update to stencil 0.7.10 2018-03-28 16:52:41 -05:00
Adam Bradley
53b6471d2b chore(release): rename release script 2018-03-28 16:20:20 -05:00
Adam Bradley
f304480dfc chore(deploy): update deploy scripts 2018-03-28 15:35:31 -05:00
Brandy Carney
a5d2a33016 docs(action-sheet): rename docs directory to usage 2018-03-28 12:25:10 -04:00
Brandy Carney
67488b2eca docs(action-sheet): add javascript and angular example docs 2018-03-28 12:20:30 -04:00
Adam Bradley
0105a4ee47 refactor(tab): rename tab properties 2018-03-28 10:12:04 -05:00
Adam Bradley
b1b3c19908 test(tabs): update angular simple tabs test 2018-03-28 08:17:55 -05:00
Adam Bradley
eff2ef3892 chore(package): update to stencil 0.7.9 2018-03-28 08:17:10 -05:00
Manu Mtz.-Almeida
d57122c382 fix(ripple-effect): tapclick is required in ionic 2018-03-27 23:45:53 +02:00
Manu Mtz.-Almeida
b70837278d 0.1.5-4 2018-03-27 23:43:44 +02:00
Manu Mtz.-Almeida
c31bcde720 fix(menu): default menu mode 2018-03-27 23:07:56 +02:00
Manu Mtz.-Almeida
5007c78a40 0.1.5-3 2018-03-27 23:02:10 +02:00
Manu Mtz.-Almeida
011a374f6b fix(nav): transition name 2018-03-27 22:58:04 +02:00
Brandy Carney
98403fa883 docs(components): update menu and breaking changes 2018-03-27 16:47:23 -04:00
Brandy Carney
ce5b47ef99 refactor(toolbar): rename the slots to match other component behavior
`left` -> `start`
`right` -> `end`
`start` -> `secondary`
`end` -> `primary`
2018-03-27 16:45:26 -04:00
Brandy Carney
6fbd708ae0 refactor(list): rename methods and update docs 2018-03-27 16:45:26 -04:00
Brandy Carney
3f68031a09 docs(datetime): update the datetime docs 2018-03-27 16:45:26 -04:00
Manu Mtz.-Almeida
57a5d490a6 fix(nav): animated opts 2018-03-27 21:26:35 +02:00
Manu Mtz.-Almeida
726938f67c fix(angular): stack based navigation 2018-03-27 19:51:08 +02:00
Manu Mtz.-Almeida
46bbd0fdf8 feat(nav-controller): goback best guess 2018-03-27 17:13:57 +02:00
Manu Mtz.-Almeida
862e5719c6 feat(nav): goBack directive 2018-03-27 14:55:31 +02:00
Adam Bradley
49937eb98c test(tabs): add lazy load ng-router angular tabs 2018-03-27 07:28:39 -05:00
Manu Mtz.-Almeida
4fdfddb6b8 fix(nav): no animation 2018-03-27 12:36:37 +02:00
Manu Mtz.-Almeida
113af9e53b fix(router): ion-nav 2018-03-27 12:05:30 +02:00
Manu Mtz.-Almeida
00fc460c4e feat(button): goback attribute 2018-03-27 12:05:30 +02:00
Adam Bradley
a428fdc48c test(angular): simple ng tabs test 2018-03-27 01:23:28 -05:00
Adam Bradley
7677e4f78a test(tabs): static angular tabs 2018-03-26 21:14:44 -05:00
Manu Mtz.-Almeida
9e9f2a206f fix(router): route change detection 2018-03-27 01:32:47 +02:00
Manu Mtz.-Almeida
b26a56314b fix(router): wait RAF 2018-03-27 01:28:49 +02:00
Manu Mtz.-Almeida
a718f7e1e3 fix(router): change detection for componentProps 2018-03-27 00:57:50 +02:00
Manu Mtz.-Almeida
ffaec1661a fix(router): loging 2018-03-26 23:43:44 +02:00
Manu Mtz.-Almeida
c9d2a0d33b fix(toolbar): unused private 2018-03-26 23:43:43 +02:00
Manu Mtz.-Almeida
8b4b5ba633 test(nav): fix tests 2018-03-26 23:43:43 +02:00
Manu Mtz.-Almeida
d0c5f53a08 fix(button): dynamic bar-button 2018-03-26 23:43:43 +02:00
Adam Bradley
1efc0f3a94 chore(package): update to stencil 0.7.8 2018-03-26 16:34:31 -05:00
Adam Bradley
ac4ab0d767 test(angular): update ionic/angular test app 2018-03-26 16:34:09 -05:00
Adam Bradley
97f1158cbc refactor(angular): refactor ionic/angular modules 2018-03-26 16:33:40 -05:00
Adam Bradley
a1eabecc61 chore(): update angular build scripts 2018-03-26 16:31:40 -05:00
Manu Mtz.-Almeida
dddaee1719 fix(router): fixes navChanged() 2018-03-26 22:07:00 +02:00
Ken Sodemann
076b7e55bd chore(issue-bot): do the stale closes for real 2018-03-26 12:13:54 -05:00
Ken Sodemann
944140ce80 chore(issue-bot): dry run the stale issue bot 2018-03-26 09:57:17 -05:00
Manu Mtz.-Almeida
77fc792644 feat(ripple): css variable color 2018-03-24 03:57:18 +01:00
Manu Mtz.-Almeida
08f5976a57 chore(): update components.d.ts 2018-03-24 03:27:28 +01:00
Manu Mtz.-Almeida
153f8ca02c feat(menu-controller): expose registerAnimation 2018-03-24 03:27:28 +01:00
Manu Mtz.-Almeida
e6818369ff perf(app): platform is not needed 2018-03-24 03:27:27 +01:00
Manu Mtz.-Almeida
48d1bd412c feat(tab): framework support 2018-03-24 03:27:27 +01:00
Manu Mtz.-Almeida
44f343d3dc fix(toast): dismiss timeout 2018-03-24 03:27:27 +01:00
Manu Mtz.-Almeida
e20f76c3b1 refactor(all): async/await 2018-03-24 03:27:27 +01:00
Ken Sodemann
ee1aaafd73 chore(issues): change the close and lock setup 2018-03-23 14:39:55 -05:00
Manu Mtz.-Almeida
37345eee74 @ionic/core 0.1.5-2 2018-03-23 20:34:44 +01:00
Manu Mtz.-Almeida
d86ee1f772 chore(): update to latest stencil 2018-03-23 20:27:57 +01:00
Manu Mtz.-Almeida
095f9c832e fix(transition): nav ios transition 2018-03-23 20:27:57 +01:00
Brandy Carney
574c346d45 revert(toolbar): revert to use old button attributes
references #14172
2018-03-23 14:39:13 -04:00
Manu Mtz.-Almeida
2b8e489f84 fix(back-button): ios style 2018-03-23 11:11:41 +01:00
Manu Mtz.-Almeida
ce09978eee fix(covers): absolute positioning 2018-03-22 22:17:53 +01:00
Manu Mtz.-Almeida
9836c60dae docs(scripts): deploy 2018-03-22 20:17:57 +01:00
Manu Mtz.-Almeida
7a26162c5b fix(router): explicit goback should not push 2018-03-22 19:11:10 +01:00
Manu Mtz.-Almeida
69a6f8d012 feat(config): add set to config 2018-03-22 19:11:10 +01:00
Manu Mtz.-Almeida
eb0ff2f09d fix(back-button): empty text is a valid value 2018-03-22 19:11:09 +01:00
Brandy Carney
02173484eb test(select): pass the right custom options 2018-03-22 12:41:08 -04:00
Brandy Carney
a9bd76adc6 fix(label): add missing text-wrap styles for ios
fixes #13157
2018-03-22 12:41:08 -04:00
Manu Mtz.-Almeida
1f19cc48c7 0.1.5-1 2018-03-22 17:17:36 +01:00
Manu Mtz.-Almeida
59c6891249 fix(slides): unload slides correctly 2018-03-22 17:15:25 +01:00
Manu Mtz.-Almeida
1c06bfeaac fix(picker): do not scroll 2018-03-22 17:15:24 +01:00
Manu Mtz.-Almeida
5c2678f7ea feat(content): scrollEnabled 2018-03-22 17:15:24 +01:00
Manu Mtz.-Almeida
4fcddadcc9 fix(all): absolute positioning 2018-03-22 17:15:24 +01:00
Brandy Carney
b29fce1b8f fix(checkbox): update ios checkbox to be closer to native
this also updates the Sass variables so updating the checkbox width
will resize the inner checkmark
2018-03-22 11:05:23 -04:00
Brandy Carney
eae6869012 fix(item-option): remove outline on active/focus
fixes #14191
2018-03-22 11:05:23 -04:00
Adam Bradley
c2ce0f2d2d chore(package): update devDeps 2018-03-22 09:51:56 -05:00
Manu Mtz.-Almeida
59a0341104 chore(): remove prerelease increments 2018-03-22 15:03:45 +01:00
Manu Mtz.-Almeida
1a37493c79 @ionic/core 0.1.5-0 2018-03-22 15:01:44 +01:00
Manu Mtz.-Almeida
332eaaebb0 chore(scripts): adds prerelease 2018-03-22 14:57:45 +01:00
Manu Mtz.-Almeida
7b50ea974f chore(): improve publish scripts 2018-03-22 14:45:41 +01:00
Manu Mtz.-Almeida
6f5b86982c chore(all): release script improvement 2018-03-22 00:05:04 +01:00
Manu Mtz.-Almeida
2b8549bd3f 0.1.4 2018-03-21 23:59:25 +01:00
Manu Mtz.-Almeida
f904fd111b chore(all): monorepo release script 2018-03-21 23:53:25 +01:00
Brandy Carney
7d53e49912 fix(alert): update md alert to closer match spec
this also makes it so you can update the alert radio width and the
inner icon dot will resize and position properly

https://ionic-snapshot-go.appspot.com/ionic-core/snapshots/ye9/ccb/chrom
e_400x800
2018-03-21 17:11:19 -04:00
Manu Mtz.-Almeida
98b82537a9 test(nav): fix nav 2018-03-21 22:04:42 +01:00
Manu Mtz.-Almeida
72fab3665c chore(all): release script 2018-03-21 21:57:13 +01:00
Adam Bradley
814cf73a00 chore(package): init root build scripts 2018-03-21 14:14:52 -05:00
Adam Bradley
3829886a74 chore(): move demos/angular to angular/test 2018-03-21 14:05:02 -05:00
Adam Bradley
99610f7f08 chore(): remove react demo 2018-03-21 13:55:18 -05:00
Manu Mtz.-Almeida
943e2f73c0 fix(angular): router-outlet animation 2018-03-21 19:34:30 +01:00
Brandy Carney
f0a40fabb9 fix(action-sheet): update padding on title to match native 2018-03-21 13:58:58 -04:00
Manu Mtz.-Almeida
371fc19a06 fix(router): reusing checks params 2018-03-21 18:38:30 +01:00
Brandy Carney
605ec93179 fix(alert): update colors for alert text and input borders
references #14196
2018-03-21 13:16:47 -04:00
Brandy Carney
08553f1bac fix(chip): use lighter background color
references #14196
2018-03-21 13:07:19 -04:00
Brandy Carney
fc30ba18f3 test(preview): add preview tests for documentation previews 2018-03-21 12:18:18 -04:00
Brandy Carney
d26074a17f feat(fab): add box shadow and transition for ios 2018-03-21 12:18:18 -04:00
Manu Mtz.-Almeida
6e683c54e0 fix(router-outlet): css and change logic 2018-03-21 16:50:54 +01:00
Manu Mtz.-Almeida
a98c764541 chore(stencil): optimize bundles 2018-03-21 16:31:31 +01:00
Manu Mtz.-Almeida
ee27549c84 refactor(dom): attachComponent() 2018-03-21 16:22:59 +01:00
Manu Mtz.-Almeida
c03afabc0f feat(ion-router-outlet): adds router-outlet 2018-03-21 15:53:40 +01:00
Manu Mtz.-Almeida
17a3001af5 refactor(router): remove getContainerEl() 2018-03-21 15:53:40 +01:00
Manu Mtz.-Almeida
4693229c84 fix(all): ts strict (part 4) 2018-03-21 15:53:40 +01:00
Brandy Carney
779f02c932 docs(breaking): update the order and toc 2018-03-20 16:34:31 -04:00
Brandy Carney
e19b2142c5 refactor(component): update design to match the modes more 2018-03-20 15:54:33 -04:00
Brandy Carney
97dc113a9f test(button): remove the modified primary color 2018-03-20 15:44:44 -04:00
Manu Mtz.-Almeida
b49a45d81d fix(picker): does not scroll 2018-03-20 19:53:51 +01:00
Manu Mtz.-Almeida
7dbd42f9b2 0.1.4-9 2018-03-20 19:29:45 +01:00
Manu Mtz.-Almeida
fd0ceda0e9 chore(stencil): update to latest 2018-03-20 19:25:29 +01:00
Manu Mtz.-Almeida
9988c754ac fix(overlays): page is removed properly 2018-03-20 19:12:30 +01:00
Brandy Carney
769282935b test(e2e): update e2e tests to pass 2018-03-20 14:06:25 -04:00
Manu Mtz.-Almeida
9094c66f3d fix(angular): ion-nav no routing 2018-03-20 18:52:12 +01:00
Manu Mtz.-Almeida
f39d3ad9dd feat(angular): ion-nav 2018-03-20 18:00:37 +01:00
Brandy Carney
d3105d1a76 docs(breaking): add a section on the spinner name change 2018-03-20 12:57:44 -04:00
Brandy Carney
b49e9eb027 refactor(spinner): rename lines-sm to lines-small
also adds this spinner class to the infinite scroll to override the
color
2018-03-20 12:49:17 -04:00
Ross Gerbasi
f578122d15 fix(theming): update spinner classes to new names 2018-03-20 12:38:48 -04:00
Manu Mtz.-Almeida
41f54f8e2d fix(angular): removeViewFromDom 2018-03-20 17:21:02 +01:00
Manu Mtz.-Almeida
3a26256a5c chore(transition): expose transition 2018-03-20 17:16:41 +01:00
Manu Mtz.-Almeida
a73c461ed4 test(nav): tests for lifecycle events 2018-03-20 16:48:30 +01:00
Manu Mtz.-Almeida
06ad60ea0c fix(all): ts strict (part 3) 2018-03-20 16:48:30 +01:00
Brandy Carney
28215a3722 chore(stencil): update to latest 2018-03-20 11:41:55 -04:00
Brandy Carney
b82c38202f fix(back-button): use correct color for ios back button
closes #14177
2018-03-20 11:41:55 -04:00
Manu Mtz.-Almeida
f16a9672b4 refactor(nav): transitions 2018-03-20 14:12:25 +01:00
Manu Mtz.-Almeida
c85f7483c9 refactor(keyboard): move to utils 2018-03-20 14:12:25 +01:00
Brandy Carney
4d8a99f03b @ionic/core 0.1.4-8 2018-03-19 17:53:02 -04:00
Brandy Carney
e8cf9927cc refactor(toolbar): remove the mode-start and mode-end slots
- adds examples of the new way to achieve this in the e2e tests
- updates breaking change to document the new slots properly and with
examples
- removes the first-child margin on buttons in toolbar
- removes the margin on ion-buttons

closes #14172
2018-03-19 17:47:52 -04:00
Ken Sodemann
2afbd9dbb1 chore(issues): restore the issue template from v3 2018-03-19 11:47:18 -05:00
Manu Mtz.-Almeida
d8234e90dd docs(overlay): onDidDismiss 2018-03-19 17:10:52 +01:00
Manu Mtz.-Almeida
50abcf5ab3 feat(nav): support for rootParams 2018-03-19 17:10:51 +01:00
Ken Sodemann
176d4994d1 chore(ionitron): prepend the labels used to trigger ionitron 2018-03-19 10:33:16 -05:00
Brandy Carney
7d2de18a7c fix(back-button): apply the proper color to the back button
fixes #14177
2018-03-16 13:00:00 -04:00
Manu Mtz.-Almeida
a7373232da docs(router): adds some docs for ion-router 2018-03-16 14:24:10 +01:00
Manu Mtz.-Almeida
c41f9dd01c @ionic/core 0.1.4-7 prepared 2018-03-16 09:54:42 +01:00
Manu Mtz.-Almeida
2bdf4add5a feat(router): wildcard redirects 2018-03-15 21:48:29 +01:00
Manu Mtz.-Almeida
bb3f406ffc @ionic/core 0.1.4-6 prepared 2018-03-15 18:12:18 +01:00
Manu Mtz.-Almeida
207f416686 fix(router): fix selection 2018-03-15 18:07:29 +01:00
Manu Mtz.-Almeida
f48d817a85 fix(router): retuning string path 2018-03-15 17:09:59 +01:00
Manu Mtz.-Almeida
7c3cba0b92 feat(ion-router): dynamic routes 2018-03-15 17:01:19 +01:00
Ross Gerbasi
147a6090e4 refactor(theming): alpha color refactor and theme cleanup (#14161)
* Cleanup for iOS mode used in material variables
Refactor to alpha variables for colors in the color map
updated theme builder with new alpha variables
updated theme builder with duplicate default CSS modes

* moved alpha transform into css-var
removed ion-color-alpha
fixes for disabled css-variable mode
added defaults for user configurable variables

* revert to spinner related code
2018-03-15 11:53:48 -04:00
Manu Mtz.-Almeida
e729610dc8 fix(router): rename API to match stencil-router 2018-03-13 23:40:16 +01:00
Manu Mtz.-Almeida
b4f46ee3d2 fix(router): ambiguous routes 2018-03-13 23:33:31 +01:00
Manu Mtz.-Almeida
3b5f758318 fix(angular): create angular delegate 2018-03-13 22:17:12 +01:00
Manu Mtz.-Almeida
f398b3a945 fix(demos): fixes angular 2018-03-13 21:22:49 +01:00
Manu Mtz.-Almeida
9a0755a268 fix(angular): modal and popover support 2018-03-13 20:53:17 +01:00
Manu Mtz.-Almeida
6e2ca85b2a fix(overlays): OverlayController interface 2018-03-13 19:45:36 +01:00
Manu Mtz.-Almeida
cc4fecc1be fix(angular): fix overlays 2018-03-13 19:21:26 +01:00
Manu Mtz.-Almeida
de22ecae82 fix(alert): backdrop calls cancel handler 2018-03-13 17:13:55 +01:00
Manu Mtz.-Almeida
7dcf8a5bd4 feat(overlays): adds onDidDismiss and onWillDismiss 2018-03-13 16:34:24 +01:00
mhartington
73f2f2b2b2 chore(): rebuild lockfile for demo/angular 2018-03-13 10:10:17 -04:00
mhartington
c9f71dd2df chore(): rebuild lockfile for angular 2018-03-13 10:01:23 -04:00
mhartington
a5923d6eb2 chore(): rebuild lockfile 2018-03-13 09:54:35 -04:00
mhartington
30f2ac2286 chore(): update lerna 2018-03-13 09:50:57 -04:00
Amit Moryossef
ba63d01f78 perf(scss): optimize multi dir (#14156)
https://github.com/ionic-team/ionic/pull/12143
2018-03-12 18:01:51 -04:00
Brandy Carney
d37623a2ca chore(packages): move the packages to root 2018-03-12 16:02:25 -04:00
jgw96
097f1a2cd3 chore(readme): fix link to angular package 2018-03-12 14:54:52 -05:00
Brandy Carney
506b1ac53e docs(readme): add info on the v3 source move 2018-03-12 15:00:53 -04:00
mhartington
6e2a9c936d fix(alert): set input value 2018-03-12 12:51:19 -04:00
Brandy Carney
12c78bcb62 test(list): add inset list test to highlight the inconsistencies in MD 2018-03-12 12:41:18 -04:00
Manu Mtz.-Almeida
fcdf35565f test(virtual-scroll): infinite-scroll 2018-03-11 17:43:23 +01:00
Manu Mtz.-Almeida
7df023abb7 fix(toggle): ios shadow 2018-03-11 01:18:18 +01:00
Manu Mtz.-Almeida
cadcab9b40 refactor(nav): usign enums 2018-03-11 01:18:08 +01:00
Manu Mtz.-Almeida
22f6a34f5b fix(overlay): wrong stencil import 2018-03-10 20:05:11 +01:00
Manu Mtz.-Almeida
b56c2a83e5 fix(popover): lifecycles 2018-03-10 18:33:54 +01:00
Manu Mtz.-Almeida
0b099ce2b8 feat(overlay): adds lifecycle events 2018-03-10 18:25:11 +01:00
Manu Mtz.-Almeida
6383a54f35 refactor(overlays): move common code to overlay.ts 2018-03-10 18:08:26 +01:00
Manu Mtz.-Almeida
64f08669c2 fix(overlay): using hostData for zIndex 2018-03-10 01:50:18 +01:00
Manu Mtz.-Almeida
7dcefe345c refactor(helper): move functions 2018-03-10 01:41:09 +01:00
Manu Mtz.-Almeida
6b0327f2ef @ionic/core 0.1.4-5 2018-03-09 23:38:30 +01:00
Manu Mtz.-Almeida
1ace0450cb fix(router): tslint 2018-03-09 23:33:42 +01:00
Manu Mtz.-Almeida
f67100857b fix(item): button outline 2018-03-09 23:28:07 +01:00
Manu Mtz.-Almeida
f5c6333417 feat(router): adds redirectTo 2018-03-09 23:27:55 +01:00
Manu Mtz.-Almeida
88f2981044 fix(router): flickering 2 2018-03-09 20:16:38 +01:00
Manu Mtz.-Almeida
f2ac6e3064 fix(router): fix flickering 2018-03-09 20:16:38 +01:00
Perry Govier
b075ae0e71 chore(CI): add validation with Circle CI (#14129)
* giving new CI validation script a test run

* tidy up CI script in prep for PR

* seeing if validate runs fine with a `npm ci` install

* using newer/faster node

* does this version have new NPM?

* does node 9 have npm 5.7?

* seeing how forcing 5.7 compares on speed

* trying node 8.9 again

* sticking with 8.9, but ditching `npm ci` for now

* trying just 8 so I can see if it gets LTS updates

* benign commit to trigger a build ahead of PR
2018-03-09 12:28:42 -05:00
Brandy Carney
74e032a8cc @ionic/core 0.1.4-4 2018-03-08 17:07:22 -05:00
Manu Mtz.-Almeida
64a787a9de fix(back-button): implements back animation 2018-03-08 19:27:37 +01:00
Manu Mtz.-Almeida
8b6df5abbd fix(route): params is not undefined 2018-03-08 19:24:13 +01:00
Manu Mtz.-Almeida
743277eb6e chore(anchor): rename correctly 2018-03-08 19:12:50 +01:00
Manu Mtz.-Almeida
7b67342690 @ionic/core@0.1.4-3 2018-03-08 15:55:22 +01:00
Manu Mtz.-Almeida
5271f6845e feat(back-button): adds defaultHref 2018-03-08 15:30:46 +01:00
Manu Mtz.-Almeida
3ce8a67409 feat(router): reverse lookup with params 2018-03-08 14:02:28 +01:00
Manu Mtz.-Almeida
d1263a8b9c fix(router): passing params to ion-nav 2018-03-08 11:38:54 +01:00
Manu Mtz.-Almeida
1dad0adb03 refactor(tabs): tab matching 2018-03-08 10:51:18 +01:00
Manu Mtz.-Almeida
878d7e64b0 feat(nav): params 2018-03-08 10:50:18 +01:00
Manu Mtz.-Almeida
4a3030f087 feat(route): adds route-link 2018-03-08 01:42:17 +01:00
1529 changed files with 44398 additions and 60285 deletions

View File

@@ -1,12 +1,18 @@
<!-- Before submitting an issue, please consult our troubleshooting guide (http://ionicframework.com/docs/troubleshooting/) and developer resources (http://ionicframework.com/docs/developer-resources/) -->
<!-- Please make sure you are posting an issue pertaining to the Ionic Framework. If you are having an issue with the Ionic Pro services (Ionic View, Ionic Deploy, etc.) please consult the Ionic Pro support portal (http://support.ionicjs.com) -->
**Ionic version:** (check one with "x")
[ ] **1.x** (For Ionic 1.x issues, please use https://github.com/ionic-team/ionic-v1)
(For Ionic 1.x issues, please use https://github.com/ionic-team/ionic-v1)
[ ] **2.x**
[ ] **3.x**
[ ] **4.x**
**I'm submitting a ...** (check one with "x")
[ ] bug report
[ ] feature request
[ ] support request => Please do not submit support requests here, use one of these channels: https://forum.ionicframework.com/ or http://ionicworldwide.herokuapp.com/
<!-- Please do not submit support requests or "How to" questions here. Instead, please use one of these channels: https://forum.ionicframework.com/ or http://ionicworldwide.herokuapp.com/ -->
**Current behavior:**
<!-- Describe how the bug manifests. -->
@@ -15,17 +21,22 @@
<!-- Describe what the behavior would be without the bug. -->
**Steps to reproduce:**
<!-- If you are able to illustrate the bug or feature request with an example, please provide steps to reproduce and if possible a demo using one of the following templates:
For Ionic V1 issues - http://plnkr.co/edit/Xo1QyAUx35ny1Xf9ODHx?p=preview
For Ionic issues - http://plnkr.co/edit/z0DzVL?p=preview
-->
<!-- Please explain the steps required to duplicate the issue, especially if you are able to provide a sample application. -->
**Related code:**
<!-- If you are able to illustrate the bug or feature request with an example, please provide a sample application via one of the following means:
A sample application via GitHub
StackBlitz (https://stackblitz.com)
Plunker (http://plnkr.co/edit/cpeRJs?p=preview)
-->
```
insert any relevant code here
insert short code snippets here
```
**Other information:**
@@ -36,5 +47,3 @@ insert any relevant code here
```
insert the output from ionic info here
```

View File

@@ -7,6 +7,6 @@
-
-
**Ionic Version**: 1.x / 2.x / 3.x
**Ionic Version**: 1.x / 2.x / 3.x / 4.x
**Fixes**: #

View File

@@ -2,28 +2,69 @@ triage:
label: triage
dryRun: false
support:
label: support
closeAndLock:
labels:
- label: "ionitron: support"
message: >
Thanks for the issue! This issue appears to be a support request. We use this issue tracker exclusively for
bug reports and feature requests. Please use our [forum](https://forum.ionicframework.com) or our
[slack channel](https://ionicworldwide.herokuapp.com/) for questions about the framework.
Thank you for using Ionic!
- label: "ionitron: missing template"
message: >
Thanks for the issue! It appears that you have not filled out the provided issue template. We use this issue
template in order to gather more information and further assist you. Please create a new issue and ensure the
template is fully filled out.
Thank you for using Ionic!
close: true
lock: true
dryRun: false
stale:
days: 365
maxIssuesPerRun: 100
exemptLabels:
- good first issue
- triage
exemptProjects: true
exemptMilestones: true
label: "ionitron: stale issue"
message: >
Thanks for the issue! This issue appears to be a support request. We use this issue tracker exclusively for
bug reports and feature requests. Please use our [forum](https://forum.ionicframework.com) or our
[slack channel](https://ionicworldwide.herokuapp.com/) for questions about the framework.
Thanks for the issue! This issue is being closed due to inactivity. If this is still
an issue with the latest version of Ionic, please create a new issue and ensure the
template is fully filled out.
Thank you for using Ionic!
close: true
lock: true
dryRun: false
incomplete:
label: missing template
message: >
Thanks for the issue! It appears that you have not filled out the provided issue template. We use this issue
template in order to gather more information and further assist you. Please create a new issue and ensure the
template is fully filled out.
wrongRepo:
repos:
- label: "ionitron: cli"
repo: ionic-cli
message: >
Thanks for the issue! We use this issue tracker exclusively for bug reports and feature requests
associated with the Ionic Framework. It appears that this issue is associated with the Ionic CLI.
I am moving this issue to the Ionic CLI repository. Please track this issue over there.
Thank you for using Ionic!
Thank you for using Ionic!
- label: "ionitron: stencil"
repo: stencil
message: >
Thanks for the issue! We use this issue tracker exclusively for bug reports and feature requests
associated with the Ionic Framework. It appears that this issue is associated with Stencil.
I am moving this issue to the Stencil repository. Please track this issue over there.
Thank you for using Ionic!
close: true
lock: true
dryRun: false

4
.gitignore vendored
View File

@@ -18,8 +18,8 @@ dist/
node_modules/
tmp/
temp/
packages/core/theme-builder/
packages/core/test-components/
core/theme-builder/
core/test-components/
$RECYCLE.BIN/
.DS_Store

26
.scripts/README.md Normal file
View File

@@ -0,0 +1,26 @@
# Build Scripts
## Release
The deploy scripts at the root, make a new release of all the packages in this monorepo.
All packages will be released with the same version.
In order to make a new release:
1. `npm run release.prepare`
2. Review/update changelog
3. Commit updates using the package name and version number as the commit message.
4. `npm run release`
5. :tada:
## Prerelease
It's also possible to make prereleases of individual packages (@ionic/core, @ionic/angular).
In order to do so, move to the package you want to make a new release and execute:
```
npm run prerelease
```
It will publish a new prerelease in NPM, but it will not create any new git tag
or update the CHANGELOG.

73
.scripts/common.js Normal file
View File

@@ -0,0 +1,73 @@
const fs = require('fs-extra');
const path = require('path');
const execa = require('execa');
const Listr = require('listr');
const semver = require('semver');
const rootDir = path.join(__dirname, '../');
const packages = [
'core',
'angular'
];
function readPkg(project) {
const packageJsonPath = packagePath(project);
return JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
}
function writePkg(project, pkg) {
const packageJsonPath = packagePath(project);
const text = JSON.stringify(pkg, null, 2);
return fs.writeFileSync(packageJsonPath, text);
}
function packagePath(project) {
return path.join(rootDir, project, 'package.json');
}
function projectPath(project) {
return path.join(rootDir, project);
}
function checkGit(tasks) {
tasks.push(
{
title: 'Check current branch',
task: () => execa.stdout('git', ['symbolic-ref', '--short', 'HEAD']).then(branch => {
if (branch !== 'master') {
throw new Error(`Not on "master" 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.`);
}
})
},
{
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.`);
}
})
}
);
}
const isValidVersion = input => Boolean(semver.valid(input));
module.exports = {
isValidVersion,
readPkg,
writePkg,
rootDir,
projectPath,
checkGit,
packages
};

306
.scripts/prepare.js Normal file
View File

@@ -0,0 +1,306 @@
/**
* Deploy script adopted from https://github.com/sindresorhus/np
* MIT License (c) Sindre Sorhus (sindresorhus.com)
*/
const chalk = require('chalk');
const execa = require('execa');
const inquirer = require('inquirer');
const Listr = require('listr');
const fs = require('fs-extra');
const semver = require('semver');
const common = require('./common');
const path = require('path');
async function main() {
try {
const version = await askVersion();
// compile and verify packages
await preparePackages(common.packages, version);
console.log(`\nionic ${version} prepared 🤖\n`);
console.log(`Next steps:`);
console.log(` Verify CHANGELOG.md`);
console.log(` git commit -m "${version}"`);
console.log(` npm run release\n`);
} catch(err) {
console.log('\n', chalk.red(err), '\n');
process.exit(1);
}
}
async function askVersion() {
const pkg = common.readPkg('core');
const oldVersion = pkg.version;
const prompts = [
{
type: 'list',
name: 'version',
message: 'Select semver increment or specify new version',
pageSize: SEMVER_INCREMENTS.length + 2,
choices: SEMVER_INCREMENTS
.map(inc => ({
name: `${inc} ${prettyVersionDiff(oldVersion, inc)}`,
value: inc
}))
.concat([
new inquirer.Separator(),
{
name: 'Other (specify)',
value: null
}
]),
filter: input => isValidVersionInput(input) ? getNewVersion(oldVersion, input) : input
},
{
type: 'input',
name: 'version',
message: 'Version',
when: answers => !answers.version,
filter: input => isValidVersionInput(input) ? getNewVersion(pkg.version, input) : input,
validate: input => {
if (!isValidVersionInput(input)) {
return 'Please specify a valid semver, for example, `1.2.3`. See http://semver.org';
} else if (!isVersionGreater(oldVersion, input)) {
return `Version must be greater than ${oldVersion}`;
}
return true;
}
},
{
type: 'confirm',
name: 'confirm',
message: answers => {
return `Will bump from ${chalk.cyan(oldVersion)} to ${chalk.cyan(answers.version)}. Continue?`;
}
}
];
const {version} = await inquirer.prompt(prompts);
return version;
}
async function preparePackages(packages, version) {
// execution order matters
const tasks = [];
// check git is nice and clean local and remote
common.checkGit(tasks);
// test we're good with git
validateGit(tasks, version);
// add all the prepare scripts
// run all these tasks before updating package.json version
packages.forEach(package => {
preparePackage(tasks, package, version);
});
// add update package.json of each project
packages.forEach(package => {
updatePackageVersion(tasks, package, version);
});
// generate changelog
generateChangeLog(tasks);
const listr = new Listr(tasks, { showSubtasks: true });
await listr.run();
}
function validateGit(tasks, version) {
tasks.push(
{
title: `Validate git tag ${chalk.dim(`(v${version})`)}`,
task: () => execa('git', ['fetch'])
.then(() => {
return execa.stdout('npm', ['config', 'get', 'tag-version-prefix']);
})
.then(
output => {
tagPrefix = output;
},
() => {}
)
.then(() => execa.stdout('git', ['rev-parse', '--quiet', '--verify', `refs/tags/${tagPrefix}${version}`]))
.then(
output => {
if (output) {
throw new Error(`Git tag \`${tagPrefix}${version}\` already exists.`);
}
},
err => {
// Command fails with code 1 and no output if the tag does not exist, even though `--quiet` is provided
// https://github.com/sindresorhus/np/pull/73#discussion_r72385685
if (err.stdout !== '' || err.stderr !== '') {
throw err;
}
}
)
},
);
}
function preparePackage(tasks, package, version) {
const projectRoot = common.projectPath(package);
const pkg = common.readPkg(package);
const projectTasks = [
{
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}\``);
}
}
},
{
title: `${pkg.name}: install npm dependencies`,
task: async () => {
await fs.remove(path.join(projectRoot, 'node_modules'))
await execa('npm', ['ci'], { cwd: projectRoot });
}
}
];
if (package !== 'core') {
projectTasks.push(
{
title: `${pkg.name}: npm link @ionic/core`,
task: () => execa('npm', ['link', '@ionic/core'], { cwd: projectRoot })
},
{
title: `${pkg.name}: update ionic/core dep to ${version}`,
task: () => {
updateDependency(pkg, "@ionic/core", version);
common.writePkg(package, pkg);
}
}
);
}
projectTasks.push(
{
title: `${pkg.name}: lint`,
task: () => execa('npm', ['run', 'lint'], { cwd: projectRoot })
},
{
title: `${pkg.name}: build`,
task: () => execa('npm', ['run', 'build'], { cwd: projectRoot })
},
{
title: `${pkg.name}: test`,
task: () => execa('npm', ['test'], { cwd: projectRoot })
}
);
if (package === 'core') {
projectTasks.push(
{
title: `${pkg.name}: npm link`,
task: () => execa('npm', ['link'], { cwd: projectRoot })
}
);
}
// Add project tasks
tasks.push({
title: `Prepare ${chalk.bold(pkg.name)}`,
task: () => new Listr(projectTasks)
});
}
function updateDependency(pkg, dependency, version) {
if (pkg.dependencies && pkg.dependencies[dependency]) {
pkg.dependencies[dependency] = version;
}
if (pkg.devDependencies && pkg.devDependencies[dependency]) {
pkg.devDependencies[dependency] = version;
}
}
function updatePackageVersion(tasks, package, version) {
const projectRoot = common.projectPath(package);
const pkg = common.readPkg(package);
tasks.push(
{
title: `${pkg.name}: update package.json ${chalk.dim(`(${version})`)}`,
task: async () => {
await execa('npm', ['version', version], { cwd: projectRoot });
const pkgLock = path.join(projectRoot, 'package-lock.json');
const pkgLockData = JSON.parse(fs.readFileSync(pkgLock, 'utf-8'));
pkgLockData.version = version;
fs.writeFileSync(pkgLock, JSON.stringify(pkgLockData));
}
}
);
}
async function generateChangeLog(tasks) {
tasks.push(
{
title: `Generate CHANGELOG.md`,
task: () => execa('npm', ['run', 'changelog'], { cwd: common.rootDir }),
}
);
}
const SEMVER_INCREMENTS = ['patch', 'minor', 'major'];
const isValidVersion = input => Boolean(semver.valid(input));
const isValidVersionInput = input => SEMVER_INCREMENTS.indexOf(input) !== -1 || common.isValidVersion(input);
function getNewVersion(oldVersion, input) {
if (!isValidVersionInput(input)) {
throw new Error(`Version should be either ${SEMVER_INCREMENTS.join(', ')} or a valid semver version.`);
}
return SEMVER_INCREMENTS.indexOf(input) === -1 ? input : semver.inc(oldVersion, input);
};
const isVersionGreater = (oldVersion, newVersion) => {
if (!common.isValidVersion(newVersion)) {
throw new Error('Version should be a valid semver version.');
}
return semver.gt(newVersion, oldVersion);
};
function prettyVersionDiff(oldVersion, inc) {
const newVersion = getNewVersion(oldVersion, inc).split('.');
oldVersion = oldVersion.split('.');
let firstVersionChange = false;
const output = [];
for (let i = 0; i < newVersion.length; i++) {
if ((newVersion[i] !== oldVersion[i] && !firstVersionChange)) {
output.push(`${chalk.dim.cyan(newVersion[i])}`);
firstVersionChange = true;
} else if (newVersion[i].indexOf('-') >= 1) {
let preVersion = [];
preVersion = newVersion[i].split('-');
output.push(`${chalk.dim.cyan(`${preVersion[0]}-${preVersion[1]}`)}`);
} else {
output.push(chalk.reset.dim(newVersion[i]));
}
}
return output.join(chalk.reset.dim('.'));
}
main();

92
.scripts/release.js Normal file
View File

@@ -0,0 +1,92 @@
/**
* Deploy script adopted from https://github.com/sindresorhus/np
* MIT License (c) Sindre Sorhus (sindresorhus.com)
*/
const chalk = require('chalk');
const execa = require('execa');
const Listr = require('listr');
const common = require('./common');
async function main() {
try {
const {version} = common.readPkg('core');
// publish each package in NPM
await publishPackages(common.packages, version);
console.log(`\nionic ${version} published!! 🎉\n`);
} catch (err) {
console.log('\n', chalk.red(err), '\n');
process.exit(1);
}
}
async function publishPackages(packages, version) {
const tasks = [];
// repo must be clean
common.checkGit(tasks);
// first verify version
packages.forEach(package => {
if (package === 'core') return;
const pkg = common.readPkg(package);
tasks.push(
{
title: `${pkg.name}: check version (must match: ${version})`,
task: () => {
if (version !== pkg.version) {
throw new Error(`${pkg.name} version ${pkg.version} must match ${version}`);
}
}
}
);
});
// next publish
packages.forEach(package => {
const pkg = common.readPkg(package);
const projectRoot = common.projectPath(package);
tasks.push(
{
title: `${pkg.name}: publish ${pkg.version}`,
task: () =>execa('npm', ['publish', '--tag', 'latest'], { cwd: projectRoot })
}
);
});
// push tag to git remote
publishGitTag(tasks, version);
const listr = new Listr(tasks);
await listr.run();
}
function publishGitTag(tasks, version) {
const tag = `v${version}`;
tasks.push(
{
title: `Tag latest commit ${chalk.dim(`(${tag})`)}`,
task: () => execa('git', ['tag', `${tag}`], { cwd: common.rootDir })
},
{
title: 'Push branches to Github',
task: () => execa('git', ['push'], { cwd: common.rootDir })
},
{
title: 'Push tags to Github',
task: () => execa('git', ['push', '--tags'], { cwd: common.rootDir })
}
);
}
main();

View File

@@ -1,949 +1,3 @@
# Breaking Changes
A list of the breaking changes introduced in Ionic Angular v4.
- [Dynamic Mode](#dynamic-mode)
- [Button](#button)
- [Chip](#chip)
- [Colors](#colors)
- [Datetime](#datetime)
- [FAB](#fab)
- [Fixed Content](#fixed-content)
- [Icon](#icon)
- [Input](#Input)
- [Item](#item)
- [Item Divider](#item-divider)
- [Item Sliding](#item-sliding)
- [List Header](#list-header)
- [Menu Toggle](#menu-toggle)
- [Nav](#nav)
- [Option](#option)
- [Radio](#radio)
- [Range](#range)
- [Segment](#segment)
- [Select](#select)
- [Text/Typography](#text-typography)
- [Theming](#theming)
- [Toolbar](#toolbar)
## Dynamic Mode
Components are no longer able to have their mode changed dynamically. You can change the mode before the first render, but after that it will not style properly because only the initial mode's styles are included.
## Button
### Markup Changed
Button should now be written as an `<ion-button>` element. Ionic will determine when to render an anchor tag based on the presence of an `href` attribute.
**Old Usage Example:**
```html
<button ion-button (click)="doSomething()">
Default Button
</button>
<a ion-button href="#">
Default Anchor
</a>
```
**New Usage Example:**
```html
<ion-button (click)="doSomething()">
Default Button
</ion-button>
<ion-button href="#">
Default Anchor
</ion-button>
```
### Attributes Renamed
Previously to style icons inside of a button the following attributes were used: `icon-left`, `icon-right`, (and with the added support of RTL) `icon-start`, `icon-end`.
These have been renamed to the following, and moved from the button element to the icon itself:
| Old Property | New Property | Property Behavior |
|---------------------------|----------------|-----------------------------------------------------------------------|
| `icon-left`, `icon-start` | `slot="start"` | Positions to the left of the button in LTR, and to the right in RTL. |
| `icon-right`, `icon-end` | `slot="end"` | Positions to the right of the button in LTR, and to the left in RTL. |
In addition, several sets of mutually exclusive boolean attributes have been combined into a single string attribute.
The `small` and `large` attributes are now combined under the `size` attribute. The `clear`, `outline`, and `solid` attributes have been combined under `fill`. And, lastly, the `full` and `block` attributes have been combined under `expand`.
| Old Property | New Property | Property Behavior |
| --------------------------- | ------------ | --------------------------- |
| `small`, `large` | `size` | Sets the button size. |
| `clear`, `outline`, `solid` | `fill` | Sets the button fill style. |
| `full`, `block`             | `expand` | Sets the button width. |
**Old Usage Example:**
```html
<ion-button icon-left>
<ion-icon name="home"></ion-icon>
Icon Left
</ion-button>
<ion-button icon-start>
<ion-icon name="home"></ion-icon>
Icon Left on LTR, Right on RTL
</ion-button>
<ion-button icon-right>
Icon Right
<ion-icon name="home"></ion-icon>
</ion-button>
<ion-button icon-end>
Icon Right on LTR, Left on RTL
<ion-icon name="home"></ion-icon>
</ion-button>
<ion-button large>
Large Button
</ion-button>
<ion-button outline>
Outline Button
</ion-button>
<ion-button full>
Full-width Button
</ion-button>
```
**New Usage Example:**
```html
<ion-button>
<ion-icon slot="start" name="home"></ion-icon>
Icon Left on LTR, Right on RTL
</ion-button>
<ion-button>
Icon Right on LTR, Left on RTL
<ion-icon slot="end" name="home"></ion-icon>
</ion-button>
<ion-button size="large">
Large Button
</ion-button>
<ion-button fill="outline">
Outline Button
</ion-button>
<ion-button expand="full">
Full-width Button
</ion-button>
```
## Chip
### Markup Changed
Buttons inside of an `<ion-chip>` container should now be written as an `<ion-chip-button>` element. Ionic will determine when to render an anchor tag based on the presence of an `href` attribute.
**Old Usage Example:**
```html
<ion-chip>
<ion-label>Default</ion-label>
<ion-button clear color="light">
<ion-icon name="close-circle"></ion-icon>
</ion-button>
</ion-chip>
```
**New Usage Example:**
```html
<ion-chip>
<ion-label>Default</ion-label>
<ion-chip-button fill="clear" color="light">
<ion-icon name="close-circle"></ion-icon>
</ion-chip-button>
</ion-chip>
```
## Colors
The default Ionic theme colors have changed. Previously we had:
```
primary: #327eff
secondary: #32db64
danger: #f53d3d
light: #f4f4f4
dark: #222
```
Some of their values have changed and we now include more colors by default:
```
primary: #3880ff
secondary: #0cd1e8
tertiary: #7044ff
success: #10dc60
warning: #ffce00
danger: #f04141
light: #f4f5f8
medium: #989aa2
dark: #222428
```
The `secondary` color saw the largest change. If you were previously using our `secondary` color we recommend switching to `success` instead.
## Datetime
The Datetime classes and interfaces have changed capitalization from `DateTime` to `Datetime`. This is more consistent with other components and their tags.
**Old Usage Example:**
```javascript
import { DateTime } from 'ionic-angular';
```
**New Usage Example:**
```javascript
import { Datetime } from 'ionic-angular';
```
## FAB
### Markup Changed
Buttons inside of an `<ion-fab>` container should now be written as an `<ion-fab-button>` element. Ionic will determine when to render an anchor tag based on the presence of an `href` attribute.
**Old Usage Example:**
```html
<ion-fab top right edge>
<button ion-fab>
<ion-icon name="add"></ion-icon>
</button>
<ion-fab-list>
<button ion-fab>
<ion-icon name="logo-facebook"></ion-icon>
</button>
<button ion-fab>
<ion-icon name="logo-twitter"></ion-icon>
</button>
<button ion-fab>
<ion-icon name="logo-vimeo"></ion-icon>
</button>
<button ion-fab>
<ion-icon name="logo-googleplus"></ion-icon>
</button>
</ion-fab-list>
</ion-fab>
```
**New Usage Example:**
```html
<ion-fab vertical="top" horizontal="right" edge>
<ion-fab-button>
<ion-icon name="add"></ion-icon>
</ion-fab-button>
<ion-fab-list>
<ion-fab-button>
<ion-icon name="logo-facebook"></ion-icon>
</ion-fab-button>
<ion-fab-button>
<ion-icon name="logo-twitter"></ion-icon>
</ion-fab-button>
<ion-fab-button>
<ion-icon name="logo-vimeo"></ion-icon>
</ion-fab-button>
<ion-fab-button>
<ion-icon name="logo-googleplus"></ion-icon>
</ion-fab-button>
</ion-fab-list>
</ion-fab>
```
### Attributes Renamed
The mutually exclusive boolean attributes to position the fab have been combined into two single string attributes.
The attributes to align the fab horizontally are now combined under the `horizontal` attribute and the attributes to align the fab vertically are now combined under the `vertical` attribute:
| Old Property | New Property | Property Behavior |
|--------------|----------------------|-------------------------------------------------------------------------|
| left | `horizontal="left"` | Positions to the left of the viewport. |
| right | `horizontal="right"` | Positions to the right of the viewport. |
| center | `horizontal="center"`| Positions to the center of the viewport. |
| start | `horizontal="start"` | Positions to the left of the viewport in LTR, and to the right in RTL. |
| end | `horizontal="end"` | Positions to the right of the viewport in LTR, and to the left in RTL. |
| top | `vertical="top"` | Positions at the top of the viewport. |
| bottom | `vertical="bottom"` | Positions at the bottom of the viewport. |
| middle | `vertical="center"` | Positions at the center of the viewport. |
_Note that `middle` has been changed to `center` for the vertical positioning._
**Old Usage Example:**
```html
<ion-fab top right edge>
<!-- fab buttons and lists -->
</ion-fab>
<ion-fab center middle>
<!-- fab buttons and lists -->
</ion-fab>
```
**New Usage Example:**
```html
<ion-fab vertical="top" horizontal="right" edge>
<!-- fab buttons and lists -->
</ion-fab>
<ion-fab vertical="center" horizontal="center">
<!-- fab buttons and lists -->
</ion-fab>
```
### Fixed Content
The `<ion-fab>` container was previously placed inside of the fixed content by default. Now, any fixed content should use the `fixed` slot.
**Old Usage Example:**
```html
<ion-content>
<ion-fab top right edge>
<!-- fab buttons and lists -->
</ion-fab>
Scrollable Content
</ion-content>
```
**New Usage Example:**
```html
<ion-fab vertical="top" horizontal="right" edge slot="fixed">
<!-- fab buttons and lists -->
</ion-fab>
<ion-content>
Scrollable Content
</ion-content>
```
## Icon
### Fonts Removed
Icons have been refactored to use SVGs instead of fonts. Ionic will only fetch the SVG for the icon when it is needed, instead of having a large font file that is always loaded in.
If any `CSS` is being overridden for an icon it will need to change to override the SVG itself. Below is a usage example of the differences in changing the icon color.
**Old Usage Example:**
```css
.icon {
color: #000;
}
```
**New Usage Example:**
```css
.icon {
fill: #000;
}
```
### Property Removed
The `isActive` property has been removed. It only worked for `ios` icons previously. If you would like to switch between an outline and solid icon you should set it in the `name`, or `ios`/`md` attribute and then change it when needed.
## Input
The Sass variables were all renamed from having `$text-input` as the prefix to `$input`.
**Old Usage Example:**
```css
$text-input-highlight-color-valid: #32db64;
```
**New Usage Example:**
```css
$input-highlight-color-valid: #32db64;
```
## Item
### Markup Changed
Item should now be written as an `<ion-item>` element. Ionic will determine when to render an anchor tag based on the presence of an `href` attribute, and a button tag based on the presence of an `onclick` or `tappable` attribute. Otherwise, it will render a div.
**Old Usage Example:**
```html
<ion-item>
Default Item
</ion-item>
<button ion-item (click)="doSomething()">
Button Item
</button>
<a ion-item href="#">
Anchor Item
</a>
```
**New Usage Example:**
```html
<ion-item>
Default Item
</ion-item>
<ion-item tappable (click)="doSomething()">
Button Item
</ion-item>
<ion-item href="#">
Anchor Item
</ion-item>
```
### Label Required
Previously an `ion-label` would automatically get added to an `ion-item` if one wasn't provided. Now an `ion-label` should always be added if the component is used to display text.
```html
<ion-item>
<ion-label>Item Label</ion-label>
</ion-item>
```
### Attributes Renamed
Previously to position elements inside of an `ion-item` the following attributes were used: `item-left`, `item-right`, (and with the added support of RTL) `item-start`, `item-end`.
These have been renamed to the following:
| Old Property | New Property | Property Behavior |
|---------------------------|----------------|---------------------------------------------------------------------|
| `item-left`, `item-start` | `slot="start"` | Positions to the left of the item in LTR, and to the right in RTL. |
| `item-right`, `item-end` | `slot="end"` | Positions to the right of the item in LTR, and to the left in RTL. |
**Old Usage Example:**
```html
<ion-item>
<div item-left>Left</div>
<ion-label>Item Label</ion-label>
<div item-right>Right</div>
</ion-item>
<ion-item>
<div item-start>Left on LTR, Right on RTL</div>
<ion-label>Item Label</ion-label>
<div item-end>Right on LTR, Left on RTL</div>
</ion-item>
```
**New Usage Example:**
```html
<ion-item>
<div slot="start">Left on LTR, Right on RTL</div>
<ion-label>Item Label</ion-label>
<div slot="end">Right on LTR, Left on RTL</div>
</ion-item>
```
### Detail Push
The attributes to show/hide the detail arrows on items have been converted to a single property and value. Instead of writing `detail-push` or `detail-none` to show/hide the arrow, it should be written `detail`/`detail="true"` or `detail="false"`.
**Old Usage Example:**
```html
<button ion-item detail-none>
<ion-label>Item Label</ion-label>
</button>
<ion-item detail-push>
<ion-label>Item Label</ion-label>
</ion-item>
```
**New Usage Example:**
```html
<ion-item tappable detail="false">
<ion-label>Item Label</ion-label>
</ion-item>
<ion-item detail>
<ion-label>Item Label</ion-label>
</ion-item>
```
By default, items that render buttons or anchor tags will show the arrow in `ios` mode.
## Item Divider
### Label Required
Previously an `ion-label` would automatically get added to an `ion-item-divider` if one wasn't provided. Now an `ion-label` should always be added if the component is used to display text.
```html
<ion-item-divider>
<ion-label>Item Divider Label</ion-label>
</ion-item-divider>
```
## List Header
### Label Required
Previously an `ion-label` would automatically get added to an `ion-list-header` if one wasn't provided. Now an `ion-label` should always be added if the component is used to display text.
```html
<ion-list-header>
<ion-label>List Header Label</ion-label>
</ion-list-header>
```
## Menu Toggle
### Markup Changed
The `menuToggle` attribute should not be added to an element anymore. Elements that should toggle a menu should be wrapped in an `ion-menu-toggle` element.
**Old Usage Example:**
```html
<button ion-button menuToggle>
Toggle Menu
</button>
```
**New Usage Example:**
```html
<ion-menu-toggle>
<ion-button>
Toggle Menu
</ion-button>
</ion-menu-toggle>
```
## Item Sliding
### Markup Changed
The option component should not be written as a `button` with an `ion-button` directive anymore. It should be written as an `ion-item-option`. This will render a native button element inside of it.
**Old Usage Example:**
```html
<ion-item-sliding>
<ion-item>
Item 1
</ion-item>
<ion-item-options side="right">
<button ion-button expandable>
<ion-icon name="star"></ion-icon>
</button>
</ion-item-options>
</ion-item-sliding>
```
**New Usage Example:**
```html
<ion-item-sliding>
<ion-item>
<ion-label>Item 1</ion-label>
</ion-item>
<ion-item-options side="right">
<ion-item-option expandable>
<ion-icon name="star"></ion-icon>
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
```
### Method Renamed
The `getSlidingPercent` method has been renamed to `getSlidingRatio` since the function is returning a ratio of the open amount of the item compared to the width of the options.
## Toolbar
Previously if a `menuToggle` directive was added to an Ionic `button` in a toolbar, it would be positioned outside of the `ion-buttons` element. Since menu toggle is simply a wrapper to a button now, it should be placed inside of the `ion-buttons` element.
**Old Usage Example:**
```html
<ion-toolbar>
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>Left side menu toggle</ion-title>
</ion-toolbar>
```
**New Usage Example:**
```html
<ion-toolbar>
<ion-buttons slot="start">
<ion-menu-toggle>
<ion-button>
<ion-icon slot="icon-only" name="menu"></ion-icon>
</ion-button>
</ion-menu-toggle>
</ion-buttons>
<ion-title>Left side menu toggle</ion-title>
</ion-toolbar>
```
## Nav
### Method renamed
The `remove` method has been renamed to `removeIndex` to avoid conflicts with HTML and be more descriptive as to what it does.
The `getActiveChildNavs` method has been renamed to `getChildNavs`.
## Option
### Markup Changed
Select's option element should now be written as `<ion-select-option>`. This makes it more obvious that the element should only be used with a Select.
**Old Usage Example:**
```html
<ion-select>
<ion-option>Option 1</ion-option>
<ion-option>Option 2</ion-option>
<ion-option>Option 3</ion-option>
</ion-select>
```
**New Usage Example:**
```html
<ion-select>
<ion-select-option>Option 1</ion-select-option>
<ion-select-option>Option 2</ion-select-option>
<ion-select-option>Option 3</ion-select-option>
</ion-select>
```
### Class Changed
The class has been renamed from `Option` to `SelectOption` to keep it consistent with the element tag name.
## Radio
### Slot Required
Previously radio was positioned inside of an item automatically or by using `item-left`/`item-right`. It is now required to have a `slot` to be positioned properly.
** Old Usage Example **
```html
<ion-item>
<ion-label>Apple</ion-label>
<ion-radio value="apple"></ion-radio>
</ion-item>
<ion-item>
<ion-label>Grape, checked, disabled</ion-label>
<ion-radio item-left value="grape" checked disabled></ion-radio>
</ion-item>
<ion-item>
<ion-label>Cherry</ion-label>
<ion-radio item-right color="danger" value="cherry"></ion-radio>
</ion-item>
```
** New Usage Example **
```html
<ion-item>
<ion-label>Apple</ion-label>
<ion-radio slot="start" value="apple"></ion-radio>
</ion-item>
<ion-item>
<ion-label>Grape, checked, disabled</ion-label>
<ion-radio slot="start" value="grape" checked disabled></ion-radio>
</ion-item>
<ion-item>
<ion-label>Cherry</ion-label>
<ion-radio slot="end" color="danger" value="cherry"></ion-radio>
</ion-item>
```
### Radio Group
Radio group has been changed to an element. It should now be wrapped around any `<ion-radio>` elements as `<ion-radio-group>`.
** Old Usage Example **
```html
<ion-list radio-group>
<ion-item>
<ion-label>Apple</ion-label>
<ion-radio value="apple"></ion-radio>
</ion-item>
<ion-item>
<ion-label>Grape, checked, disabled</ion-label>
<ion-radio value="grape" checked disabled></ion-radio>
</ion-item>
<ion-item>
<ion-label>Cherry</ion-label>
<ion-radio color="danger" value="cherry"></ion-radio>
</ion-item>
</ion-list>
```
** New Usage Example **
```html
<ion-list>
<ion-radio-group>
<ion-item>
<ion-label>Apple</ion-label>
<ion-radio slot="start" value="apple"></ion-radio>
</ion-item>
<ion-item>
<ion-label>Grape, checked, disabled</ion-label>
<ion-radio slot="start" value="grape" checked disabled></ion-radio>
</ion-item>
<ion-item>
<ion-label>Cherry</ion-label>
<ion-radio slot="start" color="danger" value="cherry"></ion-radio>
</ion-item>
</ion-radio-group>
</ion-list>
```
## Range
### Attributes Renamed
Previously to place content inside of a range the following attributes were used: `range-left`, `range-right`, (and with the added support of RTL) `range-start`, `range-end`.
These have been renamed to the following:
| Old Property | New Property | Property Behavior |
|-----------------------------|----------------|-----------------------------------------------------------------------|
| `range-left`, `range-start` | `slot="start"` | Positions to the left of the range in LTR, and to the right in RTL. |
| `range-right`, `range-end` | `slot="end"` | Positions to the right of the range in LTR, and to the left in RTL. |
**Old Usage Example:**
```html
<ion-range>
<ion-icon name="sunny" range-left></ion-icon>
<ion-icon name="sunny" range-right></ion-icon>
</ion-range>
<ion-range>
<ion-icon name="sunny" range-start></ion-icon>
<ion-icon name="sunny" range-end></ion-icon>
</ion-range>
```
**New Usage Example:**
```html
<ion-range>
<ion-icon name="sunny" slot="start"></ion-icon>
<ion-icon name="sunny" slot="end"></ion-icon>
</ion-range>
```
## Segment
The markup hasn't changed for Segments, but now writing `<ion-segment-button>` will render a native button element inside of it.
## Select
The `selectOptions` property was renamed to `interfaceOptions` since it directly correlates with the `interface` property.
**Old Usage Example:**
```html
<ion-select [selectOptions]="customOptions">
...
</ion-select>
```
```ts
this.customOptions = {
title: 'Pizza Toppings',
subTitle: 'Select your toppings'
};
```
**New Usage Example:**
```html
<ion-select [interfaceOptions]="customOptions">
...
</ion-select>
```
```ts
this.customOptions = {
title: 'Pizza Toppings',
subTitle: 'Select your toppings'
};
```
## Text / Typography
### Markup Changed
Typography should now be written as an `<ion-text>` element. Previously the `ion-text` attribute could be added to any HTML element to set its color. It should now be used as a wrapper around the HTML elements to style.
**Old Usage Example:**
```html
<h1 ion-text color="secondary">H1: The quick brown fox jumps over the lazy dog</h1>
<h2 ion-text color="primary">H2: The quick brown fox jumps over the lazy dog</h2>
<h3 ion-text color="light">H3: The quick brown fox jumps over the lazy dog</h3>
<p>
I saw a werewolf with a Chinese menu in his hand.
Walking through the <sub ion-text color="danger">streets</sub> of Soho in the rain.
He <i ion-text color="primary">was</i> looking for a place called Lee Ho Fook's.
Gonna get a <a ion-text color="secondary">big dish of beef chow mein.</a>
</p>
```
**New Usage Example:**
```html
<ion-text color="secondary">
<h1>H1: The quick brown fox jumps over the lazy dog</h1>
</ion-text>
<ion-text color="primary">
<h2>H2: The quick brown fox jumps over the lazy dog</h2>
</ion-text>
<ion-text color="light">
<h3>H3: The quick brown fox jumps over the lazy dog</h3>
</ion-text>
<p>
I saw a werewolf with a Chinese menu in his hand.
Walking through the <ion-text color="danger"><sub>streets</sub></ion-text> of Soho in the rain.
He <ion-text color="primary"><i>was</i></ion-text> looking for a place called Lee Ho Fook's.
Gonna get a <ion-text color="secondary"><a>big dish of beef chow mein.</a></ion-text>
</p>
```
## Theming
### Including Sass
Previously all `scss` files in the `src` directory were imported. Now each `scss` file should be included for the component via Angular's `styleUrls` metadata. View [Angular's Component Styles](https://angular.io/guide/component-styles) for more information.
This means that any styles wrapped with a page should now be removed since they will automatically be scoped to the component.
**Old Usage Example:**
```scss
page-schedule {
p {
color: red;
}
}
```
**New Usage Example:**
```scss
p {
color: red;
}
```
### Sass Variables
Sass variables for changing the cordova statusbar have been renamed to app:
**Old Usage Example:**
```css
$cordova-ios-statusbar-padding: 20px;
$cordova-md-statusbar-padding: 20px;
```
**New Usage Example:**
```css
$app-ios-statusbar-padding: 20px;
$app-md-statusbar-padding: 20px;
```
## Toolbar
### Attributes Renamed
The attributes to position an `ion-buttons` element inside of a toolbar have been renamed, as well as the behavior attached to the name. We noticed there was some confusion behind the behavior of the `start` and `end` attributes, and with the new support for RTL we wanted to make the behavior of these match RTL. In order to do this we had to rename the old `start`/`end` to something that makes more sense with their behavior.
The names and behavior of each of the properties was previously:
| Old Property | Property Behavior |
|--------------|--------------------------------------------------------------------------------------------------------------|
| `start` | Positions element to the left of the content in `ios` mode, and directly to the right in `md` and `wp` mode. |
| `end` | Positions element to the right of the content in `ios` mode, and to the far right in `md` and `wp` mode. |
| `left` | Positions element to the left of all other elements. |
| `right` | Positions element to the right of all other elements. |
The properties have been renamed to the following:
| Old Property | New Property | Property Behavior |
|--------------|---------------------|------------------------------------------------------------------------------------------------------------------|
| `start` | `slot="mode-start"` | Positions element to the `left` of the content in `ios` mode, and directly to the `right` in `md` and `wp` mode. |
| `end` | `slot="mode-end"` | Positions element to the `right` of the content in `ios` mode, and to the far right in `md` and `wp` mode. |
| `left` | `slot="start"` | Positions element to the `left` of all other elements in `LTR`, and to the `right` in `RTL`. |
| `right` | `slot="end"` | Positions element to the `right` of all other elements in `LTR`, and to the `left` in `RTL`. |
The list of the breaking changes introduced in Ionic Angular v4 has been moved to [angular/BREAKING.md](https://github.com/ionic-team/ionic/blob/master/angular/BREAKING.md).

445
CHANGELOG.md Normal file
View File

@@ -0,0 +1,445 @@
<a name="4.0.0-alpha.3"></a>
# [4.0.0-alpha.3](https://github.com/ionic-team/ionic/compare/v4.0.0-alpha.2...v4.0.0-alpha.3) (2018-04-23)
### Bug Fixes
* **all:** strong typed events ([d5129df](https://github.com/ionic-team/ionic/commit/d5129df))
* **angular:** adds missing events ([c929dad](https://github.com/ionic-team/ionic/commit/c929dad))
* **angular:** Config provider ([c87f0c5](https://github.com/ionic-team/ionic/commit/c87f0c5))
* **angular:** platform ready() ([2b3c14b](https://github.com/ionic-team/ionic/commit/2b3c14b))
* **overlay:** cssClasses applied to overlay ([43d7538](https://github.com/ionic-team/ionic/commit/43d7538))
* **prerender:** local references to window/document ([78bd146](https://github.com/ionic-team/ionic/commit/78bd146))
* **virtual-scroll:** queue.write ([c1cbbc5](https://github.com/ionic-team/ionic/commit/c1cbbc5))
### Features
* **angular:** animation is explicit ([099b3ed](https://github.com/ionic-team/ionic/commit/099b3ed))
### Performance Improvements
* **platform:** remove from critical path ([86a6cde](https://github.com/ionic-team/ionic/commit/86a6cde))
<a name="4.0.0-alpha.2"></a>
# [4.0.0-alpha.2](https://github.com/ionic-team/ionic/compare/v4.0.0-alpha.1...v4.0.0-alpha.2) (2018-04-13)
### Bug Fixes
* **angular:** add NavParams ([22ebbce](https://github.com/ionic-team/ionic/commit/22ebbce))
* **angular:** change detection in deep ViewContainers ([850d7fc](https://github.com/ionic-team/ionic/commit/850d7fc))
* **angular:** emit es5 code ([02c1e83](https://github.com/ionic-team/ionic/commit/02c1e83))
* **angular:** icon proxy ([db5313e](https://github.com/ionic-team/ionic/commit/db5313e))
* **angular:** router-outlet uses stack by default ([5c91101](https://github.com/ionic-team/ionic/commit/5c91101))
* **angular:** using es2017 types ([12a27bc](https://github.com/ionic-team/ionic/commit/12a27bc))
* **angular:** viewContainer in overlays ([8ad3df9](https://github.com/ionic-team/ionic/commit/8ad3df9))
* **back-button:** get the back button color working ([5f4250b](https://github.com/ionic-team/ionic/commit/5f4250b))
* **fab:** fix fab activation ([a203534](https://github.com/ionic-team/ionic/commit/a203534))
* **label:** inline position by default ([fde878b](https://github.com/ionic-team/ionic/commit/fde878b))
* **label:** using prop for position ([b1ee4b8](https://github.com/ionic-team/ionic/commit/b1ee4b8)), closes [#14288](https://github.com/ionic-team/ionic/issues/14288)
* **mode:** set mode css class on ion-app ([fcb08e1](https://github.com/ionic-team/ionic/commit/fcb08e1))
* **props:** update stencil ([ea24ad6](https://github.com/ionic-team/ionic/commit/ea24ad6))
* **react:** FrameworkDelegate matches API ([e40a6b0](https://github.com/ionic-team/ionic/commit/e40a6b0))
* **toast:** account for safe-area on ios ([d984214](https://github.com/ionic-team/ionic/commit/d984214))
### Features
* **angular:** adds DomController ([6a31f39](https://github.com/ionic-team/ionic/commit/6a31f39)), closes [#14286](https://github.com/ionic-team/ionic/issues/14286)
* **angular:** push/setRoot/pop ([4d23cba](https://github.com/ionic-team/ionic/commit/4d23cba))
* **DomController:** add DomController provider using stencil queue ([bceece7](https://github.com/ionic-team/ionic/commit/bceece7))
* **queue:** use stencil's queue controller for dom read/writes ([d623b3b](https://github.com/ionic-team/ionic/commit/d623b3b))
* **router:** dont reuse the component if the params are different ([5899b03](https://github.com/ionic-team/ionic/commit/5899b03))
* **routerDirection:** refactors goBack ([54d7a12](https://github.com/ionic-team/ionic/commit/54d7a12))
<a name="4.0.0-alpha.1"></a>
# [4.0.0-alpha.1](https://github.com/ionic-team/ionic/compare/v0.2.2...v4.0.0-alpha.1) (2018-04-06)
### Bug Fixes
* **angular:** change detection ([79ba639](https://github.com/ionic-team/ionic/commit/79ba639))
* **angular:** proxy methods ([5153da4](https://github.com/ionic-team/ionic/commit/5153da4))
* **angular:** proxy outputs ([64a9497](https://github.com/ionic-team/ionic/commit/64a9497))
* **menu:** prerender ([a3cd5db](https://github.com/ionic-team/ionic/commit/a3cd5db))
* **split-pane:** prerender ([c6e962c](https://github.com/ionic-team/ionic/commit/c6e962c))
<a name="0.2.2"></a>
## [0.2.2](https://github.com/ionic-team/ionic/compare/v0.2.1...v0.2.2) (2018-04-05)
### Bug Fixes
* **back-button:** fix menu and back button alignment ([#14268](https://github.com/ionic-team/ionic/issues/14268)) ([57fbf6c](https://github.com/ionic-team/ionic/commit/57fbf6c))
* **ripple-effect:** animation ([25c852c](https://github.com/ionic-team/ionic/commit/25c852c))
* **sass:** add missing alert css properties ([#14269](https://github.com/ionic-team/ionic/issues/14269)) ([3471dd6](https://github.com/ionic-team/ionic/commit/3471dd6)), closes [#14258](https://github.com/ionic-team/ionic/issues/14258)
* **script:** release script pushes tags ([d23108a](https://github.com/ionic-team/ionic/commit/d23108a))
* **scripts:** improve script ([2215c6a](https://github.com/ionic-team/ionic/commit/2215c6a))
* **select:** pass header and subHeader to interfaces ([2195895](https://github.com/ionic-team/ionic/commit/2195895))
* **select:** wrap the text for the message in a popover ([0a0959b](https://github.com/ionic-team/ionic/commit/0a0959b))
<a name="0.2.1"></a>
## [0.2.1](https://github.com/ionic-team/ionic/compare/v0.2.0...v0.2.1) (2018-04-04)
### Bug Fixes
* **angular:** back button prevents default ([4db687e](https://github.com/ionic-team/ionic/commit/4db687e))
* **angular:** back-button ([1f78390](https://github.com/ionic-team/ionic/commit/1f78390))
* **angular:** back-button does not push view ([bb46b5f](https://github.com/ionic-team/ionic/commit/bb46b5f))
* **angular:** tabs flickering ([7e97006](https://github.com/ionic-team/ionic/commit/7e97006))
* **app:** hide elements ([11cb42f](https://github.com/ionic-team/ionic/commit/11cb42f))
* **scripts:** update dep version ([974b949](https://github.com/ionic-team/ionic/commit/974b949))
### Features
* **angular:** href integration ([09e6b7e](https://github.com/ionic-team/ionic/commit/09e6b7e))
<a name="0.2.0"></a>
# [0.2.0](https://github.com/ionic-team/ionic/compare/v0.1.6...v0.2.0) (2018-04-02)
### Bug Fixes
* **angular:** URL based tabs ([14fedb9](https://github.com/ionic-team/ionic/commit/14fedb9))
<a name="0.1.6"></a>
## [0.1.6](https://github.com/ionic-team/ionic/compare/v0.1.5...v0.1.6) (2018-04-02)
### Bug Fixes
* **angular:** lifecycles ([062641d](https://github.com/ionic-team/ionic/commit/062641d))
* **angular:** modal and popover ([acd411d](https://github.com/ionic-team/ionic/commit/acd411d))
* **angular:** module exports ([cece447](https://github.com/ionic-team/ionic/commit/cece447))
* **angular:** proxies ([2308239](https://github.com/ionic-team/ionic/commit/2308239))
* **angular:** tabs angular tests ([ff1ed88](https://github.com/ionic-team/ionic/commit/ff1ed88))
* **router-outlet:** enteringEl !== leavingEl ([0d44253](https://github.com/ionic-team/ionic/commit/0d44253))
* **router-outlet:** mutable prop ([ff06dab](https://github.com/ionic-team/ionic/commit/ff06dab))
<a name="0.1.5"></a>
## [0.1.5](https://github.com/ionic-team/ionic/compare/v0.1.4...v0.1.5) (2018-03-29)
### Bug Fixes
* **all:** absolute positioning ([4fcddad](https://github.com/ionic-team/ionic/commit/4fcddad))
* **angular:** goback navigation ([7b9a00e](https://github.com/ionic-team/ionic/commit/7b9a00e))
* **angular:** ion-back-button ([9c789ce](https://github.com/ionic-team/ionic/commit/9c789ce))
* **angular:** stack based navigation ([726938f](https://github.com/ionic-team/ionic/commit/726938f))
* **avatar:** adjust wide images to fill instead of squish ([b0f8ca5](https://github.com/ionic-team/ionic/commit/b0f8ca5))
* **back-button:** empty text is a valid value ([eb0ff2f](https://github.com/ionic-team/ionic/commit/eb0ff2f))
* **back-button:** ios style ([2b8e489](https://github.com/ionic-team/ionic/commit/2b8e489))
* **button:** dynamic bar-button ([d0c5f53](https://github.com/ionic-team/ionic/commit/d0c5f53))
* **checkbox:** update ios checkbox to be closer to native ([b29fce1](https://github.com/ionic-team/ionic/commit/b29fce1))
* **components:** add font-smoothing to mixing components ([9caeec7](https://github.com/ionic-team/ionic/commit/9caeec7))
* **covers:** absolute positioning ([ce09978](https://github.com/ionic-team/ionic/commit/ce09978))
* **item-option:** remove outline on active/focus ([eae6869](https://github.com/ionic-team/ionic/commit/eae6869)), closes [#14191](https://github.com/ionic-team/ionic/issues/14191)
* **label:** add missing text-wrap styles for ios ([a9bd76a](https://github.com/ionic-team/ionic/commit/a9bd76a)), closes [#13157](https://github.com/ionic-team/ionic/issues/13157)
* **menu:** default menu mode ([c31bcde](https://github.com/ionic-team/ionic/commit/c31bcde))
* **nav:** animated opts ([57a5d49](https://github.com/ionic-team/ionic/commit/57a5d49))
* **nav:** no animation ([4fdfddb](https://github.com/ionic-team/ionic/commit/4fdfddb))
* **nav:** transition name ([011a374](https://github.com/ionic-team/ionic/commit/011a374))
* **picker:** do not scroll ([1c06bfe](https://github.com/ionic-team/ionic/commit/1c06bfe))
* **ripple-effect:** tapclick is required in ionic ([d57122c](https://github.com/ionic-team/ionic/commit/d57122c))
* **router:** change detection for componentProps ([a718f7e](https://github.com/ionic-team/ionic/commit/a718f7e))
* **router:** explicit goback should not push ([7a26162](https://github.com/ionic-team/ionic/commit/7a26162))
* **router:** fixes navChanged() ([dddaee1](https://github.com/ionic-team/ionic/commit/dddaee1))
* **router:** ion-nav ([113af9e](https://github.com/ionic-team/ionic/commit/113af9e))
* **router:** loging ([ffaec16](https://github.com/ionic-team/ionic/commit/ffaec16))
* **router:** route change detection ([9e9f2a2](https://github.com/ionic-team/ionic/commit/9e9f2a2))
* **router:** wait RAF ([b26a563](https://github.com/ionic-team/ionic/commit/b26a563))
* **slides:** unload slides correctly ([59c6891](https://github.com/ionic-team/ionic/commit/59c6891))
* **thumbnail:** adjust wide images to fill instead of squish ([54558c9](https://github.com/ionic-team/ionic/commit/54558c9))
* **toast:** dismiss timeout ([44f343d](https://github.com/ionic-team/ionic/commit/44f343d))
* **toolbar:** unused private ([c9d2a0d](https://github.com/ionic-team/ionic/commit/c9d2a0d))
* **transition:** nav ios transition ([095f9c8](https://github.com/ionic-team/ionic/commit/095f9c8))
### Features
* **button:** goback attribute ([00fc460](https://github.com/ionic-team/ionic/commit/00fc460))
* **config:** add set to config ([69a6f8d](https://github.com/ionic-team/ionic/commit/69a6f8d))
* **content:** scrollEnabled ([5c2678f](https://github.com/ionic-team/ionic/commit/5c2678f))
* **menu-controller:** expose registerAnimation ([153f8ca](https://github.com/ionic-team/ionic/commit/153f8ca))
* **nav:** goBack directive ([862e571](https://github.com/ionic-team/ionic/commit/862e571))
* **nav-controller:** goback best guess ([46bbd0f](https://github.com/ionic-team/ionic/commit/46bbd0f))
* **ripple:** css variable color ([77fc792](https://github.com/ionic-team/ionic/commit/77fc792))
* **tab:** framework support ([48d1bd4](https://github.com/ionic-team/ionic/commit/48d1bd4))
### Performance Improvements
* **app:** platform is not needed ([e681836](https://github.com/ionic-team/ionic/commit/e681836))
### Reverts
* **toolbar:** revert to use old button attributes ([574c346](https://github.com/ionic-team/ionic/commit/574c346)), closes [#14172](https://github.com/ionic-team/ionic/issues/14172)
<a name="0.1.4"></a>
## [0.1.4](https://github.com/ionic-team/ionic/compare/v0.1.4-9...v0.1.4) (2018-03-21)
### Bug Fixes
* **action-sheet:** update padding on title to match native ([f0a40fa](https://github.com/ionic-team/ionic/commit/f0a40fa))
* **alert:** update colors for alert text and input borders ([605ec93](https://github.com/ionic-team/ionic/commit/605ec93)), closes [#14196](https://github.com/ionic-team/ionic/issues/14196)
* **alert:** update md alert to closer match spec ([7d53e49](https://github.com/ionic-team/ionic/commit/7d53e49))
* **all:** ts strict (part 4) ([4693229](https://github.com/ionic-team/ionic/commit/4693229))
* **angular:** router-outlet animation ([943e2f7](https://github.com/ionic-team/ionic/commit/943e2f7))
* **chip:** use lighter background color ([08553f1](https://github.com/ionic-team/ionic/commit/08553f1)), closes [#14196](https://github.com/ionic-team/ionic/issues/14196)
* **picker:** does not scroll ([b49a45d](https://github.com/ionic-team/ionic/commit/b49a45d))
* **router:** reusing checks params ([371fc19](https://github.com/ionic-team/ionic/commit/371fc19))
* **router-outlet:** css and change logic ([6e683c5](https://github.com/ionic-team/ionic/commit/6e683c5))
### Features
* **fab:** add box shadow and transition for ios ([d26074a](https://github.com/ionic-team/ionic/commit/d26074a))
* **ion-router-outlet:** adds router-outlet ([c03afab](https://github.com/ionic-team/ionic/commit/c03afab))
<a name="0.1.4-9"></a>
## [0.1.4-9](https://github.com/ionic-team/ionic/compare/v0.1.4-8...v0.1.4-9) (2018-03-20)
### Bug Fixes
* **all:** ts strict (part 3) ([06ad60e](https://github.com/ionic-team/ionic/commit/06ad60e))
* **angular:** ion-nav no routing ([9094c66](https://github.com/ionic-team/ionic/commit/9094c66))
* **angular:** removeViewFromDom ([41f54f8](https://github.com/ionic-team/ionic/commit/41f54f8))
* **back-button:** use correct color for ios back button ([b82c382](https://github.com/ionic-team/ionic/commit/b82c382)), closes [#14177](https://github.com/ionic-team/ionic/issues/14177)
* **overlays:** page is removed properly ([9988c75](https://github.com/ionic-team/ionic/commit/9988c75))
* **theming:** update spinner classes to new names ([f578122](https://github.com/ionic-team/ionic/commit/f578122))
### Features
* **angular:** ion-nav ([f39d3ad](https://github.com/ionic-team/ionic/commit/f39d3ad))
<a name="0.1.4-8"></a>
## [0.1.4-8](https://github.com/ionic-team/ionic/compare/v0.1.4-7...v0.1.4-8) (2018-03-19)
### Bug Fixes
* **back-button:** apply the proper color to the back button ([7d2de18](https://github.com/ionic-team/ionic/commit/7d2de18)), closes [#14177](https://github.com/ionic-team/ionic/issues/14177)
### Features
* **nav:** support for rootParams ([50abcf5](https://github.com/ionic-team/ionic/commit/50abcf5))
<a name="0.1.4-7"></a>
## [0.1.4-7](https://github.com/ionic-team/ionic/compare/v0.1.4-6...v0.1.4-7) (2018-03-16)
### Features
* **router:** wildcard redirects ([2bdf4ad](https://github.com/ionic-team/ionic/commit/2bdf4ad))
<a name="0.1.4-6"></a>
## [0.1.4-6](https://github.com/ionic-team/ionic/compare/v0.1.4-5...v0.1.4-6) (2018-03-15)
### Bug Fixes
* **alert:** backdrop calls cancel handler ([de22eca](https://github.com/ionic-team/ionic/commit/de22eca))
* **alert:** set input value ([6e2a9c9](https://github.com/ionic-team/ionic/commit/6e2a9c9))
* **angular:** create angular delegate ([3b5f758](https://github.com/ionic-team/ionic/commit/3b5f758))
* **angular:** fix overlays ([cc4fecc](https://github.com/ionic-team/ionic/commit/cc4fecc))
* **angular:** modal and popover support ([9a0755a](https://github.com/ionic-team/ionic/commit/9a0755a))
* **demos:** fixes angular ([f398b3a](https://github.com/ionic-team/ionic/commit/f398b3a))
* **overlay:** using hostData for zIndex ([64f0866](https://github.com/ionic-team/ionic/commit/64f0866))
* **overlay:** wrong stencil import ([22f6a34](https://github.com/ionic-team/ionic/commit/22f6a34))
* **overlays:** OverlayController interface ([6e2ca85](https://github.com/ionic-team/ionic/commit/6e2ca85))
* **popover:** lifecycles ([b56c2a8](https://github.com/ionic-team/ionic/commit/b56c2a8))
* **router:** ambiguous routes ([b4f46ee](https://github.com/ionic-team/ionic/commit/b4f46ee))
* **router:** fix selection ([207f416](https://github.com/ionic-team/ionic/commit/207f416))
* **router:** rename API to match stencil-router ([e729610](https://github.com/ionic-team/ionic/commit/e729610))
* **router:** retuning string path ([f48d817](https://github.com/ionic-team/ionic/commit/f48d817))
* **toggle:** ios shadow ([7df023a](https://github.com/ionic-team/ionic/commit/7df023a))
### Features
* **ion-router:** dynamic routes ([7c3cba0](https://github.com/ionic-team/ionic/commit/7c3cba0))
* **overlay:** adds lifecycle events ([0b099ce](https://github.com/ionic-team/ionic/commit/0b099ce))
* **overlays:** adds onDidDismiss and onWillDismiss ([7dcf8a5](https://github.com/ionic-team/ionic/commit/7dcf8a5))
### Performance Improvements
* **scss:** optimize multi dir ([#14156](https://github.com/ionic-team/ionic/issues/14156)) ([ba63d01](https://github.com/ionic-team/ionic/commit/ba63d01))
<a name="0.1.4-5"></a>
## [0.1.4-5](https://github.com/ionic-team/ionic/compare/v0.1.4-4...v0.1.4-5) (2018-03-09)
### Bug Fixes
* **item:** button outline ([f671008](https://github.com/ionic-team/ionic/commit/f671008))
* **router:** fix flickering ([f2ac6e3](https://github.com/ionic-team/ionic/commit/f2ac6e3))
* **router:** flickering 2 ([88f2981](https://github.com/ionic-team/ionic/commit/88f2981))
* **router:** tslint ([1ace045](https://github.com/ionic-team/ionic/commit/1ace045))
### Features
* **router:** adds redirectTo ([f5c6333](https://github.com/ionic-team/ionic/commit/f5c6333))
<a name="0.1.4-4"></a>
## [0.1.4-4](https://github.com/ionic-team/ionic/compare/v0.1.4-3...v0.1.4-4) (2018-03-08)
### Bug Fixes
* **back-button:** implements back animation ([64a787a](https://github.com/ionic-team/ionic/commit/64a787a))
* **route:** params is not undefined ([8b6df5a](https://github.com/ionic-team/ionic/commit/8b6df5a))
<a name="0.1.4-3"></a>
## [0.1.4-3](https://github.com/ionic-team/ionic/compare/v0.1.4-2...v0.1.4-3) (2018-03-08)
### Bug Fixes
* **router:** passing params to ion-nav ([d1263a8](https://github.com/ionic-team/ionic/commit/d1263a8))
### Features
* **back-button:** adds defaultHref ([5271f68](https://github.com/ionic-team/ionic/commit/5271f68))
* **nav:** params ([878d7e6](https://github.com/ionic-team/ionic/commit/878d7e6))
* **route:** adds route-link ([4a3030f](https://github.com/ionic-team/ionic/commit/4a3030f))
* **router:** reverse lookup with params ([3ce8a67](https://github.com/ionic-team/ionic/commit/3ce8a67))
<a name="0.1.4-2"></a>
## [0.1.4-2](https://github.com/ionic-team/ionic/compare/v0.1.4-0...v0.1.4-2) (2018-03-07)
### Bug Fixes
* **fab:** add side as a property for fab list ([7387d34](https://github.com/ionic-team/ionic/commit/7387d34))
* **ion-router:** fixes routing algorithm ([c8a27b7](https://github.com/ionic-team/ionic/commit/c8a27b7))
* **item:** href ([540c33b](https://github.com/ionic-team/ionic/commit/540c33b))
* **overlays:** bundling of overlays ([9650bec](https://github.com/ionic-team/ionic/commit/9650bec))
* **router:** invalid url ([c7fe694](https://github.com/ionic-team/ionic/commit/c7fe694))
* **routing:** flickering (part 1) ([7b264f9](https://github.com/ionic-team/ionic/commit/7b264f9))
* **tabs:** do not select when using router ([174d9b5](https://github.com/ionic-team/ionic/commit/174d9b5))
### Features
* **router:** adds parameters ([f29e3f4](https://github.com/ionic-team/ionic/commit/f29e3f4))
* **virtual-scroll:** adds JSX support ([dc8b363](https://github.com/ionic-team/ionic/commit/dc8b363))
<a name="0.1.4-1"></a>
## [0.1.4-1](https://github.com/ionic-team/ionic/compare/v0.1.4-0...v0.1.4-1) (2018-03-07)
### Bug Fixes
* **ion-router:** fixes routing algorithm ([c8a27b7](https://github.com/ionic-team/ionic/commit/c8a27b7))
* **overlays:** bundling of overlays ([9650bec](https://github.com/ionic-team/ionic/commit/9650bec))
* **routing:** flickering (part 1) ([7b264f9](https://github.com/ionic-team/ionic/commit/7b264f9))
* **tabs:** do not select when using router ([174d9b5](https://github.com/ionic-team/ionic/commit/174d9b5))
### Features
* **virtual-scroll:** adds JSX support ([dc8b363](https://github.com/ionic-team/ionic/commit/dc8b363))
<a name="0.1.4-0"></a>
## [0.1.4-0](https://github.com/ionic-team/ionic/compare/v0.1.3...v0.1.4-0) (2018-03-06)
### Refactor
- Refactored navigation system
### Bug Fixes
* **testing:** do not throw error for missing Ionic global ([aa91d11](https://github.com/ionic-team/ionic/commit/aa91d11))
* **zone:** forgot to remove console.logs ([4ec3e48](https://github.com/ionic-team/ionic/commit/4ec3e48))
<a name="0.1.3"></a>
## [0.1.3](https://github.com/ionic-team/ionic/compare/v0.1.2...v0.1.3) (2018-03-03)
### Performance Improvements
* Updates to latest stencil, that includes the zone bypassing abilities.
### Bug Fixes
* **ts:** ts strict fixes ([8ff02c7](https://github.com/ionic-team/ionic/commit/8ff02c7))
<a name="0.1.2"></a>
## [0.1.2](https://github.com/ionic-team/ionic/compare/v0.1.1...v0.1.2) (2018-03-03)
### Performance Improvements
* **events:** bypass ngzone ([7366c38](https://github.com/ionic-team/ionic/commit/7366c38))
* **scroll:** watchdog + simplification ([33a6274](https://github.com/ionic-team/ionic/commit/33a6274))
### Bug Fixes
* **scroll:** clearInterval just to be safe ([6da9882](https://github.com/ionic-team/ionic/commit/6da9882))
<a name="0.1.1"></a>
## [0.1.1](https://github.com/ionic-team/ionic/commit/291e85e61128b2f3101d9cea6b42d4cf751dc481) (2018-03-01)
### Bug Fixes
* **button:** pass the property type instead of hardcoding button ([10e481a](https://github.com/ionic-team/ionic/commit/10e481a))
<a name="0.1.0"></a>
## [0.1.0](https://github.com/ionic-team/ionic/commit/43a8c4c7a719169336a84964fc1c737562d764a6) (2018-03-01)

View File

@@ -8,8 +8,8 @@ Ionic is based on [Web Components](https://www.webcomponents.org/introduction) a
# Packages
- [Core](packages/core/README.md)
- [Ionic Angular](packages/ionic-angular/README.md)
- [Core](core/README.md)
- [Ionic Angular](angular/README.md)
### Getting Started
@@ -46,3 +46,8 @@ As Ionic components migrate to the web component standard, a goal of ours is to
The source code for Ionic V1 has been moved to [ionic-team/ionic-v1](https://github.com/ionic-team/ionic-v1).
Please open any issues and pull requests related to Ionic V1 on that repository.
### Ionic V3
The source code for Ionic V3 has been moved to the [v3 branch](https://github.com/ionic-team/ionic/tree/v3).

1174
angular/BREAKING.md Normal file
View File

File diff suppressed because it is too large Load Diff

1
angular/package-lock.json generated Normal file
View File

File diff suppressed because one or more lines are too long

66
angular/package.json Normal file
View File

@@ -0,0 +1,66 @@
{
"name": "@ionic/angular",
"version": "4.0.0-alpha.3",
"description": "Angular specific wrappers for @ionic/core",
"keywords": [
"ionic",
"framework",
"angular",
"mobile",
"app",
"webapp",
"capacitor",
"cordova",
"progressive web app",
"pwa"
],
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/ionic-team/ionic.git"
},
"scripts": {
"build": "npm run clean && npm run compile && npm run clean-generated && npm run ionic-core",
"build.link": "npm run build && node scripts/link-copy.js",
"clean": "node scripts/clean.js",
"clean-generated": "node ./scripts/clean-generated.js",
"compile": "./node_modules/.bin/ngc",
"ionic-core": "node ../core/node_modules/.bin/stencil build",
"ionic-core-dev": "node ../core/node_modules/.bin/stencil build --dev",
"lint": "tslint --project .",
"prerelease": "npm run validate && np prerelease --yolo --any-branch --tag next",
"test": "echo 'angular no tests yet'",
"tsc": "tsc -p .",
"validate": "npm i && npm run lint && npm run test && npm run build"
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist/"
],
"dependencies": {
"@ionic/core": "4.0.0-alpha.3"
},
"devDependencies": {
"@angular/common": "^6.0.0-rc.3",
"@angular/compiler": "^6.0.0-rc.3",
"@angular/compiler-cli": "^6.0.0-rc.3",
"@angular/core": "^6.0.0-rc.3",
"@angular/forms": "^6.0.0-rc.3",
"@angular/platform-browser": "^6.0.0-rc.3",
"@angular/platform-browser-dynamic": "^6.0.0-rc.3",
"@angular/router": "^6.0.0-rc.3",
"chalk": "^2.3.2",
"execa": "^0.10.0",
"fs-extra": "^5.0.0",
"glob": "7.1.2",
"inquirer": "^5.2.0",
"listr": "^0.13.0",
"rxjs": "^6.0.0-terrific-rc.3",
"semver": "^5.5.0",
"tslint": "^5.8.0",
"tslint-ionic-rules": "0.0.14",
"typescript": "2.7.2",
"zone.js": "^0.8.20"
}
}

19
angular/scripts/README.md Normal file
View File

@@ -0,0 +1,19 @@
# Local @ionic/angular test app development
1. `npm install` at the root of `angular`
2. `npm run build` to build local `@ionic/angular`
3. `npm link` to locally link `@ionic/angular`
4. `cd` to the test app, such as `angular/test/nav`
5. `npm install` in the test app directory
6. `npm link @ionic/angular` in the test app directory
7. `ng serve` in the test app directory
8. [http://localhost:4200/](http://localhost:4200/)
# npm link local development
`npm link` doesn't work as expected due to the `devDependency` on `@angular/core`. This is the work around...
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.

View File

@@ -2,23 +2,12 @@ const path = require('path');
const cwd = process.cwd();
const glob = require('glob');
const rimRaf = require('rimraf');
const fs = require('fs-extra');
const distDir = path.join(cwd, 'dist');
const distDir = path.join(__dirname, '../dist');
const distGeneratedNodeModules = path.join(distDir, 'node_modules');
function rimRafAsync(dir) {
return new Promise((resolve, reject) => {
rimRaf(dir, {}, err => {
if (err) {
return reject(err);
}
resolve();
})
});
}
function doGlob(globString) {
return new Promise((resolve, reject) => {
glob(globString, (err, matches) => {
@@ -40,15 +29,14 @@ function getCodegenedFilesToDelete() {
const deleteFilePromises = [];
listOfGlobResults.forEach(fileMatches => {
fileMatches.forEach(filePath => {
deleteFilePromises.push(rimRafAsync(filePath));
deleteFilePromises.push(fs.remove(filePath));
})
})
return Promise.all(deleteFilePromises);
});
}
const taskPromises = [];
taskPromises.push(getCodegenedFilesToDelete());
taskPromises.push(rimRafAsync(distGeneratedNodeModules));
return Promise.all(taskPromises);
Promise.all([
getCodegenedFilesToDelete(),
fs.remove(distGeneratedNodeModules)
]);

28
angular/src/components.d.ts vendored Normal file
View File

@@ -0,0 +1,28 @@
/**
* This is an autogenerated file created by the Stencil build process.
* It contains typing information for all components that exist in this project
* and imports for stencil collections that might be configured in your stencil.config.js file
*/
import '@stencil/core';
declare global {
namespace JSX {
interface Element {}
export interface IntrinsicElements {}
}
namespace JSXElements {}
interface HTMLStencilElement extends HTMLElement {
componentOnReady(): Promise<this>;
componentOnReady(done: (ele?: this) => void): void;
forceUpdate(): void;
}
interface HTMLAttributes {}
}
import 'ionicons';
import '@ionic/core';

View File

@@ -1,4 +1,4 @@
import { Directive, ElementRef, HostListener, Renderer2 } from '@angular/core';
import { Directive, ElementRef, HostListener } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { setIonicClasses } from './util/set-ionic-classes';
@@ -15,7 +15,8 @@ import { setIonicClasses } from './util/set-ionic-classes';
]
})
export class BooleanValueAccessor implements ControlValueAccessor {
constructor(private element: ElementRef, private renderer: Renderer2) {
constructor(private element: ElementRef) {
this.onChange = () => {/**/};
this.onTouched = () => {/**/};
}
@@ -24,14 +25,15 @@ export class BooleanValueAccessor implements ControlValueAccessor {
onTouched: () => void;
writeValue(value: any) {
this.renderer.setProperty(this.element.nativeElement, 'checked', value);
this.element.nativeElement.checked = value;
setIonicClasses(this.element);
}
@HostListener('ionChange', ['$event.target.checked'])
_handleIonChange(value: any) {
this.onChange(value);
setTimeout(() => {
requestAnimationFrame(() => {
setIonicClasses(this.element);
});
}
@@ -39,24 +41,21 @@ export class BooleanValueAccessor implements ControlValueAccessor {
@HostListener('ionBlur')
_handleBlurEvent() {
this.onTouched();
setTimeout(() => {
requestAnimationFrame(() => {
setIonicClasses(this.element);
});
}
registerOnChange(fn: (value: any) => void): void {
registerOnChange(fn: (value: any) => void) {
this.onChange = fn;
}
registerOnTouched(fn: () => void): void {
registerOnTouched(fn: () => void) {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean): void {
this.renderer.setProperty(
this.element.nativeElement,
'disabled',
isDisabled
);
setDisabledState(isDisabled: boolean) {
this.element.nativeElement.disabled = isDisabled;
}
}

View File

@@ -1,4 +1,4 @@
import { Directive, ElementRef, HostListener, Renderer2 } from '@angular/core';
import { Directive, ElementRef, HostListener } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { setIonicClasses } from './util/set-ionic-classes';
@@ -15,7 +15,8 @@ import { setIonicClasses } from './util/set-ionic-classes';
]
})
export class NumericValueAccessor implements ControlValueAccessor {
constructor(private element: ElementRef, private renderer: Renderer2) {
constructor(private element: ElementRef) {
this.onChange = () => {/**/};
this.onTouched = () => {/**/};
}
@@ -23,49 +24,42 @@ export class NumericValueAccessor implements ControlValueAccessor {
onChange: (value: any) => void;
onTouched: () => void;
writeValue(value: any): void {
writeValue(value: any) {
// The value needs to be normalized for IE9, otherwise it is set to 'null' when null
// Probably not an issue for us, but it doesn't really cost anything either
const normalizedValue = value == null ? '' : value;
this.renderer.setProperty(
this.element.nativeElement,
'value',
normalizedValue
);
this.element.nativeElement.value = value == null ? '' : value;
setIonicClasses(this.element);
}
@HostListener('input', ['$event.target.value'])
_handleInputEvent(value: any): void {
_handleInputEvent(value: any) {
this.onChange(value);
setTimeout(() => {
requestAnimationFrame(() => {
setIonicClasses(this.element);
});
}
@HostListener('ionBlur')
_handleBlurEvent(): void {
_handleBlurEvent() {
this.onTouched();
setTimeout(() => {
requestAnimationFrame(() => {
setIonicClasses(this.element);
});
}
registerOnChange(fn: (_: number | null) => void): void {
registerOnChange(fn: (_: number | null) => void) {
this.onChange = value => {
fn(value === '' ? null : parseFloat(value));
};
}
registerOnTouched(fn: () => void): void {
registerOnTouched(fn: () => void) {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean): void {
this.renderer.setProperty(
this.element.nativeElement,
'disabled',
isDisabled
);
setDisabledState(isDisabled: boolean) {
this.element.nativeElement.disabled = isDisabled;
}
}

View File

@@ -1,4 +1,4 @@
import { Directive, ElementRef, HostListener, Input, Renderer2 } from '@angular/core';
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { setIonicClasses } from './util/set-ionic-classes';
@@ -20,24 +20,24 @@ export class RadioValueAccessor implements ControlValueAccessor {
onChange: (value: any) => void;
onTouched: () => void;
constructor(private element: ElementRef, private renderer: Renderer2) {
constructor(private element: ElementRef) {
this.onChange = () => {/**/};
this.onTouched = () => {/**/};
}
writeValue(value: any) {
this.renderer.setProperty(
this.element.nativeElement,
'checked',
value === this.value
);
setIonicClasses(this.element);
this.element.nativeElement.checked = this.value = value;
requestAnimationFrame(() => {
setIonicClasses(this.element);
});
}
@HostListener('ionSelect', ['$event.target.checked'])
_handleIonSelect(value: any) {
this.onChange(value);
setTimeout(() => {
requestAnimationFrame(() => {
setIonicClasses(this.element);
});
}
@@ -45,26 +45,23 @@ export class RadioValueAccessor implements ControlValueAccessor {
@HostListener('ionBlur')
_handleBlurEvent() {
this.onTouched();
setTimeout(() => {
requestAnimationFrame(() => {
setIonicClasses(this.element);
});
}
registerOnChange(fn: (value: any) => void): void {
registerOnChange(fn: (value: any) => void) {
this.onChange = () => {
fn(this.value);
};
}
registerOnTouched(fn: () => void): void {
registerOnTouched(fn: () => void) {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean): void {
this.renderer.setProperty(
this.element.nativeElement,
'disabled',
isDisabled
);
setDisabledState(isDisabled: boolean) {
this.element.nativeElement.disabled = isDisabled;
}
}

View File

@@ -1,10 +1,8 @@
import { Directive, ElementRef, HostListener, Renderer2 } from '@angular/core';
import { Directive, ElementRef, HostListener } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { setIonicClasses } from './util/set-ionic-classes';
// NOTE: May need to look at this to see if we need anything else:
// https://github.com/angular/angular/blob/5.0.2/packages/forms/src/directives/select_control_value_accessor.ts#L28-L158
@Directive({
/* tslint:disable-next-line:directive-selector */
selector: 'ion-range, ion-select, ion-radio-group, ion-segment, ion-datetime',
@@ -17,7 +15,8 @@ import { setIonicClasses } from './util/set-ionic-classes';
]
})
export class SelectValueAccessor implements ControlValueAccessor {
constructor(private element: ElementRef, private renderer: Renderer2) {
constructor(private element: ElementRef) {
this.onChange = () => {/**/};
this.onTouched = () => {/**/};
}
@@ -26,14 +25,18 @@ export class SelectValueAccessor implements ControlValueAccessor {
onTouched: () => void;
writeValue(value: any) {
this.renderer.setProperty(this.element.nativeElement, 'value', value);
setIonicClasses(this.element);
this.element.nativeElement.value = value;
requestAnimationFrame(() => {
setIonicClasses(this.element);
});
}
@HostListener('ionChange', ['$event.target.value'])
_handleChangeEvent(value: any) {
this.onChange(value);
setTimeout(() => {
requestAnimationFrame(() => {
setIonicClasses(this.element);
});
}
@@ -41,7 +44,8 @@ export class SelectValueAccessor implements ControlValueAccessor {
@HostListener('ionBlur')
_handleBlurEvent() {
this.onTouched();
setTimeout(() => {
requestAnimationFrame(() => {
setIonicClasses(this.element);
});
}
@@ -54,11 +58,7 @@ export class SelectValueAccessor implements ControlValueAccessor {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean): void {
this.renderer.setProperty(
this.element.nativeElement,
'disabled',
isDisabled
);
setDisabledState(isDisabled: boolean) {
this.element.nativeElement.disabled = isDisabled;
}
}

View File

@@ -1,4 +1,4 @@
import { Directive, ElementRef, HostListener, Renderer2 } from '@angular/core';
import { Directive, ElementRef, HostListener } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { setIonicClasses } from './util/set-ionic-classes';
@@ -15,7 +15,8 @@ import { setIonicClasses } from './util/set-ionic-classes';
]
})
export class TextValueAccessor implements ControlValueAccessor {
constructor(private element: ElementRef, private renderer: Renderer2) {
constructor(private element: ElementRef) {
this.onChange = () => {/**/};
this.onTouched = () => {/**/};
}
@@ -24,14 +25,18 @@ export class TextValueAccessor implements ControlValueAccessor {
onTouched: () => void;
writeValue(value: any) {
this.renderer.setProperty(this.element.nativeElement, 'value', value);
setIonicClasses(this.element);
this.element.nativeElement.value = value;
requestAnimationFrame(() => {
setIonicClasses(this.element);
});
}
@HostListener('input', ['$event.target.value'])
_handleInputEvent(value: any) {
this.onChange(value);
setTimeout(() => {
requestAnimationFrame(() => {
setIonicClasses(this.element);
});
}
@@ -39,7 +44,8 @@ export class TextValueAccessor implements ControlValueAccessor {
@HostListener('ionBlur')
_handleBlurEvent() {
this.onTouched();
setTimeout(() => {
requestAnimationFrame(() => {
setIonicClasses(this.element);
});
}
@@ -52,11 +58,7 @@ export class TextValueAccessor implements ControlValueAccessor {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean): void {
this.renderer.setProperty(
this.element.nativeElement,
'disabled',
isDisabled
);
setDisabledState(isDisabled: boolean) {
this.element.nativeElement.disabled = isDisabled;
}
}

View File

@@ -0,0 +1,45 @@
import { Directive, ElementRef, Input } from '@angular/core';
import { inputs } from '../util/util';
@Directive({ selector: 'ion-icon' })
export class Icon {
/**
* The color to use from your Sass `$colors` map.
* Default options are: `"primary"`, `"secondary"`, `"danger"`, `"light"`, and `"dark"`.
* For more information, see [Theming your App](/docs/theming/theming-your-app).
*/
@Input() color: string;
/**
* Specifies the label to use for accessibility. Defaults to the icon name.
*/
@Input() ariaLabel = '';
/**
* Specifies which icon to use on `ios` mode.
*/
@Input() ios = '';
/**
* Specifies which icon to use on `md` mode.
*/
@Input() md = '';
/**
* Specifies which icon to use. The appropriate icon will be used based on the mode.
* For more information, see [Ionicons](/docs/ionicons/).
*/
@Input() name = '';
/**
* The size of the icon.
* Available options are: `"small"` and `"large"`.
*/
@Input() size: string;
constructor(el: ElementRef) {
inputs(this, el, ['color', 'ariaLabel', 'ios', 'md', 'name', 'size']);
}
}

View File

@@ -0,0 +1,21 @@
export { BooleanValueAccessor } from './control-value-accessors/boolean-value-accessor';
export { NumericValueAccessor } from './control-value-accessors/numeric-value-accesssor';
export { RadioValueAccessor } from './control-value-accessors/radio-value-accessor';
export { SelectValueAccessor } from './control-value-accessors/select-value-accessor';
export { TextValueAccessor } from './control-value-accessors/text-value-accessor';
export { RouterDirection } from './navigation/router-direction';
export { IonBackButton } from './navigation/ion-back-button';
export { NavDelegate } from './navigation/nav-delegate';
export { TabDelegate } from './navigation/tab-delegate';
export { TabsDelegate } from './navigation/tabs-delegate';
export { IonRouterOutlet } from './navigation/ion-router-outlet';
export { HrefDelegate } from './navigation/href-delegate';
export { NavParams } from './navigation/nav-params';
export { Icon } from './icon';
export { VirtualScroll } from './virtual-scroll/virtual-scroll';
export { VirtualItem } from './virtual-scroll/virtual-item';
export { VirtualHeader } from './virtual-scroll/virtual-header';
export { VirtualFooter } from './virtual-scroll/virtual-footer';

View File

@@ -0,0 +1,30 @@
import { Directive, ElementRef, HostListener, Input, Optional } from '@angular/core';
import { Router } from '@angular/router';
@Directive({
selector: 'ion-anchor,ion-button,ion-item'
})
export class HrefDelegate {
@Input()
set href(value: string) {
this.elementRef.nativeElement.href = value;
}
get href() {
return this.elementRef.nativeElement.href;
}
constructor(
@Optional() private router: Router,
private elementRef: ElementRef
) {}
@HostListener('click', ['$event'])
onClick(ev: Event) {
const url = this.href;
if (this.router && url != null && url[0] !== '#' && url.indexOf('://') === -1) {
ev.preventDefault();
this.router.navigateByUrl(url);
}
}
}

View File

@@ -0,0 +1,37 @@
import { Directive, ElementRef, HostListener, Input, Optional } from '@angular/core';
import { Router } from '@angular/router';
import { NavController, NavIntent } from '../../providers/nav-controller';
import { IonRouterOutlet } from './ion-router-outlet';
@Directive({
selector: 'ion-back-button'
})
export class IonBackButton {
@Input()
set defaultHref(value: string) {
this.elementRef.nativeElement.defaultHref = value;
}
get defaultHref() {
return this.elementRef.nativeElement.defaultHref;
}
constructor(
@Optional() private router: Router,
@Optional() private routerOutlet: IonRouterOutlet,
private navCtrl: NavController,
private elementRef: ElementRef,
) {}
@HostListener('click', ['$event'])
onClick(ev: Event) {
if (this.routerOutlet && this.routerOutlet.canGoBack()) {
this.routerOutlet.pop();
ev.preventDefault();
} else if (this.router && this.defaultHref != null) {
this.navCtrl.setIntent(NavIntent.Back);
this.router.navigateByUrl(this.defaultHref);
ev.preventDefault();
}
}
}

View File

@@ -1,30 +1,42 @@
import { Attribute, ChangeDetectorRef, ComponentFactoryResolver, ComponentRef, Directive, EventEmitter, Injector, OnDestroy, OnInit, Output, ViewContainerRef } from '@angular/core';
import { ActivatedRoute, ChildrenOutletContexts } from '@angular/router';
import * as ctrl from './router-controller';
import { runTransition } from './router-transition';
import { Attribute, ChangeDetectorRef, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, Injector, OnDestroy, OnInit, Optional, Output, ViewContainerRef } from '@angular/core';
import { ActivatedRoute, ChildrenOutletContexts, PRIMARY_OUTLET, Router } from '@angular/router';
import { StackController } from './router-controller';
import { NavController } from '../../providers/nav-controller';
import { bindLifecycleEvents } from '../../providers/angular-delegate';
@Directive({selector: 'ion-router-outlet', exportAs: 'ionOutlet'})
@Directive({
selector: 'ion-router-outlet',
exportAs: 'outlet'
})
export class IonRouterOutlet implements OnDestroy, OnInit {
private activated: ComponentRef<any>|null = null;
private _activatedRoute: ActivatedRoute|null = null;
private name: string;
private views: ctrl.RouteView[] = [];
private stackCtrl: StackController;
@Output('activate') activateEvents = new EventEmitter<any>();
@Output('deactivate') deactivateEvents = new EventEmitter<any>();
constructor(
private parentContexts: ChildrenOutletContexts, private location: ViewContainerRef,
private resolver: ComponentFactoryResolver, @Attribute('name') name: string,
private changeDetector: ChangeDetectorRef) {
this.name = name || 'primary';
private parentContexts: ChildrenOutletContexts,
private location: ViewContainerRef,
private resolver: ComponentFactoryResolver,
private elementRef: ElementRef,
@Attribute('name') name: string,
@Optional() @Attribute('stack') stack: any,
private changeDetector: ChangeDetectorRef,
private navCtrl: NavController,
router: Router
) {
this.name = name || PRIMARY_OUTLET;
parentContexts.onChildOutletCreated(this.name, this as any);
const hasStack = stack !== 'false' || stack !== false;
this.stackCtrl = new StackController(hasStack, elementRef.nativeElement, router, this.navCtrl);
}
ngOnDestroy(): void {
ctrl.destoryViews(this.views);
this.parentContexts.onChildOutletDestroyed(this.name);
}
@@ -48,12 +60,16 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
get isActivated(): boolean { return !!this.activated; }
get component(): Object {
if (!this.activated) throw new Error('Outlet is not activated');
if (!this.activated) {
throw new Error('Outlet is not activated');
}
return this.activated.instance;
}
get activatedRoute(): ActivatedRoute {
if (!this.activated) throw new Error('Outlet is not activated');
if (!this.activated) {
throw new Error('Outlet is not activated');
}
return this._activatedRoute as ActivatedRoute;
}
@@ -68,7 +84,9 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
* Called when the `RouteReuseStrategy` instructs to detach the subtree
*/
detach(): ComponentRef<any> {
if (!this.activated) throw new Error('Outlet is not activated');
if (!this.activated) {
throw new Error('Outlet is not activated');
}
this.location.detach();
const cmp = this.activated;
this.activated = null;
@@ -82,38 +100,29 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
attach(ref: ComponentRef<any>, activatedRoute: ActivatedRoute) {
this.activated = ref;
this._activatedRoute = activatedRoute;
ctrl.attachView(this.views, this.location, ref, activatedRoute);
this.location.insert(ref.hostView);
}
deactivate(): void {
if (this.activated) {
const c = this.component;
ctrl.deactivateView(this.views, this.activated);
this.activated = null;
this._activatedRoute = null;
this.deactivateEvents.emit(c);
}
}
activateWith(activatedRoute: ActivatedRoute, resolver: ComponentFactoryResolver|null) {
async activateWith(activatedRoute: ActivatedRoute, resolver: ComponentFactoryResolver|null) {
if (this.isActivated) {
throw new Error('Cannot activate an already activated outlet');
}
this._activatedRoute = activatedRoute;
const existingView = ctrl.getExistingView(this.views, activatedRoute);
if (existingView) {
// we've already got a view hanging around
this.activated = existingView.ref;
let enteringView = this.stackCtrl.getExistingView(activatedRoute);
if (enteringView) {
this.activated = enteringView.ref;
} else {
// haven't created this view yet
const snapshot = (activatedRoute as any)._futureSnapshot;
const component = <any>snapshot.routeConfig !.component;
resolver = resolver || this.resolver;
@@ -121,30 +130,47 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
const childContexts = this.parentContexts.getOrCreateContext(this.name).children;
const injector = new OutletInjector(activatedRoute, childContexts, this.location.injector);
this.activated = this.location.createComponent(factory, this.location.length, injector);
const cmp = this.activated = this.location.createComponent(factory, this.location.length, injector);
// keep a ref
ctrl.initRouteViewElm(this.views, this.activated, activatedRoute);
bindLifecycleEvents(cmp.instance, cmp.location.nativeElement);
// Calling `markForCheck` to make sure we will run the change detection when the
// `RouterOutlet` is inside a `ChangeDetectionStrategy.OnPush` component.
this.changeDetector.markForCheck();
enteringView = this.stackCtrl.createView(this.activated, activatedRoute);
}
// Calling `markForCheck` to make sure we will run the change detection when the
// `RouterOutlet` is inside a `ChangeDetectionStrategy.OnPush` component.
this.changeDetector.markForCheck();
const {direction, animated} = this.navCtrl.consumeTransition();
await this.stackCtrl.setActive(enteringView, direction, animated);
this.activateEvents.emit(this.activated.instance);
const lastDeactivatedRef = ctrl.getLastDeactivatedRef(this.views);
emitEvent(this.elementRef.nativeElement);
}
runTransition(this.activated, lastDeactivatedRef).then(() => {
console.log('transition end');
this.activateEvents.emit(this.activated.instance);
});
canGoBack(deep = 1) {
return this.stackCtrl.canGoBack(deep);
}
pop(deep = 1) {
return this.stackCtrl.pop(deep);
}
}
function emitEvent(el: HTMLElement) {
console.log('ionRouterOutletActivated');
const event = new CustomEvent('ionRouterOutletActivated', {
bubbles: true,
cancelable: true,
});
el.dispatchEvent(event);
}
class OutletInjector implements Injector {
constructor(
private route: ActivatedRoute, private childContexts: ChildrenOutletContexts,
private parent: Injector) {}
private route: ActivatedRoute,
private childContexts: ChildrenOutletContexts,
private parent: Injector
) {}
get(token: any, notFoundValue?: any): any {
if (token === ActivatedRoute) {

View File

@@ -0,0 +1,17 @@
import { ComponentFactoryResolver, Directive, ElementRef, Injector, ViewContainerRef } from '@angular/core';
import { AngularDelegate } from '../../providers/angular-delegate';
@Directive({
selector: 'ion-nav',
})
export class NavDelegate {
constructor(
ref: ElementRef,
resolver: ComponentFactoryResolver,
injector: Injector,
angularDelegate: AngularDelegate,
location: ViewContainerRef
) {
ref.nativeElement.delegate = angularDelegate.create(resolver, injector, location);
}
}

View File

@@ -0,0 +1,45 @@
/**
* @name NavParams
* @description
* NavParams are an object that exists on a page and can contain data for that particular view.
* Similar to how data was pass to a view in V1 with `$stateParams`, NavParams offer a much more flexible
* option with a simple `get` method.
*
* @usage
* ```ts
* import { NavParams } from '@ionic/angular';
*
* export class MyClass{
*
* constructor(navParams: NavParams){
* // userParams is an object we have in our nav-parameters
* navParams.get('userParams');
* }
*
* }
* ```
*/
export class NavParams {
constructor(public data: {[key: string]: any} = {}) {}
/**
* Get the value of a nav-parameter for the current view
*
* ```ts
* import { NavParams } from 'ionic-angular';
*
* export class MyClass{
* constructor(public navParams: NavParams){
* // userParams is an object we have in our nav-parameters
* this.navParams.get('userParams');
* }
* }
* ```
*
* @param {string} param Which param you want to look up
*/
get(param: string): any {
return this.data[param];
}
}

View File

@@ -0,0 +1,147 @@
import { ComponentRef } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { NavDirection } from '@ionic/core';
import { NavController } from '../../providers/nav-controller';
export class StackController {
private viewsSnapshot: RouteView[] = [];
private views: RouteView[] = [];
constructor(
private stack: boolean,
private containerEl: HTMLIonRouterOutletElement,
private router: Router,
private navCtrl: NavController,
) {}
createView(enteringRef: ComponentRef<any>, route: ActivatedRoute): RouteView {
return {
ref: enteringRef,
element: (enteringRef && enteringRef.location && enteringRef.location.nativeElement) as HTMLElement,
url: this.getUrl(route),
deactivatedId: -1
};
}
getExistingView(activatedRoute: ActivatedRoute): RouteView|null {
const activatedUrlKey = this.getUrl(activatedRoute);
return this.views.find(vw => vw.url === activatedUrlKey);
}
canGoBack(deep: number): boolean {
return this.views.length > deep;
}
async setActive(enteringView: RouteView, direction: number, animated: boolean) {
const leavingView = this.getActive();
this.insertView(enteringView, direction);
await this.transition(enteringView, leavingView, direction, animated, this.canGoBack(1));
this.cleanup();
}
pop(deep: number) {
const view = this.views[this.views.length - deep - 1];
this.navCtrl.goBack(view.url);
}
private insertView(enteringView: RouteView, direction: number) {
// no stack
if (!this.stack) {
this.views = [enteringView];
return;
}
// stack setRoot
if (direction === 0) {
this.views = [enteringView];
return;
}
// stack
const index = this.views.indexOf(enteringView);
if (index >= 0) {
this.views = this.views.slice(0, index + 1);
} else {
if (direction === 1) {
this.views.push(enteringView);
} else {
this.views = [enteringView];
}
}
}
private cleanup() {
this.viewsSnapshot
.filter(view => !this.views.includes(view))
.forEach(view => destroyView(view));
for (let i = 0; i < this.views.length - 1; i++) {
this.views[i].element.hidden = true;
}
this.viewsSnapshot = this.views.slice();
}
getActive(): RouteView | null {
return this.views.length > 0 ? this.views[this.views.length - 1] : null;
}
private async transition(
enteringView: RouteView,
leavingView: RouteView,
direction: number,
animated: boolean,
showGoBack: boolean
) {
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', 'hide-page');
containerEl.appendChild(enteringEl);
await containerEl.componentOnReady();
await containerEl.commit(enteringEl, leavingEl, {
duration: !animated ? 0 : undefined,
direction: direction === 1 ? NavDirection.Forward : NavDirection.Back,
deepWait: true,
showGoBack
});
}
}
private getUrl(activatedRoute: ActivatedRoute) {
const urlTree = this.router.createUrlTree(['.'], { relativeTo: activatedRoute });
return this.router.serializeUrl(urlTree);
}
}
export function destroyView(view: RouteView) {
if (view) {
// TODO lifecycle event
view.ref.destroy();
}
}
export function getLastDeactivatedRef(views: RouteView[]) {
if (views.length < 2) {
return null;
}
return views.sort((a, b) => {
if (a.deactivatedId > b.deactivatedId) return -1;
if (a.deactivatedId < b.deactivatedId) return 1;
return 0;
})[0].ref;
}
export interface RouteView {
url: string;
element: HTMLElement;
ref: ComponentRef<any>;
deactivatedId: number;
}

View File

@@ -0,0 +1,28 @@
import { Directive, HostListener, Input } from '@angular/core';
import { NavController, NavIntent } from '../../providers/nav-controller';
@Directive({
selector: '[routerDirection]',
})
export class RouterDirection {
@Input() routerDirection: string;
constructor(
private navCtrl: NavController,
) {}
@HostListener('click')
onClick() {
this.navCtrl.setIntent(textToIntent(this.routerDirection));
}
}
function textToIntent(direction: string) {
switch (direction) {
case 'forward': return NavIntent.Forward;
case 'back': return NavIntent.Back;
case 'root': return NavIntent.Root;
default: return NavIntent.Auto;
}
}

View File

@@ -0,0 +1,32 @@
import { ComponentFactoryResolver, Directive, ElementRef, HostListener, Injector, ViewContainerRef } from '@angular/core';
import { AngularDelegate } from '../../providers/angular-delegate';
@Directive({
selector: 'ion-tab'
})
export class TabDelegate {
constructor(
private elementRef: ElementRef,
resolver: ComponentFactoryResolver,
injector: Injector,
angularDelegate: AngularDelegate,
location: ViewContainerRef
) {
elementRef.nativeElement.delegate = angularDelegate.create(resolver, injector, location);
}
@HostListener('ionRouterOutletActivated', ['$event'])
async onNavChanged() {
const tab = this.elementRef.nativeElement as HTMLIonTabElement;
await tab.componentOnReady();
const tabs = tab.closest('ion-tabs');
if (tabs) {
await tabs.componentOnReady();
await tabs.select(tab);
}
}
}

View File

@@ -0,0 +1,25 @@
import { Directive, ElementRef, HostListener, Optional } from '@angular/core';
import { Router } from '@angular/router';
@Directive({
selector: 'ion-tabs'
})
export class TabsDelegate {
constructor(
@Optional() private router: Router,
elementRef: ElementRef
) {
if (router) {
elementRef.nativeElement.useRouter = true;
}
}
@HostListener('ionTabbarClick', ['$event'])
onTabbarClick(ev: UIEvent) {
const tabElm: HTMLIonTabElement = ev.detail as any;
if (this.router && tabElm && tabElm.href) {
this.router.navigateByUrl(tabElm.href);
}
}
}

View File

@@ -0,0 +1,79 @@
import * as d from './proxies';
export const DIRECTIVES = [
d.App,
d.Avatar,
d.BackButton,
d.Badge,
d.Button,
d.Buttons,
d.Card,
d.CardContent,
d.CardHeader,
d.CardSubtitle,
d.CardTitle,
d.Checkbox,
d.Chip,
d.ChipButton,
d.Col,
d.Content,
d.Datetime,
d.Fab,
d.FabButton,
d.FabList,
d.Footer,
d.Grid,
d.Header,
d.HideWhen,
d.InfiniteScroll,
d.InfiniteScrollContent,
d.Input,
d.Item,
d.ItemDivider,
d.ItemGroup,
d.ItemOption,
d.ItemOptions,
d.ItemSliding,
d.Label,
d.List,
d.ListHeader,
d.Menu,
d.MenuButton,
d.MenuToggle,
d.Nav,
d.NavPop,
d.NavPush,
d.NavSetRoot,
d.Note,
d.Radio,
d.RadioGroup,
d.Range,
d.Refresher,
d.RefresherContent,
d.Reorder,
d.ReorderGroup,
d.RippleEffect,
d.Row,
d.Scroll,
d.Searchbar,
d.Segment,
d.SegmentButton,
d.Select,
d.SelectOption,
d.SelectPopover,
d.ShowWhen,
d.SkeletonText,
d.Slide,
d.Slides,
d.Spinner,
d.SplitPane,
d.Tab,
d.Tabs,
d.Text,
d.Textarea,
d.Thumbnail,
d.Toggle,
d.Toolbar,
d.ToolbarTitle
];

View File

File diff suppressed because one or more lines are too long

20
angular/src/index.ts Normal file
View File

@@ -0,0 +1,20 @@
// export module
export { IonicModule } from './module';
// export auto generated directive
export * from './directives/proxies';
// export custom directives
export * from './directives';
// export custom providers
export * from './providers';
// ionic types
export * from './types/interfaces';
// ionic oute reuse strategy
export * from './util/ionic-router-reuse-strategy';
/*tslint:disable*/
import './ionic-angular';

View File

@@ -0,0 +1,32 @@
/*tslint:disable*/
import './ionic';
import { IonicWindow } from './types/interfaces';
const win = (window as IonicWindow);
const Ionic = win.Ionic;
if (Ionic) {
Ionic.ael = function ngAddEventListener(elm, eventName, cb, opts) {
if (elm.__zone_symbol__addEventListener) {
elm.__zone_symbol__addEventListener(eventName, cb, opts);
} else {
elm.addEventListener(eventName, cb, opts);
}
};
Ionic.rel = function ngRemoveEventListener(elm, eventName, cb, opts) {
if (elm.__zone_symbol__removeEventListener) {
elm.__zone_symbol__removeEventListener(eventName, cb, opts);
} else {
elm.removeEventListener(eventName, cb, opts);
}
};
Ionic.raf = function ngRequestAnimationFrame(cb: any) {
if (win.__zone_symbol__requestAnimationFrame) {
win.__zone_symbol__requestAnimationFrame(cb);
} else {
win.requestAnimationFrame(cb);
}
};
}

3
angular/src/ionic.ts Normal file
View File

@@ -0,0 +1,3 @@
// placeholder for ionic loader js
// created by the stencil build process

156
angular/src/module.ts Normal file
View File

@@ -0,0 +1,156 @@
import { InjectionToken, ModuleWithProviders, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import * as c from './directives';
import * as d from './directives/proxies';
import * as p from './providers';
const DECLARATIONS = [
// proxies
d.App,
d.Avatar,
d.BackButton,
d.Badge,
d.Button,
d.Buttons,
d.Card,
d.CardContent,
d.CardHeader,
d.CardSubtitle,
d.CardTitle,
d.Checkbox,
d.Chip,
d.ChipButton,
d.Col,
d.Content,
d.Datetime,
d.Fab,
d.FabButton,
d.FabList,
d.Footer,
d.Grid,
d.Header,
d.HideWhen,
d.InfiniteScroll,
d.InfiniteScrollContent,
d.Input,
d.Item,
d.ItemDivider,
d.ItemGroup,
d.ItemOption,
d.ItemOptions,
d.ItemSliding,
d.Label,
d.List,
d.ListHeader,
d.Menu,
d.MenuButton,
d.MenuToggle,
d.Nav,
d.NavPop,
d.NavPush,
d.NavSetRoot,
d.Note,
d.Radio,
d.RadioGroup,
d.Range,
d.Refresher,
d.RefresherContent,
d.Reorder,
d.ReorderGroup,
d.RippleEffect,
d.Row,
d.Scroll,
d.Searchbar,
d.Segment,
d.SegmentButton,
d.Select,
d.SelectOption,
d.SelectPopover,
d.ShowWhen,
d.SkeletonText,
d.Slide,
d.Slides,
d.Spinner,
d.SplitPane,
d.Tab,
d.Tabs,
d.Text,
d.Textarea,
d.Thumbnail,
d.Toggle,
d.Toolbar,
d.ToolbarTitle,
// custom proxy
c.Icon,
// ngModel accessors
c.BooleanValueAccessor,
c.NumericValueAccessor,
c.RadioValueAccessor,
c.SelectValueAccessor,
c.TextValueAccessor,
// navigation
c.IonBackButton,
c.IonRouterOutlet,
c.RouterDirection,
c.NavDelegate,
c.TabDelegate,
c.TabsDelegate,
c.HrefDelegate,
// virtual scroll
c.VirtualFooter,
c.VirtualHeader,
c.VirtualItem,
c.VirtualScroll,
];
const PROVIDERS = [
p.ActionSheetController,
p.AlertController,
p.LoadingController,
p.PickerController,
p.ToastController,
p.MenuController,
p.NavController,
p.Platform,
p.Events,
p.DomController,
];
@NgModule({
declarations: DECLARATIONS,
exports: DECLARATIONS,
providers: [
p.AngularDelegate,
p.ModalController,
p.PopoverController,
],
imports: [
CommonModule,
]
})
export class IonicModule {
static forRoot(config?: {[key: string]: any}): ModuleWithProviders {
return {
ngModule: IonicModule,
providers: [
// Load config with defualt values
{ provide: ConfigToken, useValue: config },
{ provide: p.Config, useFactory: setupConfig, deps: [ ConfigToken ] },
...PROVIDERS,
]
};
}
}
export const ConfigToken = new InjectionToken<any>('USERCONFIG');
export function setupConfig(userConfig: any): p.Config {
const config = new p.Config(userConfig);
return config;
}

View File

@@ -0,0 +1,10 @@
import { Injectable } from '@angular/core';
import { ActionSheetOptions } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
@Injectable()
export class ActionSheetController extends OverlayBaseController<ActionSheetOptions, HTMLIonActionSheetElement> {
constructor() {
super('ion-action-sheet-controller');
}
}

View File

@@ -0,0 +1,10 @@
import { Injectable } from '@angular/core';
import { AlertOptions } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
@Injectable()
export class AlertController extends OverlayBaseController<AlertOptions, HTMLIonAlertElement> {
constructor() {
super('ion-alert-controller');
}
}

View File

@@ -0,0 +1,129 @@
import { ApplicationRef, ComponentFactoryResolver, Injectable, InjectionToken, Injector, NgZone, ViewContainerRef } from '@angular/core';
import { FrameworkDelegate, ViewLifecycle } from '@ionic/core';
import { NavParams } from '../directives/navigation/nav-params';
@Injectable()
export class AngularDelegate {
constructor(
private zone: NgZone,
private appRef: ApplicationRef
) {}
create(
resolver: ComponentFactoryResolver,
injector: Injector,
location?: ViewContainerRef,
) {
return new AngularFrameworkDelegate(resolver, injector, location, this.appRef, this.zone);
}
}
export class AngularFrameworkDelegate implements FrameworkDelegate {
private elRefMap = new WeakMap<HTMLElement, any>();
constructor(
private resolver: ComponentFactoryResolver,
private injector: Injector,
private location: ViewContainerRef,
private appRef: ApplicationRef,
private zone: NgZone,
) {}
attachViewToDom(container: any, component: any, params?: any, cssClasses?: string[]): Promise<any> {
return new Promise(resolve => {
this.zone.run(() => {
const el = attachView(
this.resolver, this.injector, this.location, this.appRef, this.elRefMap,
container, component, params, cssClasses
);
resolve(el);
});
});
}
removeViewFromDom(_container: any, component: any): Promise<void> {
return new Promise(resolve => {
this.zone.run(() => {
const componentRef = this.elRefMap.get(component);
if (componentRef) {
componentRef.destroy();
this.elRefMap.delete(component);
}
resolve();
});
});
}
}
export function attachView(
resolver: ComponentFactoryResolver,
injector: Injector,
location: ViewContainerRef|undefined,
appRef: ApplicationRef,
elRefMap: WeakMap<HTMLElement, any>,
container: any, component: any, params: any, cssClasses: string[]
) {
const factory = resolver.resolveComponentFactory(component);
const childInjector = Injector.create(getProviders(params), injector);
const componentRef = (location)
? location.createComponent(factory, location.length, childInjector)
: factory.create(childInjector);
const hostElement = componentRef.location.nativeElement;
if (params) {
Object.assign(hostElement, params);
}
for (const clazz of cssClasses) {
hostElement.classList.add(clazz);
}
bindLifecycleEvents(componentRef.instance, hostElement);
container.appendChild(hostElement);
if (!location) {
appRef.attachView(componentRef.hostView);
}
componentRef.changeDetectorRef.reattach();
elRefMap.set(hostElement, componentRef);
return hostElement;
}
const LIFECYCLES = [
ViewLifecycle.WillEnter,
ViewLifecycle.DidEnter,
ViewLifecycle.WillLeave,
ViewLifecycle.DidLeave,
ViewLifecycle.WillUnload
];
export function bindLifecycleEvents(instance: any, element: HTMLElement) {
LIFECYCLES.forEach(eventName => {
element.addEventListener(eventName, (ev: CustomEvent) => {
if (typeof instance[eventName] === 'function') {
instance[eventName](ev.detail);
}
});
});
}
const NavParamsToken = new InjectionToken<any>('NavParamsToken');
function getProviders(params: {[key: string]: any}) {
return [
{
provide: NavParamsToken, useValue: params
},
{
provide: NavParams, useFactory: provideNavParamsInjectable, deps: [NavParamsToken]
}
];
}
function provideNavParamsInjectable(params: {[key: string]: any}) {
return new NavParams(params);
}

View File

@@ -0,0 +1,40 @@
import { Config as CoreConfig } from '@ionic/core';
export class Config {
constructor(defaultConfig: {[key: string]: any}) {
const Ionic = (window as any).Ionic;
if (Ionic.config && Ionic.config.constructor.name !== 'Object') {
console.error('ionic config was already initialized');
return;
}
Ionic.config = {
...Ionic.config,
...defaultConfig
};
}
get(key: string, fallback?: any): any {
return getConfig().get(key, fallback);
}
getBoolean(key: string, fallback?: boolean): boolean {
return getConfig().getBoolean(key, fallback);
}
getNumber(key: string, fallback?: number): number {
return getConfig().getNumber(key, fallback);
}
set(key: string, value?: any) {
getConfig().set(key, value);
}
}
function getConfig(): CoreConfig {
const Ionic = (window as any).Ionic;
if (Ionic && Ionic.config) {
return Ionic.config;
}
return null;
}

View File

@@ -0,0 +1,27 @@
import { Injectable } from '@angular/core';
@Injectable()
export class DomController {
read(cb: RafCallback) {
getQueue().read(cb);
}
write(cb: RafCallback) {
getQueue().write(cb);
}
}
function getQueue() {
const Ionic = (window as any).Ionic;
if (Ionic && Ionic.queue) {
return Ionic.queue;
}
return {
read: (cb: any) => window.requestAnimationFrame(cb),
write: (cb: any) => window.requestAnimationFrame(cb)
};
}
export type RafCallback = { (timeStamp?: number): void };

View File

@@ -0,0 +1,15 @@
export { AngularDelegate } from './angular-delegate';
export { ActionSheetController } from './action-sheet-controller';
export { AlertController } from './alert-controller';
export { Events } from './events';
export { LoadingController } from './loading-controller';
export { MenuController } from './menu-controller';
export { PickerController } from './picker-controller';
export { ModalController } from './modal-controller';
export { Platform } from './platform';
export { PopoverController } from './popover-controller';
export { ToastController } from './toast-controller';
export { NavController } from './nav-controller';
export { DomController } from './dom-controller';
export { Config } from './config';

View File

@@ -0,0 +1,10 @@
import { Injectable } from '@angular/core';
import { LoadingOptions } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
@Injectable()
export class LoadingController extends OverlayBaseController<LoadingOptions, HTMLIonLoadingElement> {
constructor() {
super('ion-loading-controller');
}
}

View File

@@ -0,0 +1,104 @@
import { Injectable } from '@angular/core';
import { proxyMethod } from '../util/util';
const CTRL = 'ion-menu-controller';
@Injectable()
export class MenuController {
/**
* Programatically open the Menu.
* @param {string} [menuId] Optionally get the menu by its id, or side.
* @return {Promise} returns a promise when the menu is fully opened
*/
open(menuId?: string): Promise<boolean> {
return proxyMethod(CTRL, 'open', menuId);
}
/**
* Programatically close the Menu. If no `menuId` is given as the first
* argument then it'll close any menu which is open. If a `menuId`
* is given then it'll close that exact menu.
* @param {string} [menuId] Optionally get the menu by its id, or side.
* @return {Promise} returns a promise when the menu is fully closed
*/
close(menuId?: string): Promise<boolean> {
return proxyMethod(CTRL, 'close', menuId);
}
/**
* Toggle the menu. If it's closed, it will open, and if opened, it
* will close.
* @param {string} [menuId] Optionally get the menu by its id, or side.
* @return {Promise} returns a promise when the menu has been toggled
*/
toggle(menuId?: string): Promise<boolean> {
return proxyMethod(CTRL, 'toggle', menuId);
}
/**
* Used to enable or disable a menu. For example, there could be multiple
* left menus, but only one of them should be able to be opened at the same
* time. If there are multiple menus on the same side, then enabling one menu
* will also automatically disable all the others that are on the same side.
* @param {string} [menuId] Optionally get the menu by its id, or side.
* @return {HTMLIonMenuElement} Returns the instance of the menu, which is useful for chaining.
*/
enable(shouldEnable: boolean, menuId?: string): Promise<HTMLIonMenuElement> {
return proxyMethod(CTRL, 'enable', shouldEnable, menuId);
}
/**
* Used to enable or disable the ability to swipe open the menu.
* @param {boolean} shouldEnable True if it should be swipe-able, false if not.
* @param {string} [menuId] Optionally get the menu by its id, or side.
* @return {HTMLIonMenuElement} Returns the instance of the menu, which is useful for chaining.
*/
swipeEnable(shouldEnable: boolean, menuId?: string): Promise<HTMLIonMenuElement> {
return proxyMethod(CTRL, 'swipeEnable', shouldEnable, menuId);
}
/**
* @param {string} [menuId] Optionally get the menu by its id, or side.
* @return {boolean} 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, 'isOpen', menuId);
}
/**
* @param {string} [menuId] Optionally get the menu by its id, or side.
* @return {boolean} Returns true if the menu is currently enabled, otherwise false.
*/
isEnabled(menuId?: string): Promise<boolean> {
return proxyMethod(CTRL, 'isEnabled', menuId);
}
/**
* Used to get a menu instance. If a `menuId` is not provided then it'll
* return the first menu found. If a `menuId` is `left` or `right`, then
* it'll return the enabled menu on that side. Otherwise, if a `menuId` is
* provided, then it'll try to find the menu using the menu's `id`
* property. If a menu is not found then it'll return `null`.
* @param {string} [menuId] Optionally get the menu by its id, or side.
* @return {HTMLIonMenuElement} Returns the instance of the menu if found, otherwise `null`.
*/
get(menuId?: string): Promise<HTMLIonMenuElement> {
return proxyMethod(CTRL, 'get', menuId);
}
/**
* @return {Menu} Returns the instance of the menu already opened, otherwise `null`.
*/
getOpen(): Promise<HTMLIonMenuElement> {
return proxyMethod(CTRL, 'getOpen');
}
/**
* @return {Array<HTMLIonMenuElement>} Returns an array of all menu instances.
*/
getMenus(): Promise<HTMLIonMenuElement[]> {
return proxyMethod(CTRL, 'getMenus');
}
}

View File

@@ -0,0 +1,23 @@
import { ComponentFactoryResolver, Injectable, Injector } from '@angular/core';
import { ModalOptions } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
import { AngularDelegate } from './angular-delegate';
@Injectable()
export class ModalController extends OverlayBaseController<ModalOptions, HTMLIonModalElement> {
constructor(
private angularDelegate: AngularDelegate,
private resolver: ComponentFactoryResolver,
private injector: Injector,
) {
super('ion-modal-controller');
}
create(opts?: ModalOptions): Promise<HTMLIonModalElement> {
return super.create({
...opts,
delegate: this.angularDelegate.create(this.resolver, this.injector)
});
}
}

View File

@@ -0,0 +1,85 @@
import { Injectable, Optional } from '@angular/core';
import { NavigationExtras, Router, UrlTree } from '@angular/router';
export const enum NavIntent {
Auto,
Forward,
Back,
Root
}
@Injectable()
export class NavController {
private intent: NavIntent = NavIntent.Auto;
private animated = true;
private stack: string[] = [];
constructor(
@Optional() private router?: Router
) {}
goForward(url: string | UrlTree, animated?: boolean, extras?: NavigationExtras) {
this.setIntent(NavIntent.Forward, animated);
return this.router.navigateByUrl(url, extras);
}
goBack(url: string | UrlTree, animated?: boolean, extras?: NavigationExtras) {
this.setIntent(NavIntent.Back, animated);
return this.router.navigateByUrl(url, extras);
}
goRoot(url: string | UrlTree, animated?: boolean, extras?: NavigationExtras) {
this.setIntent(NavIntent.Root, animated);
return this.router.navigateByUrl(url, extras);
}
setIntent(intent: NavIntent, animated?: boolean) {
this.intent = intent;
this.animated = (animated === undefined)
? intent !== NavIntent.Root
: animated;
}
consumeTransition() {
const guessDirection = this.guessDirection();
let direction = 0;
let animated = false;
if (this.intent === NavIntent.Auto) {
direction = guessDirection;
animated = direction !== 0;
} else {
animated = this.animated;
direction = intentToDirection(this.intent);
}
this.intent = NavIntent.Auto;
this.animated = true;
return {
direction,
animated
};
}
private guessDirection() {
const index = this.stack.indexOf(document.location.href);
if (index === -1) {
this.stack.push(document.location.href);
return 1;
} else if (index < this.stack.length - 1) {
this.stack = this.stack.slice(0, index + 1);
return -1;
}
return 0;
}
}
function intentToDirection(intent: NavIntent): number {
switch (intent) {
case NavIntent.Forward: return 1;
case NavIntent.Back: return -1;
default: return 0;
}
}

View File

@@ -0,0 +1,10 @@
import { Injectable } from '@angular/core';
import { PickerOptions } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
@Injectable()
export class PickerController extends OverlayBaseController<PickerOptions, HTMLIonPickerElement> {
constructor() {
super('ion-picker-controller');
}
}

View File

@@ -0,0 +1,199 @@
import { EventEmitter, Injectable } from '@angular/core';
import { proxyEvent } from '../util/util';
export interface PlatformConfig {
name: string;
isMatch: (win: Window) => boolean;
}
@Injectable()
export class Platform {
private _platforms: PlatformConfig[] = [];
private _readyPromise: Promise<any>;
/**
* @hidden
*/
backButton = new EventEmitter<Event>();
/**
* The pause event emits when the native platform puts the application
* into the background, typically when the user switches to a different
* application. This event would emit when a Cordova app is put into
* the background, however, it would not fire on a standard web browser.
*/
pause = new EventEmitter<Event>();
/**
* The resume event emits when the native platform pulls the application
* out from the background. This event would emit when a Cordova app comes
* out from the background, however, it would not fire on a standard web browser.
*/
resume = new EventEmitter<Event>();
/**
* The resize event emits when the browser window has changed dimensions. This
* could be from a browser window being physically resized, or from a device
* changing orientation.
*/
resize = new EventEmitter<Event>();
constructor() {
proxyEvent(this.pause, document, 'pause');
proxyEvent(this.resume, document, 'resume');
proxyEvent(this.backButton, document, 'backbutton');
proxyEvent(this.resize, document, 'resize');
let readyResolve: Function;
this._readyPromise = new Promise(res => { readyResolve = res; } );
if ((window as any)['cordova']) {
window.addEventListener('deviceready', () => {
readyResolve();
});
} else {
readyResolve();
}
}
/**
* @returns {boolean} returns true/false based on platform.
* @description
* Depending on the platform the user is on, `is(platformName)` will
* return `true` or `false`. Note that the same app can return `true`
* for more than one platform name. For example, an app running from
* an iPad would return `true` for the platform names: `mobile`,
* `ios`, `ipad`, and `tablet`. Additionally, if the app was running
* from Cordova then `cordova` would be true, and if it was running
* from a web browser on the iPad then `mobileweb` would be `true`.
*
* ```
* import { Platform } from 'ionic-angular';
*
* @Component({...})
* export MyPage {
* constructor(public platform: Platform) {
* if (this.platform.is('ios')) {
* // This will only print when on iOS
* console.log('I am an iOS device!');
* }
* }
* }
* ```
*
* | Platform Name | Description |
* |-----------------|------------------------------------|
* | android | on a device running Android. |
* | cordova | on a device running Cordova. |
* | core | on a desktop device. |
* | ios | on a device running iOS. |
* | ipad | on an iPad device. |
* | iphone | on an iPhone device. |
* | mobile | on a mobile device. |
* | mobileweb | in a browser on a mobile device. |
* | phablet | on a phablet device. |
* | tablet | on a tablet device. |
* | windows | on a device running Windows. |
* | electron | in Electron on a desktop device. |
*
* @param {string} platformName
*/
is(platformName: string): boolean {
return this._platforms.some(p => p.name === platformName);
}
/**
* @returns {array} the array of platforms
* @description
* Depending on what device you are on, `platforms` can return multiple values.
* Each possible value is a hierarchy of platforms. For example, on an iPhone,
* it would return `mobile`, `ios`, and `iphone`.
*
* ```
* import { Platform } from 'ionic-angular';
*
* @Component({...})
* export MyPage {
* constructor(public platform: Platform) {
* // This will print an array of the current platforms
* console.log(this.platform.platforms());
* }
* }
* ```
*/
platforms(): string[] {
return this._platforms.map(platform => platform.name);
}
/**
* Returns an object containing version information about all of the platforms.
*
* ```
* import { Platform } from 'ionic-angular';
*
* @Component({...})
* export MyPage {
* constructor(public platform: Platform) {
* // This will print an object containing
* // all of the platforms and their versions
* console.log(platform.versions());
* }
* }
* ```
*
* @returns {object} An object containing all of the platforms and their versions.
*/
versions(): PlatformConfig[] {
return this._platforms.slice();
}
ready(): Promise<void> {
return this._readyPromise;
}
get isRTL(): boolean {
return document.dir === 'rtl';
}
/**
* Get the query string parameter
*/
getQueryParam(key: string): string {
return readQueryParam(window.location.href, key);
}
isLandscape(): boolean {
return !this.isPortrait();
}
isPortrait(): boolean {
return window.matchMedia('(orientation: portrait)').matches;
}
testUserAgent(expression: string): boolean {
return navigator.userAgent.indexOf(expression) >= 0;
}
url() {
return window.location.href;
}
width() {
return window.innerWidth;
}
height(): number {
return window.innerHeight;
}
}
function readQueryParam(url: string, key: string) {
key = key.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
const regex = new RegExp('[\\?&]' + key + '=([^&#]*)');
const results = regex.exec(url);
return results ? decodeURIComponent(results[1].replace(/\+/g, ' ')) : null;
}

View File

@@ -0,0 +1,23 @@
import { ComponentFactoryResolver, Injectable, Injector } from '@angular/core';
import { PopoverOptions } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
import { AngularDelegate } from './angular-delegate';
@Injectable()
export class PopoverController extends OverlayBaseController<PopoverOptions, HTMLIonPopoverElement> {
constructor(
private angularDelegate: AngularDelegate,
private resolver: ComponentFactoryResolver,
private injector: Injector,
) {
super('ion-popover-controller');
}
create(opts?: PopoverOptions): Promise<HTMLIonPopoverElement> {
return super.create({
...opts,
delegate: this.angularDelegate.create(this.resolver, this.injector)
});
}
}

View File

@@ -0,0 +1,10 @@
import { Injectable } from '@angular/core';
import { ToastOptions } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
@Injectable()
export class ToastController extends OverlayBaseController<ToastOptions, HTMLIonToastElement> {
constructor() {
super('ion-toast-controller');
}
}

View File

@@ -0,0 +1,28 @@
import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router';
import { deepEqual, objectValues } from './util';
export class IonicRouteStrategy implements RouteReuseStrategy {
shouldDetach(_route: ActivatedRouteSnapshot): boolean {
return false;
}
// tslint:disable-next-line
store(_route: ActivatedRouteSnapshot, _detachedTree: DetachedRouteHandle): void { }
shouldAttach(_route: ActivatedRouteSnapshot): boolean {
return false;
}
retrieve(_route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
return null;
}
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
if (objectValues(future.params) && objectValues(curr.params)) {
return deepEqual(future.params, curr.params);
} else {
return future.routeConfig === curr.routeConfig;
}
}
}

View File

@@ -0,0 +1,17 @@
import { proxyMethod } from '../util/util';
export class OverlayBaseController<Opts, Overlay> {
constructor(private ctrl: string) {}
create(opts?: Opts): Promise<Overlay> {
return proxyMethod(this.ctrl, 'create', opts);
}
dismiss(data?: any, role?: string, id = -1): Promise<void> {
return proxyMethod(this.ctrl, 'dismiss', data, role, id);
}
getTop(): Promise<Overlay> {
return proxyMethod(this.ctrl, 'getTop');
}
}

52
angular/src/util/util.ts Normal file
View File

@@ -0,0 +1,52 @@
import { ElementRef } from '@angular/core';
export function inputs(instance: any, el: ElementRef, props: string[]) {
props.forEach(propName => {
Object.defineProperty(instance, propName, {
get: () => el.nativeElement[propName], set: (val: any) => el.nativeElement[propName] = val
});
});
}
export function proxyEvent(emitter: any, el: Node, eventName: string) {
el.addEventListener(eventName, (ev) => {
emitter.emit(ev);
});
}
export function proxyMethod(ctrlName: string, methodName: string, ...args: any[]) {
const controller = ensureElementInBody(ctrlName);
return controller.componentOnReady()
.then(() => (controller as any)[methodName].apply(controller, args));
}
export function ensureElementInBody(elementName: string) {
let element = document.querySelector(elementName);
if (!element) {
element = document.createElement(elementName);
document.body.appendChild(element);
}
return element as HTMLStencilElement;
}
export function objectValues(obj: any): any[] {
return Object.keys(obj).map(key => obj[key]);
}
export function deepEqual(x: any, y: any) {
if (x === y) {
return true;
} else if (typeof x === 'object' && x != null && (typeof y === 'object' && y != null)) {
if (Object.keys(x).length !== Object.keys(y).length) return false;
for (const prop in x) {
if (y.hasOwnProperty(prop)) {
if (!deepEqual(x[prop], y[prop])) return false;
} else return false;
}
return true;
} else return false;
}

72
angular/stencil.config.js Normal file
View File

@@ -0,0 +1,72 @@
const path = require('path');
// use ionic/core's stencil config
exports.config = require('../core/stencil.config.js').config;
// user ionic core's tsconfig
exports.config.tsconfig ='../core/tsconfig.json';
// update where to find the original ionic/core src
exports.config.srcDir = '../core/src';
exports.config.globalScript = '../core/src/global/ionic-global.ts';
// update the output targets
exports.config.outputTargets = [
{
type: 'angular',
directivesProxyFile: 'src/directives/proxies.ts',
directivesArrayFile: 'src/directives/proxies-list.txt',
empty: false,
excludeComponents: [
// overlays
'ion-action-sheet',
'ion-action-sheet-controller',
'ion-alert',
'ion-alert-controller',
'ion-loading',
'ion-loading-controller',
'ion-modal',
'ion-modal-controller',
'ion-picker',
'ion-picker-controller',
'ion-popover',
'ion-popover-controller',
'ion-toast',
'ion-toast-controller',
'ion-toast',
// controllers
'ion-menu-controller',
'ion-animation-controller',
'ion-animation-controller',
'ion-gesture-controller',
'ion-platform',
'ion-cordova-platform',
// navigation
'ion-router',
'ion-route',
'ion-route-redirect',
'ion-router-outlet',
'ion-anchor',
'ion-tabbar',
'ion-tab-button',
// auxiliar
'ion-gesture',
'ion-status-tap',
'ion-tap-click',
'ion-picker-column',
'ion-range-knob',
'ion-input-shims',
'ion-backdrop',
'ion-anchor',
'ion-virtual-scroll'
]
}
]
exports.devServer = {
root: '.',
watchGlob: ['dist/*.*', 'dist/ionic/**/**', 'src/**/*.html']
};

View File

@@ -10,7 +10,11 @@
"assets": [
"assets",
"favicon.ico",
{ "glob": "**/*", "input": "../node_modules/@ionic/core/dist", "output": "./ionic/core" }
{
"glob": "**/*",
"input": "../node_modules/@ionic/angular/dist/ionic",
"output": "./ionic"
}
],
"index": "index.html",
"main": "main.ts",
@@ -57,5 +61,8 @@
"defaults": {
"styleExt": "scss",
"component": {}
},
"warnings": {
"typescriptMismatch": false
}
}

View File

@@ -22,11 +22,7 @@ module.exports = function(config) {
angularCli: {
environment: 'dev'
},
files: [
// TODO: I have not fully worked out how this will work.
// Perhaps just the base include with a plugin?
{ pattern: '../node_modules/@ionic/core/dist/ionic.js', watched: false, served: false, nocache: true, included: true }
],
files: [],
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,7 @@
{
"name": "@ionic/angular-demo",
"version": "0.0.0",
"name": "@ionic/angular-test-nav",
"private": true,
"version": "0.0.1",
"license": "MIT",
"scripts": {
"ng": "ng",
@@ -8,27 +9,24 @@
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"override-router": "rm -rf ./node_modules/@angular/router && mkdir ./node_modules/@angular/router && cp -R ./scripts/router ./node_modules/@angular"
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "latest",
"@angular/common": "latest",
"@angular/compiler": "latest",
"@angular/core": "latest",
"@angular/forms": "latest",
"@angular/http": "latest",
"@angular/platform-browser": "latest",
"@angular/platform-browser-dynamic": "latest",
"@angular/router": "latest",
"@angular/animations": "^6.0.0-rc.3",
"@angular/common": "^6.0.0-rc.3",
"@angular/compiler": "^6.0.0-rc.3",
"@angular/core": "^6.0.0-rc.3",
"@angular/forms": "^6.0.0-rc.3",
"@angular/http": "^6.0.0-rc.3",
"@angular/platform-browser": "^6.0.0-rc.3",
"@angular/platform-browser-dynamic": "^6.0.0-rc.3",
"@angular/router": "^6.0.0-rc.3",
"@ionic/angular": "next",
"@ionic/core": "next",
"body-parser": "^1.18.2",
"core-js": "^2.4.1",
"express": "^4.16.2",
"rxjs": "^5.5.2",
"zone.js": "^0.8.14"
"rxjs": "^6.0.0-terrific-rc.3",
"zone.js": "^0.8.20"
},
"devDependencies": {
"@angular/cli": "latest",

View File

@@ -6,16 +6,14 @@ import { ActionSheetController } from '@ionic/angular';
selector: 'app-action-sheet-page',
template: `
<ion-app>
<ion-page class="show-page">
<ion-header>
<ion-toolbar>
<ion-title>Test</ion-title>
<ion-title>Action Sheet</ion-title>
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-button (click)="clickMe()">Open Basic ActionSheet</ion-button>
</ion-content>
</ion-page>
</ion-app>
`
})
@@ -25,9 +23,9 @@ export class ActionSheetPageComponent {
}
clickMe() {
const actionSheet = this.actionSheetController.create({
title: 'Albums',
async clickMe() {
const actionSheet = await this.actionSheetController.create({
header: 'Albums',
buttons: [{
text: 'Delete',
role: 'destructive',

View File

@@ -1,15 +1,16 @@
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { ActionSheetPageComponent } from './action-sheet-page.component';
import { ActionSheetRoutingModule } from './action-sheet-routing.module';
@NgModule({
imports: [
CommonModule,
IonicModule,
ActionSheetRoutingModule
],
declarations: [ActionSheetPageComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
declarations: [ActionSheetPageComponent]
})
export class ActionSheetModule { }

View File

@@ -6,28 +6,24 @@ import { AlertController } from '@ionic/angular';
selector: 'app-alert-page',
template: `
<ion-app>
<ion-page class="show-page">
<ion-header>
<ion-toolbar>
<ion-title>Test</ion-title>
<ion-title>Alert</ion-title>
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-button (click)="clickMe()">Open Basic Alert</ion-button>
</ion-content>
</ion-page>
</ion-app>
`
})
export class AlertPageComponent {
constructor(private alertController: AlertController) {
constructor(private alertController: AlertController) {}
}
clickMe() {
const alert = this.alertController.create({
title: 'ohhhh snap',
async clickMe() {
const alert = await this.alertController.create({
header: 'ohhhh snap',
message: 'Ive been injected via Angular keeping the old api',
buttons: [
{
@@ -45,14 +41,8 @@ export class AlertPageComponent {
}
}
]
});
alert.present().then(() => {
// return alert.dismiss();
}).then(() => {
console.log('dismissed');
});
return alert.present();
}
}

View File

@@ -1,15 +1,16 @@
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { AlertPageComponent } from './alert-page.component';
import { AlertRoutingModule } from './alert-routing.module';
@NgModule({
imports: [
CommonModule,
IonicModule,
AlertRoutingModule
],
declarations: [AlertPageComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
declarations: [AlertPageComponent]
})
export class AlertModule { }

View File

@@ -0,0 +1,35 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'basic-inputs', loadChildren: './basic-inputs-page/basic-inputs-page.module#BasicInputsPageModule' },
{ path: 'show-hide-when', loadChildren: './show-hide-when/show-hide-when.module#ShowHideWhenModule' },
{ path: 'form-sample', loadChildren: './form-sample-page/form-sample-page.module#FormSamplePageModule' },
{ path: 'group-inputs', loadChildren: './group-inputs-page/group-inputs-page.module#GroupInputsPageModule' },
{ path: 'home', loadChildren: './home-page/home-page.module#HomePageModule' },
{ path: 'alert', loadChildren: './alert/alert.module#AlertModule' },
{ path: 'actionSheet', loadChildren: './action-sheet/action-sheet.module#ActionSheetModule' },
{ path: 'badge', loadChildren: './badge/badge.module#BadgeModule' },
{ path: 'card', loadChildren: './card/card.module#CardModule' },
{ path: 'content', loadChildren: './content/content.module#ContentModule' },
{ path: 'toast', loadChildren: './toast/toast.module#ToastModule' },
{ path: 'loading', loadChildren: './loading/loading.module#LoadingModule' },
{ path: 'modal', loadChildren: './modal/modal.module#ModalModule' },
{ path: 'ng-if', loadChildren: './ng-if/ng-if.module#NgIfModule' },
{ path: 'popover', loadChildren: './popover/popover.module#PopoverModule' },
{ path: 'segment', loadChildren: './segment/segment.module#SegmentModule' },
{ path: 'virtual-scroll', loadChildren: './virtual-scroll/virtual-scroll.module#VirtualScrollModule' },
{ path: 'no-routing-nav', loadChildren: './no-routing-nav/no-routing-nav.module#NoRoutingNavModule' },
{ path: 'simple-nav', loadChildren: './simple-nav/simple-nav.module#SimpleNavModule' },
{ path: 'lazy-load-tabs', loadChildren: './lazy-load-tabs/tabs.module#TabsModule' },
{ path: 'simple-tabs', loadChildren: './simple-tabs/tabs.module#TabsModule' },
{ path: 'static-tabs', loadChildren: './static-tabs/tabs.module#TabsModule' },
];
@NgModule({
imports: [RouterModule.forRoot(routes, { enableTracing: true })],
exports: [RouterModule]
})
export class AppRoutingModule { }

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