Compare commits

...

424 Commits

Author SHA1 Message Date
Liam DeBeasi
fd65ceec84 5.2.0 2020-06-10 12:52:24 -04:00
Evgeniy
0bf9449ee1 fix(img): use setTimeout fallback on older versions of chrome (#21358) 2020-06-10 12:03:37 -04:00
Brandy Carney
cf3035778c chore(stencil): update to v1.14 (#21458) 2020-06-10 11:36:02 -04:00
Brandy Carney
17375d2325 feat(all): add shadow parts to missing components (#21436) 2020-06-10 09:58:33 -04:00
Stefanos Anagnostou
df408f91f1 feat(fab-button): add close icon font size css variable (#19628)
Co-authored-by: Brandy Carney <brandy@ionic.io>
2020-06-10 09:34:48 -04:00
Liam DeBeasi
e95b481a53 fix(angular): patch FormControl methods to properly sync Ionic form classes (#21429)
Co-authored-by: Mark Levy <MarkChrisLevy@users.noreply.github.com>
2020-06-09 11:54:40 -04:00
Stefanos Anagnostou
698e526b9f feat(fab-button): add closeIcon property (#19626) 2020-06-08 16:46:03 -04:00
Liam DeBeasi
f34d3752e3 feat(all): add support for configuring animations on a per-page basis (#21433) 2020-06-08 15:49:14 -04:00
Matthias Max
c8db0d5eeb fix(router): going back uses correct nav transition (#21301) 2020-06-08 12:23:27 -04:00
Liam DeBeasi
a4f0bdb4c3 fix(modal): set card-style modal height using the --height css variable (#21453) 2020-06-08 10:29:39 -04:00
Liam DeBeasi
187917c746 chore(): exempt bugs and feature requests from stale issues (#21435) 2020-06-05 09:45:27 -04:00
Liam DeBeasi
137c49d70b fix(scroll-assist): improve scroll detection accuracy (#21416) 2020-06-03 10:01:01 -04:00
Alexey Vinogradov
5bf83b80d7 feat(all): add optional generics typings for overlay component methods (#21393) 2020-06-03 09:08:27 -04:00
Niklas Merz
c7e94a1f23 docs(datetime): specify default value for dayShortNames (#21281) 2020-06-02 17:21:38 -04:00
Celilsemi Sam Erkiner
1ed81693f2 feat(alert): add support for custom input attributes (#21365) 2020-06-01 11:18:59 -04:00
Thomas Clark
5f2001c43c fix(reorder-group): revert item to original position when passing false to complete (#21396)
fixes #19128
2020-05-29 14:35:34 -04:00
Brandy Carney
882f8fef07 fix(item): inherit align-items from parent item (#19278)
inherits alignment in inner item, sets item alignment to center

fixes #18703
2020-05-29 11:30:19 -04:00
Adam Bradley
323e15003f chore: internal import updates to improve bundling (#21400)
* chore: internal import updates to improve bundling

- Rename keyboard.ts so it has a good filename after custom element bundling
- Import util fns directly instead of from top level index
- Do not export with *

* chore(angular): bump ng-packagr

Co-authored-by: Mike Hartington <mikehartington@gmail.com>
2020-05-29 10:04:12 -05:00
Haidar Zeineddine
53fc8e37c8 feat(angular): strongly type Ionic lifecycle hooks (#18044)
closes #18043
2020-05-27 16:42:34 -04:00
Alex Currie-Clark
29d208de88 fix(item): input-wrapper now inherits overflow (#21282) 2020-05-27 12:56:11 -04:00
Brandy Carney
5285824da5 feat(select-option): pass class from the option to the interface for individual styling (#21304)
Co-authored-by: Robb Wright <audaxion@gmail.com>
2020-05-27 12:12:01 -04:00
David
2dac12c577 fix(header): large title transition works on older versions of iOS (#21339) 2020-05-27 10:34:01 -04:00
Simon Hänisch
7703da28f8 fix(toast, action-sheet): allow button handler to return Promise<void> (#21259) 2020-05-26 15:27:14 -04:00
Brandy Carney
1ea5ce5839 chore(stencil): update to latest stencil version (#21378)
references ionic-team/ionic-docs#1343
2020-05-26 15:05:36 -04:00
Liam DeBeasi
33be1f061e fix(ios): add haptic drag gesture for action sheet and alert components (#21060) 2020-05-26 11:33:51 -04:00
Manu MA
e53f0241e2 feat(alert): add destructive role to alert buttons (#21269) 2020-05-22 15:32:12 -04:00
Liam DeBeasi
4af54a2fea feat(angular): expose getPlatforms and isPlatform (#21308) 2020-05-22 10:27:03 -04:00
Manu MA
4fd7c0cc5a feat(all): add all autocomplete values to input and searchbar (#21297) 2020-05-22 09:23:44 -04:00
Liam DeBeasi
32906048a4 fix(slides): update Swiper dependency to resolve error when doing SSR (#21350) 2020-05-20 15:54:02 -04:00
Liam DeBeasi
829a0d9be5 feat(angular): expose activatedView (#21302) 2020-05-20 15:24:30 -04:00
Liam DeBeasi
c680705162 chore(): update scripts to use colorette instead of turbocolor (#21349) 2020-05-20 13:33:53 -04:00
Liam DeBeasi
60be68ca6d docs(title): clarify background-color styling with collapsible large title (#21348) 2020-05-20 12:58:24 -04:00
Liam DeBeasi
237748049c fix(textarea): native textarea inherits max/min width and heights (#21333)
Co-authored-by: Stefanos Anagnostou <anagstef@users.noreply.github.com>
2020-05-19 12:38:03 -04:00
Liam DeBeasi
ec4c0fe5bd chore(): revert changes until bot is updated (#21332)
This reverts commit cc780c80b2.
2020-05-18 13:48:39 -04:00
Liam DeBeasi
cc780c80b2 chore(): update bot template to properly close issues (#21330) 2020-05-18 13:40:37 -04:00
Liam DeBeasi
eaf4fb6b2a fix(menu-button): screen readers now properly announce menu button (#21324) 2020-05-18 12:43:02 -04:00
Liam DeBeasi
3937101e5c fix(datetime): ensure year-only values are not affected by timezone when parsing (#21309) 2020-05-15 11:36:01 -04:00
Brandy Carney
16a03d58ec docs(headings): update readme headings to be correct level 2020-05-14 17:26:44 -04:00
Julian Baumann
448dfa0a69 fix(modal): card style modal no longer gets stuck when swiping quickly (#21224) 2020-05-14 11:50:31 -04:00
Liam DeBeasi
39bfaeaa79 merge release-5.1.1
5.1.1
2020-05-13 14:22:45 -04:00
Liam DeBeasi
f954d40453 5.1.1 2020-05-13 14:19:55 -04:00
Brandy Carney
dd4cb706ff fix(input): check for tabindex and pass it properly to native input (#21170)
* fix(input): check for tabindex and pass it properly to native input

references #17515

* style(input): fix lint error

* test(input): update test for more use cases (inside item)

* fix(item): adds delegatesFocus to shadow

* style(input): add comment block on what the code does
2020-05-13 12:18:03 -04:00
Liam DeBeasi
50678c03c9 fix(ios): transition shadow properly sized regardless of footer (#21095) 2020-05-13 12:17:45 -04:00
Brandy Carney
898401a7e0 docs(overlays): add documentation on customization in scoped overlays (#21283)
- improves the documentation on customizing scoped overlays using cssClass and/or CSS variables
- includes a section in the Angular usage with information on where the CSS needs to be styled (globally) in order to work for an overlay
2020-05-13 11:54:11 -04:00
Brandy Carney
687122127c docs(stencil): add stencil usage to components (#21261) 2020-05-12 20:35:48 -04:00
Brandy Carney
703ef5c992 fix(display): remove 1px gap between mutually exclusive breakpoints (#21276)
updates breakpoint max to reduce the max width by 0.02px

closes #20993 closes #20743
2020-05-12 12:02:07 -04:00
Liam DeBeasi
85cc35ee91 fix(segment-button): screen readers now announce selected state properly (#21273) 2020-05-12 11:37:56 -04:00
Liam DeBeasi
7166a290cc fix(all): improve scroll assist reliability for below the fold inputs (#21206) 2020-05-11 15:44:59 -04:00
Liam DeBeasi
1e6f92377a fix(refresher): refresher completes even after switching to a new tab (#21236) 2020-05-11 15:21:26 -04:00
Liam DeBeasi
8e11ecc136 fix(picker): haptics now work properly (#21268) 2020-05-11 15:10:19 -04:00
Liam DeBeasi
1fbdb2255e fix(toggle): screen readers now announce toggle properly (#21168) 2020-05-08 11:59:04 -04:00
Liam DeBeasi
0c13f25bbb fix(header): do not error on collapsable header on devices that do not support IntersectionObserve (#21222) 2020-05-08 11:57:50 -04:00
Liam DeBeasi
9d0dcbbd31 fix(overlays): respect keyboardClose property when opening overlays (#21240) 2020-05-08 11:56:40 -04:00
Liam DeBeasi
f23f1cb37e fix(refresher): correctly select shadow root on older browsers (#21237) 2020-05-08 11:54:57 -04:00
Liam DeBeasi
f334e83a43 fix(md): do not hide page when swipe gesture is cancelled (#21247) 2020-05-08 10:16:42 -04:00
Liam DeBeasi
bb62023a0c fix(all): overlay components no longer display outline when focused (#21226) 2020-05-07 16:33:51 -04:00
Liam DeBeasi
cae389bd12 chore(): remove undocumented back button parts (#21223) 2020-05-07 16:32:18 -04:00
Liam DeBeasi
9308f0329c merge release-5.1.0
5.1.0
2020-04-30 18:25:49 -04:00
Liam DeBeasi
042686c7a4 5.1.0 2020-04-30 17:34:30 -04:00
Ely Lucas
43f9d24824 feat(react): Add IonTabsContext to add some missing element methods, closes #19935 (#21171) 2020-04-30 15:08:23 -06:00
Liam DeBeasi
ae5f1ddff0 feat(app): keyboard open and close events (#18478) 2020-04-30 16:07:44 -04:00
Liam DeBeasi
dea9248763 fix(all): gestures should use a passive listener (#21038) 2020-04-30 16:03:54 -04:00
Liam DeBeasi
eab3373213 fix(router): account for query string when pushing page (#21071) 2020-04-30 16:02:21 -04:00
Liam DeBeasi
bcf0fa17a9 docs(select): direct old controller links to component pages (#21167) 2020-04-30 12:10:08 -04:00
Liam DeBeasi
a261cb1f67 chore(select): make note about interfaceOptions and alert input/buttons clearer (#21166) 2020-04-30 11:12:54 -04:00
Brandy Carney
6bc62e1da5 docs(select): update headings to display properly in the docs (#21159) 2020-04-30 11:10:33 -04:00
Brandy Carney
04ace4c983 feat(toggle): improve customization with css vars and auto-adjust handle width and height (#21050)
- Updates Material Design toggle background & box-shadow to match spec
- Adds the following variables: --handle-box-shadow, --handle-height, --handle-max-height, --handle-transition, --handle-width, --handle-spacing
- Improves customization of toggle by inheriting properties where possible and auto-adjusting the handle height and position based on the width and height of the toggle

Closes #19868, closes #20474
2020-04-29 18:31:34 -04:00
Liam DeBeasi
83dcc7168a fix(refresher): properly calculate content dimensions in native ion-refresher (#21157) 2020-04-29 13:53:01 -04:00
Liam DeBeasi
c53b136dbe fix(all): use proper undefined check when using Haptics plugin (#21156)
fixes #21148
2020-04-29 13:13:28 -04:00
Liam DeBeasi
fc2be8d08b fix(overlays): focus overlay when presented (#20997)
fixes #19882, fixes #17126
2020-04-28 16:43:00 -04:00
Brandy Carney
c54911f451 docs(refresher): update usage to correct ionicons 5 icon (#21141)
closes ionic-team/ionic-docs#1263
2020-04-28 15:34:01 -04:00
Liam DeBeasi
fa9ddc91bc feat(all): add ability to eject from Ionic sanitizer (#20457)
resolves #18277
2020-04-27 16:03:39 -04:00
Liam DeBeasi
578ab93d29 feat(content): add parts support for background, scroll (#20929) 2020-04-27 16:01:39 -04:00
Liam DeBeasi
64144960b0 feat(item): add parts support for detail-icon (#20979) 2020-04-27 15:33:54 -04:00
Liam DeBeasi
3821c0463a feat(): add ability to continue processing hardware back button events (#20613)
fixes #17824
2020-04-27 12:58:37 -04:00
Liam DeBeasi
429edb053b feat(gesture): add option to run inside NgZone for Angular apps (#20685)
fixes #20529
2020-04-27 12:50:44 -04:00
Liam DeBeasi
15203de08b fix(angular): do not navigate to same tab if already active (#21085)
fixes #21074, fixes #19943
2020-04-27 12:19:23 -04:00
Liam DeBeasi
671802f9a2 fix(overlays): prevent accidental clicks when dismissing overlays (#21093)
fixes #21092
2020-04-27 11:33:23 -04:00
Liam DeBeasi
14c226ce75 fix(back-button): screen readers correctly announce the back button text (#21053)
fixes #21043
2020-04-27 11:31:32 -04:00
Liam DeBeasi
66e8e6404d fix(select): account for MutationObserver when performing SSR (#21068)
fixes #21063
2020-04-27 11:29:44 -04:00
Liam DeBeasi
4bd9134473 fix(modal): swipeToClose property is now reactive (#21073)
fixes #21072
2020-04-27 11:27:18 -04:00
EinfachHans
1b11ff7fb9 feat(back-button): add 'backButtonDefaultHref' property to Ionic Config (#20491)
closes #19305

Co-authored-by: Brandy Carney <brandy@ionic.io>
2020-04-27 10:57:43 -04:00
Liam DeBeasi
32ecdd6753 feat(gesture): add support for blurring active inputs on gesture start (#20638)
fixes #20588
2020-04-27 10:52:14 -04:00
Alex Currie-Clark
32ee040e3f fix(textarea): height is set correctly when using autoGrow in modals (#20971)
fixes #18993
2020-04-24 13:54:51 -04:00
Liam DeBeasi
1622d9bb3c feat(textarea): add support for inputmode and enterkeyhint (#21106) 2020-04-24 11:56:10 -04:00
Antoine
a75e8f34d6 fix(datetime): locale inputs are now reactive (#20826)
fixes #20367
2020-04-24 11:29:22 -04:00
Liam DeBeasi
e585a22ac9 chore(): change contributing link text (#21121) 2020-04-23 15:57:18 -04:00
Liam DeBeasi
395d7ec5a3 chore(): add extra lines for ionitron message (#21120) 2020-04-23 15:53:02 -04:00
Liam DeBeasi
71c7284ed5 chore(): update contributing docs, update ionitron bot (#21117) 2020-04-23 15:44:21 -04:00
Liam DeBeasi
0a33a095f1 chore(button): remove unreleased parts support (#21111) 2020-04-23 12:23:48 -04:00
Liam DeBeasi
50bc212d0b feat(menu): add parts support for backdrop, container (#20978) 2020-04-23 12:22:19 -04:00
Liam DeBeasi
76ca475734 feat(datetime): add parts support for placeholder, text (#20930) 2020-04-23 12:20:25 -04:00
Liam DeBeasi
63c75edd21 feat(img): add parts support for image (#20943) 2020-04-23 12:19:52 -04:00
Liam DeBeasi
d4b9151396 feat(checkbox): add parts support for container, mark (#20950) 2020-04-23 12:19:24 -04:00
Liam DeBeasi
228ca2b093 feat(radio): add parts support for container, mark (#20952) 2020-04-23 12:18:58 -04:00
Liam DeBeasi
ba20209604 feat(reorder): add parts support for icon (#20960) 2020-04-23 12:18:32 -04:00
Liam DeBeasi
619f67a00b feat(range): add parts support for bar, bar-active, knob, pin, tick, tick-active (#20961) 2020-04-23 12:18:04 -04:00
Liam DeBeasi
d2b772f19f feat(toggle): add parts support for handle, track (#20962) 2020-04-23 12:17:17 -04:00
Liam DeBeasi
15a603b397 fix(searchbar): screen readers correctly announce the cancel button text (#21049)
fixes #21013
2020-04-23 12:15:54 -04:00
Liam DeBeasi
30a1c89688 feat(select): add parts support for placeholder, icon, text (#21108) 2020-04-23 12:14:21 -04:00
Liam DeBeasi
63d8f6239c fix(loading): screen readers no longer incorrectly announce spinner (#21116)
fixes #21107
2020-04-23 12:07:43 -04:00
Brandy Carney
ae0a98924f chore(api): update api generator to include parts in the public API (#21110) 2020-04-22 15:41:44 -04:00
Liam DeBeasi
e442324753 fix(action-sheet): show correct cancel button background on dark mode (#21084)
fixes #21082
2020-04-22 14:27:18 -04:00
Liam DeBeasi
57b2a6b0cc docs(input): provide info regarding pattern used with date type (#21067)
fixes #21020
2020-04-17 10:09:21 -04:00
Liam DeBeasi
497380743d fix(md): do not display blank screen when using MD page transition and swipe gesture (#21058)
fixes #21056
2020-04-16 13:15:02 -04:00
Liam DeBeasi
6a167172ff chore(): update to swiper 5.3.7 (#21055) 2020-04-16 09:55:12 -04:00
Brandy Carney
fe175380d2 chore(github): remove weekly digest 2020-04-15 16:15:47 -04:00
Liam DeBeasi
e90683a713 feat(searchbar): add support for enterkeyhint (#21036)
fixes #21034
2020-04-15 15:08:43 -04:00
Liam DeBeasi
3efaf43821 feat(input): add support for enterkeyhint (#21035)
fixes #21034
2020-04-15 15:08:12 -04:00
Masanori Onoue
102a842bd2 fix(react): IonTabBar properly extends IonicReactProps (#21009)
fixes #21006
2020-04-10 13:09:06 -04:00
Ramez Atassi
7a21708d24 fix(split-pane): properly show border in rtl mode (#20995)
closes #20994

Co-authored-by: Ramez Atassi <ramez@al-salamah.net>
2020-04-08 15:27:24 -04:00
Liam DeBeasi
8a02b28efe fix(ios): properly animate content when navigating from a tabbed page (#20918)
fixes #20912
2020-04-08 15:16:10 -04:00
Liam DeBeasi
6f13b8c792 perf(all): improve scroll assist responsiveness (#20987)
resolves #20922
2020-04-07 12:19:58 -04:00
EinfachHans
acaa1d9ef7 feat(searchbar): add border-radius css variable (#20662)
fixes #17426
fixes #18247
2020-04-03 13:01:07 -04:00
Liam DeBeasi
5b9840508f feat(animation): add option to clean up old animation stylesheets (#20940)
fixes #20610
2020-04-03 09:28:41 -04:00
Liam DeBeasi
4e28445ecb feat(slides): update to swiper 5 (#20917)
fixes #20033
2020-04-02 16:19:28 -04:00
Liam DeBeasi
e23dec5eb9 fix(ios): account for nested tabs with page transition (#20955)
fixes #20948
2020-04-02 15:03:08 -04:00
Liam DeBeasi
e0f3c09bab chore(): update @stencil/core (#20945)
- also updated @stencil/sass
2020-04-01 17:45:26 -04:00
Mike Hartington
6fac5ff7fc docs(modal): remove navParams usage 2020-04-01 10:13:43 -04:00
Liam DeBeasi
3123a318b6 fix(slides): slides no longer breaks when Angular Ivy enabled (#20899)
fixes #20356
2020-03-31 13:07:25 -04:00
Liam DeBeasi
e5e02d4f88 feat(toast): add white-space variable for toast message (#20729)
fixes #20727
2020-03-30 12:02:46 -04:00
Liam DeBeasi
bd64509bae fix(modal): properly inherit border radius for modals on Safari (#20887)
fixes #20878
2020-03-30 11:56:46 -04:00
Liam DeBeasi
9b534bd43f chore(): generate correct change log (#20888) 2020-03-30 11:53:37 -04:00
Liam DeBeasi
8a161f053f merge release-5.0.7
Release 5.0.7
2020-03-26 11:48:51 -04:00
Liam DeBeasi
af1a6d6d6d 5.0.7 2020-03-26 11:30:32 -04:00
Liam DeBeasi
5816cf52a7 fix(modal): properly target card modal for iPadOS styles (#20884) 2020-03-26 11:19:47 -04:00
Liam DeBeasi
7c5661fcfb fix(modal): properly target card modal for iPadOS styles (#20884) 2020-03-26 11:19:23 -04:00
Liam DeBeasi
2b854ec2cc merge release-5.0.6
Release 5.0.6
2020-03-25 15:26:55 -04:00
Liam DeBeasi
3a269e27b6 merge release-5.0.6
Release 5.0.6
2020-03-25 15:26:00 -04:00
Liam DeBeasi
576da29ac6 5.0.6 2020-03-25 14:57:31 -04:00
Jakob Engelbrecht
6ed1c51321 fix(): only cascade mode from parent Ionic components (#20828)
fixes #20055
2020-03-25 14:39:38 -04:00
Liam DeBeasi
75bae403e9 fix(modal): respect card-style modal spec for iPadOS (#20750)
fixes #20700
2020-03-25 14:39:38 -04:00
Liam DeBeasi
321140ff73 fix(title): large title now inherits global color styling during nav transition (#20862) 2020-03-25 14:39:38 -04:00
Liam DeBeasi
d3d7de121b fix(): scroll assists now recognizes inputs on inner pages and modals (#20864)
fixes #20843
2020-03-25 14:39:38 -04:00
Liam DeBeasi
43fbd9d2f2 chore(): properly export ionic page transition functions (#20860) 2020-03-25 14:39:38 -04:00
Liam DeBeasi
dff3816c04 fix(modal): properly apply border radius on card-style modal (#20852)
fixes #20851
2020-03-25 14:39:38 -04:00
Liam DeBeasi
3bd6b5def2 fix(title): improve reliability of large title ios nav transition (#20861) 2020-03-25 14:38:46 -04:00
Liam DeBeasi
2707289b36 fix(content): apply --offset-top and --offset-bottom values correctly (#20790)
fixes #20735
2020-03-25 14:38:46 -04:00
Brandy Carney
d91e22d820 fix(item-divider): update design to match native iOS (#20854) 2020-03-25 14:38:45 -04:00
Manu MA
5a20f84aa4 refactor(): minor updates for next stencil version (#20787) 2020-03-25 14:38:45 -04:00
Liam DeBeasi
71f118201b fix(modal): properly remove safe area padding on card-modal (#20853)
fixes #20799
2020-03-25 14:38:45 -04:00
Hayden Braxton
8bd5bace73 fix(textarea): properly adjust auto-grow textarea in scrolled content (#19776)
fixes #19193
2020-03-25 14:38:45 -04:00
Hayden Braxton
a3fc77be91 fix(content): set overscroll-behavior based on the scroll direction (#20011)
resolves #20010
2020-03-25 14:38:08 -04:00
Liam DeBeasi
14ac8ae24c chore(): add show-modal in component not in animation (#20833)
resolves #20827
2020-03-25 14:38:08 -04:00
Liam DeBeasi
b1a87c8892 fix(refresher): properly dismiss refresher when completed synchronously (#20815)
fixes #20803
2020-03-25 14:38:08 -04:00
Liam DeBeasi
cdfd50b554 fix(segment): automatically expand width for scrollable segment buttons (#20763)
fixes #20566
2020-03-25 14:37:56 -04:00
Brandy Carney
7bc51911f6 fix(list): show bottom border on last item in a list followed by a list (#20798) 2020-03-25 14:37:50 -04:00
Liam DeBeasi
253cd96164 fix(modal): backdrop and box shadows no longer stack when opening multiple modals (#20801)
fixes #20800
2020-03-25 14:37:44 -04:00
Liam DeBeasi
12932dd202 fix(modal): backdrop is no longer tappable on card-style modal on smaller screens (#20802)
fixes #20783
2020-03-25 14:37:34 -04:00
Liam DeBeasi
f23ac44c9a fix(item-sliding): account for swipe to go back gesture when opening item-options (#20777)
fixes #20773
2020-03-25 14:37:22 -04:00
Brandy Carney
2d5d2515be fix(slides): check that mutation observer is defined for ssr (#20791) 2020-03-25 14:37:16 -04:00
Liam DeBeasi
e24060ecd9 fix(): properly scroll to input with scroll assist (#20742)
fixes #19589
2020-03-25 14:37:10 -04:00
Liam DeBeasi
0514b421ec docs(segment): clarify usage of scrollable segments (#20765)
resolves #20692
2020-03-25 14:37:03 -04:00
Liam DeBeasi
0897c3f9c2 fix(react): expose correct type for CreateAnimation (#20775)
fixes #20771
2020-03-25 14:36:58 -04:00
Liam DeBeasi
f2dbe1ff3b fix(angular): respect animation property for ion-router-outlet (#20767)
fixes #20764
2020-03-25 14:36:47 -04:00
Liam DeBeasi
2ece194a08 fix(angular): export Animation and Gesture related types (#20766) 2020-03-25 14:36:47 -04:00
Simon Hänisch
ab146c96ec fix(segment): scrollable segments only show scrollbar if they overflow (#20760)
fixes #20758
2020-03-25 14:36:24 -04:00
Jakob Engelbrecht
364a0a63da fix(): only cascade mode from parent Ionic components (#20828)
fixes #20055
2020-03-25 14:33:13 -04:00
Liam DeBeasi
ae7fe543fe fix(modal): respect card-style modal spec for iPadOS (#20750)
fixes #20700
2020-03-25 13:36:54 -04:00
Liam DeBeasi
794c3d4e96 fix(title): large title now inherits global color styling during nav transition (#20862) 2020-03-25 12:14:26 -04:00
Liam DeBeasi
e2cba41e32 fix(): scroll assists now recognizes inputs on inner pages and modals (#20864)
fixes #20843
2020-03-25 11:45:56 -04:00
Liam DeBeasi
f340cb64c8 chore(): properly export ionic page transition functions (#20860) 2020-03-25 11:43:02 -04:00
Liam DeBeasi
645578c66b fix(modal): properly apply border radius on card-style modal (#20852)
fixes #20851
2020-03-25 11:10:57 -04:00
Liam DeBeasi
df27793702 fix(title): improve reliability of large title ios nav transition (#20861) 2020-03-24 18:06:17 -04:00
Liam DeBeasi
8680c2e83b fix(content): apply --offset-top and --offset-bottom values correctly (#20790)
fixes #20735
2020-03-24 15:44:56 -04:00
Brandy Carney
8660e61b96 fix(item-divider): update design to match native iOS (#20854) 2020-03-24 12:03:41 -04:00
Manu MA
976e68da5b refactor(): minor updates for next stencil version (#20787) 2020-03-24 11:59:07 -04:00
Liam DeBeasi
7a4ddde5ce fix(modal): properly remove safe area padding on card-modal (#20853)
fixes #20799
2020-03-24 11:53:29 -04:00
Hayden Braxton
2796e9453f fix(textarea): properly adjust auto-grow textarea in scrolled content (#19776)
fixes #19193
2020-03-24 11:48:57 -04:00
Hayden Braxton
c68160ecd3 fix(content): set overscroll-behavior based on the scroll direction (#20011)
resolves #20010
2020-03-23 15:07:08 -04:00
Liam DeBeasi
879b90c3c4 chore(): add show-modal in component not in animation (#20833)
resolves #20827
2020-03-20 12:23:09 -04:00
Liam DeBeasi
dae1ce8526 fix(refresher): properly dismiss refresher when completed synchronously (#20815)
fixes #20803
2020-03-19 09:52:49 -04:00
Liam DeBeasi
f86c82639f fix(segment): automatically expand width for scrollable segment buttons (#20763)
fixes #20566
2020-03-18 16:14:06 -04:00
Brandy Carney
de28bd3b79 fix(list): show bottom border on last item in a list followed by a list (#20798) 2020-03-18 15:43:36 -04:00
Liam DeBeasi
0b134dfebf fix(modal): backdrop and box shadows no longer stack when opening multiple modals (#20801)
fixes #20800
2020-03-18 13:44:11 -04:00
Liam DeBeasi
8b6536098a fix(modal): backdrop is no longer tappable on card-style modal on smaller screens (#20802)
fixes #20783
2020-03-18 13:20:14 -04:00
Walter S
39e6c8f55b feat(angular): support multi-app for ng-add schematic (#20768)
* chore(angular): Add missing argument type information.

* chore(angular): Add missing semicolon.

* fix(angular): Properly detect the Angular project name for multi-app repositories.

* fix(angular): Fix generated angular.json when using ng-add  in multi-app repositories.

* chore(angular): Improve reported warnings when using ng-add with invalid workspace configuration.
2020-03-18 12:46:14 -04:00
Liam DeBeasi
3514dd8362 fix(item-sliding): account for swipe to go back gesture when opening item-options (#20777)
fixes #20773
2020-03-17 11:00:38 -04:00
Brandy Carney
e2df046eff fix(slides): check that mutation observer is defined for ssr (#20791) 2020-03-16 17:36:58 -04:00
Liam DeBeasi
0e91c6c502 fix(): properly scroll to input with scroll assist (#20742)
fixes #19589
2020-03-16 15:38:11 -04:00
Liam DeBeasi
cfc6773cb9 docs(segment): clarify usage of scrollable segments (#20765)
resolves #20692
2020-03-16 09:51:13 -04:00
Liam DeBeasi
2982c95993 fix(react): expose correct type for CreateAnimation (#20775)
fixes #20771
2020-03-13 10:10:38 -04:00
Liam DeBeasi
bfb78abda0 fix(angular): respect animation property for ion-router-outlet (#20767)
fixes #20764
2020-03-12 15:26:24 -04:00
Liam DeBeasi
5049d19917 fix(angular): export Animation and Gesture related types (#20766) 2020-03-12 14:56:36 -04:00
Simon Hänisch
13e4e5b03d fix(segment): scrollable segments only show scrollbar if they overflow (#20760)
fixes #20758
2020-03-12 11:01:42 -04:00
Liam DeBeasi
ac229528eb merge release-5.0.5
Release 5.0.5
2020-03-11 14:30:12 -04:00
Liam DeBeasi
f9f3095eb4 merge release-5.0.5
5.0.5
2020-03-11 14:29:29 -04:00
Liam DeBeasi
572f7b6934 5.0.5 2020-03-11 13:07:09 -04:00
Simon Hänisch
4d34ce6a31 fix(label): text overflow for slotted headings (#20690)
fixes #17087
2020-03-11 12:42:46 -04:00
Brandy Carney
d53595eb16 fix(item): apply proper margin left for slotted icon in RTL (#20684)
fixes #20653
2020-03-11 11:52:01 -04:00
Adam Bradley
a1bf2f5b8f chore(ionicons): bump ionicons version (#20704) 2020-03-11 11:36:04 -04:00
Brandy Carney
7ecde36f9d fix(button): allow overflow to be overridden by the CSS variable (#20738)
fixes #20726
2020-03-11 11:35:26 -04:00
Liam DeBeasi
87a27216d0 fix(header): collapsible header now works when navigating quickly (#20728)
fixes #20725
2020-03-11 10:58:26 -04:00
Liam DeBeasi
f6c3ba7e5a fix(header): collapsable header should default to using content background (#20736)
fixes #20691
2020-03-11 10:52:33 -04:00
Liam DeBeasi
f796074f33 chore(): set @nguniversal/builders dependency to exact version (#20734) 2020-03-10 11:22:36 -04:00
Liam DeBeasi
7d260b96a7 fix(modal): swipeable modal now works in firefox (#20714)
fixes #20706
2020-03-06 13:19:48 -05:00
Liam DeBeasi
22d5256810 fix(modal): leave animation transitions modal completely out of viewport on ipad (#20702)
fixes #20697
2020-03-06 10:12:21 -05:00
Liam DeBeasi
b6c2a77deb fix(overlays): prevent accidental dismiss of overlays when tapping screen twice (#20683)
fixes #20608
2020-03-06 10:11:20 -05:00
Liam DeBeasi
ec4878ac08 fix(ios): large title animation now works properly in a modal (#20703)
fixes #20696
2020-03-06 10:09:39 -05:00
Liam DeBeasi
314dbb1a4d fix(segment): allow routerLink to work on segment buttons (#20682)
fixes #20678
2020-03-05 12:38:51 -05:00
Liam DeBeasi
44993b7987 fix(segment): iOS mode segment now works on older Android devices (#20673)
fixes #20648
2020-03-05 11:56:54 -05:00
Mike Hartington
f64b1420ae fix(): exclude components from ssr (#20674) 2020-03-02 14:46:03 -05:00
Ni Tianzhen
21774612d8 fix(datetime): max property now works when hour, minute, or second set to 0 (#20665)
fixes #20652
2020-03-02 11:23:43 -05:00
Brandy Carney
a360ea6d19 merge release-5.0.4 2020-02-27 18:05:03 -05:00
Brandy Carney
36f98eda1b merge release-5.0.4 2020-02-27 18:04:44 -05:00
Brandy Carney
b11ae5da67 5.0.4 2020-02-27 17:32:17 -05:00
Mike Hartington
dff1ffd124 chore(): bump stencil version 2020-02-27 17:09:55 -05:00
Brandy Carney
c1d7bf229d fix(buttons): use proper button colors based on CSS variables when inside of a toolbar (#20633) 2020-02-27 16:22:39 -05:00
Liam DeBeasi
0e0e401d86 fix(animation): reset all temporary flags when interrupting an animation (#20627)
fixes #20602
2020-02-27 11:17:43 -05:00
Beeno Tung
b84822e674 docs(readme): update npm version on CDN example to latest (#20599) 2020-02-26 19:56:29 -05:00
Liam DeBeasi
8e71317de4 merge release-5.0.3
5.0.3
2020-02-26 18:52:13 -05:00
Liam DeBeasi
5a87a728e1 5.0.3 2020-02-26 16:00:07 -05:00
Liam DeBeasi
fe8d74d08c fix(menu): allow ssr to work properly with hardware back button updates (#20629) 2020-02-26 15:54:50 -05:00
Liam DeBeasi
11d8c14d72 merge release-5.0.2
5.0.2
2020-02-26 13:39:08 -05:00
Liam DeBeasi
686325e0ec 5.0.2 2020-02-26 12:21:05 -05:00
Brandy Carney
926ac3fb47 fix(select): add icon-inner & placeholder part (#20605)
- adds custom test for styling the select parts
- set opacity on icon container
- align items center, this makes the select text align vertically with the icon when used standalone even when changing the font size of the text
2020-02-26 12:08:03 -05:00
Brandy Carney
20af652a1b fix(slides): set height to 100% for vertical slides (#20603)
fixes #17341
2020-02-26 12:06:37 -05:00
Elvis Graholskis
e3e5c69681 fix(refresher): ensure that translate is cleaned up to avoid stacking context (#20621)
fixes #17949
2020-02-26 11:56:10 -05:00
Liam DeBeasi
fcf97465f5 docs(segment-button): update usage for v5 (#20612) 2020-02-25 10:30:04 -05:00
Liam DeBeasi
b5310effe3 fix(modal): card style modal now adds appropriate contrast (#20604) 2020-02-24 15:30:56 -05:00
Liam DeBeasi
0224bed0c9 fix(segment): segment functions properly on android 5 (#20554)
fixes #20466
2020-02-24 13:41:49 -05:00
Brandy Carney
cefb08fe32 chore(release): update to latest octokit and usage (#20601)
- rename all references of `tag` to either `gitTag` or `npmTag` based on what they contain since this was confusing throughout
- add the code to publish to git as a prerelease if the npm tag is `next`
- log the version when asking if the npm tag is correct
2020-02-24 11:46:09 -05:00
Liam DeBeasi
71875417f2 fix(ios): large title transition works properly in tabbed applications (#20555)
fixes #20482
2020-02-24 11:38:50 -05:00
Liam DeBeasi
6b2a929cd7 fix(menu): hardware back button now dismisses side menu if open (#20558)
fixes #20559
2020-02-24 11:37:51 -05:00
Liam DeBeasi
8d3ce8d29c fix(modal): allow swipe to close animation to be overridden (#20585)
fixes #20577
2020-02-24 11:22:07 -05:00
Liam DeBeasi
3a2d82814b fix(modal): swipeable modal styles only apply to ios (#20571)
fixes #20569
2020-02-24 11:14:43 -05:00
Liam DeBeasi
ad6fac83cb fix(modal): swipeable modal background should be able to be overridden (#20584)
fixes #20572
2020-02-21 10:05:31 -05:00
Ely Lucas
714ecaae65 docs(react): updating icon usages 2020-02-20 16:08:23 -07:00
Ely Lucas
972e361bdc docs(react): updating react input usages with binding examples (#20557) 2020-02-19 17:49:53 -07:00
Liam DeBeasi
fa9b78e775 merge release-5.0.1
5.0.1
2020-02-19 13:55:15 -05:00
Liam DeBeasi
a826b6dff5 5.0.1 2020-02-19 13:19:39 -05:00
Brandy Carney
34f8576b95 fix(tab-bar): update ios icon and label design to match native (#20548) 2020-02-19 11:32:45 -05:00
Brandy Carney
59fa340650 fix(button): reduce font size of icon only button in toolbar on iOS (#20547) 2020-02-19 11:31:42 -05:00
Liam DeBeasi
06b828b4ff fix(segment): inner div no longer interferes with click events (#20522)
fixes #20381
2020-02-19 09:40:10 -05:00
Liam DeBeasi
3252c2f8dc fix(menu): swipe gesture should not open menu when a modal is displayed (#20546)
fixes #20467
2020-02-19 08:57:42 -05:00
Niklas Merz
800a9339bc docs(item-sliding): fix link to list (#20519) 2020-02-18 15:37:32 -05:00
Liam DeBeasi
dd32a5e278 fix(ios): clamp out of bounds values for swipe to go back (#20540)
fixes #20505
2020-02-18 15:14:30 -05:00
Brandy Carney
ce41d90715 docs(breaking): rename segment events heading to remove conflict with main events 2020-02-18 15:13:52 -05:00
Liam DeBeasi
4d50064764 fix(segment): only emit ionChange when user releases pointer from screen (#20495)
fixes #20500
fixes #20257
2020-02-18 15:11:28 -05:00
Liam DeBeasi
7a461c59c5 fix(segment): do not show ripple effect if disabled via config (#20542)
fixes #20533
2020-02-18 14:02:34 -05:00
Liam DeBeasi
9b5854d797 fix(segment): border radius applies to indicator on ios (#20541)
fixes #20539
2020-02-18 13:58:25 -05:00
Brandy Carney
e42c85d641 fix(fab): show close icon on hover, focused, activated (#20497)
also fixes the fab so users don't have to set color for each state
2020-02-18 13:55:31 -05:00
Ely Lucas
45d03baf98 fix(react): update paths of tab buttons when href changes in ion buttons, fixes #20321 (#20480) 2020-02-14 13:36:30 -07:00
Ely Lucas
82670fe4d0 fix(react): icons with MD set should work in browser (#20463) 2020-02-14 13:36:30 -07:00
Ely Lucas
c0aadd6007 fix(react): Do a better job matching up route to sync, fixes #20363 (#20446) 2020-02-14 13:36:30 -07:00
Ely Lucas
b6fbe98812 fix(react): dont remove pages when navigating between tabs, fixes #20398 (#20431) 2020-02-14 13:36:30 -07:00
Brandy Carney
27a219874c docs(grid): update usage from attributes to classes (#20492)
closes ionic-team/ionic-docs#1230
2020-02-14 12:45:46 -05:00
Liam DeBeasi
c4fb31403e fix(fab): add close icon to internal icons for react (#20490)
fixes #20489
2020-02-14 10:21:14 -05:00
Liam DeBeasi
89bf08b627 fix(input): do not clear input if "Enter" key pressed (#20462)
fixes #20442
2020-02-14 09:27:05 -05:00
Liam DeBeasi
abf594aa61 fix(modal): presenting multiple card-style modals now adds border radius properly (#20476)
fixes #20475
2020-02-13 15:57:30 -05:00
Liam DeBeasi
86ab77a6e2 fix(modal): prevent card style modal styles from being overridden (#20470)
fixes #20469
2020-02-13 10:12:28 -05:00
Brandy Carney
c16de96633 fix(card): inherit background in inner button (#20461)
fixes #20458
2020-02-12 16:25:27 -05:00
Liam DeBeasi
4d6e15ab18 fix(searchbar): properly align placeholder (#20460)
fixes #20456
2020-02-12 16:21:08 -05:00
Brandy Carney
f61b671844 docs(changelog): remove save-exact flag 2020-02-12 15:39:34 -05:00
Liam DeBeasi
99d6069ecb docs(): remove mention of controllers (#20444)
resolves #20453
2020-02-12 09:55:58 -05:00
Brandy Carney
e3364f283f merge release-5.0.0 2020-02-11 12:31:15 -05:00
Brandy Carney
054223b79c merge release-5.0.0 2020-02-11 12:30:24 -05:00
Brandy Carney
6bfdaeed86 5.0.0 2020-02-11 11:42:30 -05:00
Liam DeBeasi
0b182a9c66 merge release-5.0.0-rc.5
5.0.0-rc.5
2020-02-11 11:05:26 -05:00
Brandy Carney
d21b5df523 chore(scripts): include v4-lts as a choice tag for release 2020-02-11 10:53:19 -05:00
Liam DeBeasi
0daca31f38 5.0.0-rc.5 2020-02-11 09:26:30 -05:00
hiepxanh
fd9c7a9601 fix(schematic): correct path for angular project (#20436)
fixes #20435
2020-02-11 09:04:07 -05:00
Liam DeBeasi
61f0faccdb merge release-5.0.0-rc.4 2020-02-10 18:41:06 -05:00
Liam DeBeasi
f303acc99a 5.0.0-rc.4 2020-02-10 16:29:34 -05:00
Liam DeBeasi
3d6f287d87 fix(label): remove subpixel font-size to prevent visual glitches (#20415)
resolves #20407
2020-02-10 09:11:12 -05:00
Ely Lucas
3403574f31 chore(react): update to ionicons v5 final (#20414) 2020-02-07 12:16:23 -07:00
Liam DeBeasi
a6764c4724 fix(item): remove unneeded box-shadow CSS variable (#20412)
resolves #20392
2020-02-07 13:35:21 -05:00
Liam DeBeasi
aa663b76cc chore(datetime): run build (#20411) 2020-02-07 12:27:01 -05:00
Brandy Carney
e8886e98f1 fix(segment): add activated class directly to segment button (#20400)
this gets around a bug with Safari where the ::slotted css selector was not working properly
2020-02-07 12:13:09 -05:00
Liam DeBeasi
fd1b44a40b fix(content): only emit scroll events if enabled (#20401) 2020-02-07 11:53:11 -05:00
Brandy Carney
916f6670a0 chore(ionicons): update to official 5.0.0 release (#20399) 2020-02-06 16:38:29 -05:00
Liam DeBeasi
11d39457d5 fix(header): backdrop filter no longer distorts content with collapsible header (#20388)
fixes #20385
2020-02-06 09:41:25 -05:00
Liam DeBeasi
cfcdd97cc0 merge release-5.0.0-rc.3 (#20387) 2020-02-05 14:28:06 -05:00
Liam DeBeasi
cf7091625e fix(refresher): translate background content when refreshing (#20378)
resolves #20377
2020-02-05 12:17:53 -05:00
Liam DeBeasi
8983c7006e fix(refresher): ensure gesture does not interfere with item-sliding (#20380)
resolves #20379
2020-02-05 12:17:23 -05:00
Liam DeBeasi
46d43032ec chore(): update breaking docs for segment event (#20384) 2020-02-05 09:05:37 -05:00
Liam DeBeasi
4971499026 fix(toolbar): properly apply safe area and border (#20375)
fixes #20354
2020-02-04 12:58:44 -05:00
Brandy Carney
a25007f54f docs(react): update class usage to className (#20366) 2020-02-04 11:16:44 -05:00
Brandy Carney
0f31624104 fix(segment): allow background to be set on iOS segment in a toolbar (#20350) 2020-01-31 15:48:55 -05:00
Brandy Carney
023ed07f97 chore(themes): update commented out default colors in themes 2020-01-31 13:37:19 -05:00
Brandy Carney
43d00415a5 docs(breaking): remove references to removed global css vars (#20348) 2020-01-30 18:20:35 -05:00
Liam DeBeasi
8c4905f630 merge release-5.0.0-rc.2 2020-01-30 15:51:55 -05:00
Liam DeBeasi
ff78e6e8ca fix(radio): do not clear value of radio group from radio (#20343)
fixes #20323
2020-01-30 12:29:11 -05:00
Brandy Carney
d693ca81f5 docs(select): separate react usage by headings (#20335)
closes ionic-team/ionic-docs#1095
2020-01-29 17:52:37 -05:00
Liam DeBeasi
215d55f1eb fix(header): fix race condition in collapsible header (#20334) 2020-01-29 15:45:55 -05:00
Liam DeBeasi
fd55427991 fix(refresher): add correct fallbacks for native refreshers (#20333) 2020-01-29 15:36:09 -05:00
Liam DeBeasi
e580b88477 fix(ios): translucent toolbar blur no longer obscures entering page title (#20314)
fixes #19158
2020-01-29 15:12:00 -05:00
Brandy Carney
1e2946e0f9 docs(ripple-effect): update usage to avoid style conflicts with Ionic components (#20331)
closes ionic-team/ionic-docs#1154
2020-01-29 14:24:45 -05:00
Brandy Carney
6b2f6618f6 docs(loading): update usage to fix code errors (#20330)
closes ionic-team/ionic-docs#1200
2020-01-29 14:24:22 -05:00
Liam DeBeasi
eb57723785 fix(radio): set default radio value if undefined (#20329) 2020-01-29 14:01:27 -05:00
Brandy Carney
7877ea03fe docs(content): add information on fixed slots (#20324)
closes ionic-team/ionic-docs#731
2020-01-29 10:40:33 -05:00
Brandy Carney
ae4e28969f docs(breaking): copyediting 2020-01-28 15:59:53 -05:00
Liam DeBeasi
59d86873a2 fix(refresher): resolve undefined issues when updating component (#20322)
fixes #20320
2020-01-28 14:59:58 -05:00
Brandy Carney
f1e3e42f75 merge release-5.0.0-rc.1 2020-01-27 17:59:29 -05:00
Brandy Carney
940925ef63 5.0.0-rc.1 2020-01-27 17:40:49 -05:00
Liam DeBeasi
eabe05e503 chore(dependencies): update ionicons (#20315) 2020-01-27 17:11:31 -05:00
Brandy Carney
628db18a97 fix(components): fix issues with button states (#20278)
- Update action sheet colors to match spec (md)
- Remove activated background on buttons (md - uses ripple)
- Update Segment Button to use proper indicator color when inside of a toolbar
- Add back input highlight on focus

fixes #20276
2020-01-27 16:47:02 -05:00
Brandy Carney
23ce7c787c docs(grid): update usage to correct CSS utility classes (#20312)
resolves #20302
2020-01-27 14:23:22 -05:00
Brandy Carney
da6263a044 docs(vue): update usage examples to kebab-case (#20313)
references #20296
2020-01-27 14:22:42 -05:00
Liam DeBeasi
09bef71ccd fix(content): resolve height inheritance issues (#20309)
fixes #20305
2020-01-27 13:00:10 -05:00
Liam DeBeasi
00340885fb fix(react): export proper types of animations and gestures (#20311) 2020-01-27 12:38:18 -05:00
Liam DeBeasi
44211c11ee fix(refresher): update animation for dashed property values (#20310) 2020-01-27 12:21:26 -05:00
Brandy Carney
52f713ce79 docs(changelog): update to include link to details about dev console 2020-01-27 11:40:14 -05:00
Brandy Carney
33186ba716 fix(picker): include showBackdrop in interface (#20301)
fixes #18893
2020-01-27 11:20:32 -05:00
Brandy Carney
767b005eac fix(components): inherit text indent in all components with text inherit (#20300)
fixes #17786
2020-01-27 11:18:59 -05:00
Brandy Carney
7b44ae2a40 fix(toast): inherit color in cancel button for a toast with color (#20299)
fixes #20139
2020-01-27 11:16:23 -05:00
Liam DeBeasi
915f7f488b merge release-4.11.10 2020-01-27 11:05:17 -05:00
Liam DeBeasi
a0fc21deee chore(): update breaking changes doc for ion-radio (#20307) 2020-01-27 10:51:53 -05:00
Brandy Carney
1c2d64873e docs(list-header): update list header API changes and usage (#20289)
closes #20284
2020-01-24 16:06:54 -05:00
Liam DeBeasi
b14471178e fix(menu): fix jump when dragging open (#20288)
fixes #20286
2020-01-24 15:22:51 -05:00
Walter S
09d951ae1b fix(angular): ng-add schematic (#20281)
* fix(angular): update ng-add schematic to use the project name

* fix(angular): use relative schematics collection.json path.
2020-01-24 13:13:02 -05:00
Masahiko Sakakibara
59d064979f chore(github): update issue template to include v5 (#20232) 2020-01-24 13:11:56 -05:00
Brandy Carney
b966c5e83b merge release-5.0.0-rc.0 2020-01-23 17:54:20 -05:00
Brandy Carney
52cc48cfe8 5.0.0-rc.0 2020-01-23 17:37:56 -05:00
Brandy Carney
b8fdf41737 5.0.0-beta.6 2020-01-23 17:17:56 -05:00
Brandy Carney
94159291b2 feat(components): improve button states and add new css properties (#19440)
Before users had to know the exact opacity that the MD/iOS spec called for in order to change the hover or focused background color. This allows them to change the background without having to know the opacity. 

- changes apply to Action Sheet (Buttons), Back Button, Button, FAB Button, Item, Menu Button, Segment Button, Tab Button
- greatly reduces the requirement by users to set the background hover, focused states for dark modes and custom themes, also eliminates the need to know what the hover opacity is for each based on the spec
- updates the MD dark theme per their spec
- adds a component guide for internal use changing Ionic components

references #18279 fixes #20213 fixes #19965

BREAKING CHANGE:

*Activated Class*

The `activated` class that is automatically added to buttons on press has been renamed to `ion-activated`. This will be more consistent with our `ion-focused` class we add and also will reduce conflicts with user's CSS.

*CSS Variables*

The `--background-hover`, `--background-focused` and `--background-activated` CSS variables on components that render native buttons will now have an opacity automatically set. If you are setting any of these like the following:

```
--background-hover: rgba(44, 44, 44, 0.08);
```

You will likely not see a hover state anymore. It should be updated to only set the desired color:

```
--background-hover: rgba(44, 44, 44);
```

If the opacity desired is something other than what the spec asks for, use:

```
--background-hover: rgba(44, 44, 44);
--background-hover-opacity: 1;
```
2020-01-23 16:57:47 -05:00
Ely Lucas
445f129e2d release-4.11.9 2020-01-23 13:56:20 -07:00
Nikos Douvlis
d76a5031c4 feat(segment-button): add --indicator-height property to segment button (#19653) 2020-01-23 15:55:57 -05:00
Ely Lucas
6e0c745703 4.11.9 2020-01-23 13:16:15 -07:00
Ely Lucas
3a56228290 fix(core): updating type of input value to accept numbers, fixes #20173 (#20267) 2020-01-23 13:10:29 -07:00
Ely Lucas
5d8e0ed703 fix(react): remove leaving view when routerdirection is back, fixes #20124 (#20268) 2020-01-23 13:10:29 -07:00
Ely Lucas
9b2680d40d fix(react): adding missing overlay component events, fixes #19923 (#20266) 2020-01-23 13:10:29 -07:00
Ely Lucas
85be000a4c fix(react): support routes without a path for notfound routes, fixes #20259 (#20261) 2020-01-23 13:10:29 -07:00
Ely Lucas
f971f76b4b fix(react): update icon types to be a string as well, fixes #20229 (#20230) 2020-01-23 13:10:29 -07:00
Ely Lucas
50dcab5c32 fix(react): re attach props on update, fixes 20192 (#20228) 2020-01-23 13:09:21 -07:00
Ely Lucas
9a8057cdf2 fix(react): Don't render overlay children if isOpen is false, fixes #20225 (#20226) 2020-01-23 13:09:21 -07:00
Liam DeBeasi
b59d7647fd feat(react): add Ionic Animations wrapper (experimental) (#20273) 2020-01-23 14:26:29 -05:00
Schneider Werner Walter
7af0198e2e chore(ngAdd): use project name in builders
Closes #19765
2020-01-23 10:22:11 -05:00
Eduardo Roth
e693169cf0 fix(ngAdd): fix path for css styles in monorepo (#19904)
* feat(ng-add): Fix path for css styles in monorepo

* fix(): Changes proposed by SchnWalter

* chore(): Remove unused var

* chore(): Remove unused var
2020-01-23 10:11:29 -05:00
Liam DeBeasi
e613f63590 fix(content): set min-height to allow for sticky headers(#20265)
fixes #20258
2020-01-22 11:42:24 -05:00
Liam DeBeasi
f896821753 fix(segment): clicking disabled button no longer adds ripple to active button (#20254)
fixes #20253
2020-01-21 16:36:41 -05:00
Liam DeBeasi
443cbd9eb2 fix(modal): card-style modal now opens at full width on larger devices (#20256)
fixes #20255
2020-01-21 15:31:44 -05:00
Liam DeBeasi
32a7401576 fix(animation): add property conversions for CSS Animations (#20252)
fixes #20251
2020-01-21 12:28:41 -05:00
Liam DeBeasi
34bfc62820 merge release-5.0.0-beta.5
5.0.0-beta.5
2020-01-17 19:20:24 -05:00
Liam DeBeasi
3024a216ec 5.0.0-beta.5 2020-01-17 17:55:15 -05:00
Manu MA
a5229d90ca refactor(): remove checked property in favor of parent value (#19449)
BREAKING CHANGE:


The following components have been updated to remove the checked or selected properties:

- Radio
- Segment Button
- Select

Developers should set the value property on the respective parent components in order to managed checked/selected status.

Co-authored-by: Liam DeBeasi <liamdebeasi@users.noreply.github.com>
2020-01-17 17:22:26 -05:00
Brandy Carney
9232f16eea fix(card): remove top padding of content in iOS if under header (#20223) 2020-01-17 15:10:19 -05:00
Liam DeBeasi
dbccf8dd77 docs(title): update button example with large title (#20222)
fixes #20217
2020-01-17 10:04:37 -05:00
Ely Lucas
dc78f98153 fix(react): updating icon type and add caret to internal icons (#20216) 2020-01-16 09:49:32 -07:00
Brandy Carney
ad96c462a6 docs(breaking): update ionicons to link to its own changelog 2020-01-15 15:59:11 -05:00
Ely Lucas
28aa5eed94 chore(react): updating types for location state to fix type errors (#20207) 2020-01-14 12:49:58 -07:00
Liam DeBeasi
8732a10757 refactor(): remove deprecated controllers (#20165)
* remove action-sheet-controller and alert-controller

* rmeove loading controller

* remove popover controller

* remove toast controller

* remove picker-controller

* remove modal controller

* remove menu controller

* update menu ctrl in tests

* run linter

* remove window refs

* Update core/src/components/loading/test/standalone/index.html

Co-Authored-By: Brandy Carney <brandyscarney@users.noreply.github.com>

* remove window from modal tests

* test

* testing timeout

* change timeout

Co-authored-by: Brandy Carney <brandyscarney@users.noreply.github.com>
2020-01-14 12:09:35 -05:00
Liam DeBeasi
5b0400d5af fix(modal): prevent double dismiss via gesture and backdrop tap on card-style modal (#20203)
* fix double dismiss via backdrop tap

* add back deleted line

* fix whitespace
2020-01-14 12:08:32 -05:00
Brandy Carney
dc66ce48e1 feat(segment): implement iOS 13 segment with animation (#19036)
Changes
Closes #18663

* Converts Segment to shadow
* Enables gesture to swipe between segment buttons
* Adds indicator transition to slide the indicator between buttons
* Updates global theme variables
* Removes activated state, now handled by the gesture
* Updates iOS to latest iOS 13 UI
* Ensures customization is working for the buttons and indicator
* Updates the e2e tests
2020-01-14 11:51:28 -05:00
Liam DeBeasi
8e11f79fcc fix(header): header opacity properly resets on collapsible titles (#20202) 2020-01-14 11:40:35 -05:00
Liam DeBeasi
9d63b41a52 fix(content): scroll-content div now takes up full height of container (#20194)
fixes #20185
2020-01-13 16:09:19 -05:00
Ely Lucas
88fa670bc9 release-4.11.8 2020-01-13 10:28:18 -07:00
Ely Lucas
a1c5a06812 4.11.8 2020-01-13 10:15:08 -07:00
Ely Lucas
57eec1cb0a fix(react): add missing react memory router 2020-01-13 10:12:07 -07:00
Ely Lucas
d294e67f52 fix(react): supporting ios and md props on icons (#20170) 2020-01-13 10:12:07 -07:00
Ely Lucas
f8773a4e04 chore(docs): updating ActionSheet React sample 2020-01-13 10:12:07 -07:00
Ely Lucas
432887b410 fix(react): fixing type of icon in ToastOptions, ActionSheetOptions, fixes #20100 2020-01-13 10:12:07 -07:00
Liam DeBeasi
4bc3dc73c1 fix(menu): clamp out of bounds swipe value (#19684)
fixes #18927
2020-01-13 10:09:28 -07:00
Ely Lucas
f290025d73 chore(): bumping timeout 2020-01-13 10:06:39 -07:00
Brandy Carney
6fc1612f42 docs(breaking): add breaking changes for v5 (#20156) 2020-01-13 11:29:29 -05:00
Rajat Soni
14eda3c2ba docs(): fix broken grid layout link (#20188) 2020-01-13 09:04:55 -05:00
Asif Rahman
7b032c5e9b feat(datetime): add custom timezone display property (#19519)
resolves #19401
2020-01-09 15:29:40 -05:00
Andreas Greimel
39d12629db fix(picker): pick correct option at low velocities (#19660)
fixes #19659
2020-01-09 13:35:01 -05:00
Mike Hartington
cf287fda7f fix(modal): card-style modal offset now matches the iOS spec (#20166)
* chore(core): better animations
Updates animations to be closer to native

* Add css alternative

Co-authored-by: Liam DeBeasi <liamdebeasi@users.noreply.github.com>
2020-01-09 10:57:45 -05:00
Adam Bradley
3aa47e6e2f fix(ssr): reflect content-id attribute (#20169)
Co-authored-by: Brandy Carney <brandyscarney@users.noreply.github.com>
2020-01-08 21:36:30 -06:00
Liam DeBeasi
53fad978c5 fix(action-sheet): allow scrollable action-sheet with many options (#20145)
fixes #17311
2020-01-08 13:29:44 -05:00
Liam DeBeasi
3b4988aa60 feat(toast): expose shadow parts (#20146)
resolves #19722
2020-01-06 15:53:26 -05:00
Brandy Carney
808b1bd461 merge release-5.0.0-beta.4
Release 5.0.0 beta.4
2020-01-06 13:08:35 -05:00
Brandy Carney
dae5c5d28c 5.0.0-beta.4 2020-01-06 12:04:40 -05:00
Brandy Carney
fc35dd3efe chore(scripts): update angular versions in dist directly 2020-01-06 11:38:17 -05:00
Liam DeBeasi
5b81bdfcf1 feat(refresher): add MD native refresher (#20096)
resolves #17316
2020-01-06 11:38:17 -05:00
Brandy Carney
a5ba0c81b6 5.0.0-beta.3 2020-01-03 17:19:45 -05:00
Brandy Carney
0feace4f89 chore(scripts): update main and dist package files for angular 2020-01-03 16:58:29 -05:00
Liam DeBeasi
814ec765b9 feat(refresher): add MD native refresher (#20096)
resolves #17316
2020-01-03 14:56:26 -05:00
Brandy Carney
cb94d8d978 chore(scripts): comment out tests for release, remove core update 2020-01-03 14:31:25 -05:00
Brandy Carney
c48d96f4ea chore(scripts): include files to verify dist build for angular packages 2020-01-03 14:28:26 -05:00
Brandy Carney
9c78759ab9 chore(stencil): update to latest 2020-01-03 14:25:07 -05:00
Liam DeBeasi
a01c10267e feat(radio): add --border-radius and --inner-border-radius variables (#20140) 2020-01-03 13:14:39 -05:00
Alex Arvanitidis
c32a7bcd20 feat(checkbox): add --checkmark-width variable (#19933)
resolves #16803

Co-authored-by: Liam DeBeasi <liamdebeasi@users.noreply.github.com>
2020-01-03 12:20:04 -05:00
Brandy Carney
9318d2418e fix(icons): fix the ellipsis fill in ionicons (#20137)
- update docs icon usage for Ionicons 5
- update tests to remove mode prefixed icons
- update tests to use the correct icons for Ionicons 5
- update to latest ionicons dev which fixes the ellipsis icon fill
2020-01-03 12:19:17 -05:00
Liam DeBeasi
02a46a1007 feat(toggle): add --border-radius and --handle-border-radius variables (#20141) 2020-01-03 12:14:02 -05:00
Brandy Carney
83f77e2972 chore(release): update release script to pass proper path 2020-01-02 16:02:47 -05:00
Mike Hartington
2344d0b272 feat(angular): angular 9 support (#19515)
* init ivy support

* chore(): angular prerelease

* chore: update

* updates

* angular 8 deps

* chore(angular): update sync script

* updates

* chore(): remove console log

* chore(): updates

* chore(): update release script

* fix(): remove comments

* fix(): remove test version

* fix(): failing angular test

* fix(): failing angular tests

* fix(): update ci steps

* fix(): fix sync script

* chore(): refactor angular proxies

* chore(): updates

* chore(): updates

* chore(): lint

* chore(): updates

* chore(ssr): check for window

* chore(): fix virtual scroll angular tests

* chore(): lint

* chore(): add server to link

* chore(scripts): update release script

* chore(): bump version check

* style(scripts): spacing
2019-12-18 18:43:59 -05:00
David Boho
49c394c3d3 fix(animation): support css animation on older devices (#20020)
fixes #20017
2019-12-18 13:19:07 -05:00
Liam DeBeasi
04e7c03132 feat(refresher): add iOS native refresher (#20037)
fixes #18664
2019-12-18 10:52:58 -05:00
Antoine
6d6aba6d40 docs(item): add button property to items with click handler (#20049) 2019-12-16 13:47:17 -05:00
Liam DeBeasi
6612604733 refactor(searchbar): set inputmode default to undefined (#20080)
fixes #20074

BREAKING CHANGE: The `inputmode` property for `ion-searchbar` now defaults to `undefined`. To get the old behavior, set the `inputmode` property to `"search"`.
2019-12-16 12:16:54 -05:00
Liam DeBeasi
1cabb53650 fix(modal): account for safe area on devices with a notch (#20072)
* fix card modal on notch phones

* only apply safe area for card modal

* fix styles, fix gesture race condition

* a few more tweaks
2019-12-16 12:09:34 -05:00
Brandy Carney
9d1fe2e14f test(select): remove debuggers 2019-12-16 11:52:28 -05:00
Ely Lucas
1c344beda1 merge release-4.11.7 2019-12-12 16:07:06 -07:00
Ely Lucas
98bd2f85ae 4.11.7 2019-12-12 15:53:26 -07:00
Ely Lucas
2dcf3ee7b5 fix(react): fire lifecycle events on initial render, fixes #20071 2019-12-12 15:50:52 -07:00
Liam DeBeasi
2e8cc8ebc5 merge release-5.0.0-beta.2
5.0.0-beta.2
2019-12-12 10:05:17 -05:00
Liam DeBeasi
12ac987058 5.0.0-beta.2 2019-12-11 15:23:44 -05:00
Ely Lucas
41f8aa68ca merge release-4.11.6 2019-12-11 10:07:10 -07:00
Ely Lucas
323073ec96 chore(core): removing old test 2019-12-11 09:51:03 -07:00
Ely Lucas
e7a835bd46 4.11.6 2019-12-11 09:33:28 -07:00
Ely Lucas
4d226b05c6 fix(react): support for 'root' router direction, fixes #19982 (#20052) 2019-12-11 09:30:16 -07:00
Ely Lucas
43712db1be fix(react): first render performance improvements 2019-12-11 09:30:16 -07:00
Ely Lucas
b8517781b1 fix(react): don't show back button when not appropriate 2019-12-11 09:30:16 -07:00
Ely Lucas
693ae21096 fix(react): support navigating to same page and route updates in IonRouterOutlet, fixes #19891, #19892, #19986 2019-12-11 09:30:15 -07:00
Ely Lucas
ab0f92e01f fix(react): fix refs for controllers, overlays, ionpage, and ionrouteroutlet, fixes #19924 (#20012) 2019-12-11 09:30:15 -07:00
Ely Lucas
93bd4afb1d chore(react): fix tabs docs (#19995) 2019-12-11 09:30:15 -07:00
Liam DeBeasi
aaf9d24afd fix(menu): clamp out of bounds swipe value (#19684)
fixes #18927
2019-12-11 09:27:02 -07:00
James Manners
4c8f32fae9 fix(tabs): preserve route navigation extras when changing tabs (#18493)
fixes #18717
2019-12-11 10:46:13 -05:00
Manu MA
b3b3312711 feat(modal): add card-style presentation with swipe to close gesture (#19428)
resolves #18660
2019-12-10 16:02:41 -05:00
Liam DeBeasi
56f67bd9a5 fix(animations): convert hyphenated properties to camel case when using Web Animations (#20059)
fixes #20058
2019-12-10 15:28:44 -05:00
Liam DeBeasi
6e0b9c4548 fix(picker): pass selected value to handler on dismiss (#20042)
fixes #20036
2019-12-05 11:14:39 -05:00
Liam DeBeasi
656c356343 chore(animations): remove deprecated methods (#20041) 2019-12-05 09:29:38 -05:00
William Reiske
66e6dfbe44 docs(progress-bar): fix typo (#20009) 2019-12-04 14:43:20 -05:00
Liam DeBeasi
300d54356d fix(title): large title nav transition adds correct safe area value (#20029)
fixes #20028
2019-12-02 12:37:33 -05:00
Adam Bradley
d8161bc129 chore(ionicons): update ionicons to 5.0.0-13 (#19968) 2019-11-22 10:21:41 -05:00
Liam DeBeasi
e76619478c fix(animation): properly update Web Animation, clean up types (#19964)
Co-authored-by: manucorporat <manu.mtza@gmail.com>
2019-11-21 11:08:27 -05:00
Liam DeBeasi
7734d27bc2 docs(title): update large title docs to mention translucent and fullscreen requirements (#19956)
fixes #19483
2019-11-20 15:34:54 -05:00
Liam DeBeasi
a33cb957f6 merge release-5.0.0-beta.1
5.0.0-beta.1
2019-11-20 13:06:31 -05:00
Liam DeBeasi
6b932d9980 5.0.0-beta.1 2019-11-20 11:39:51 -05:00
Adam Bradley
69e10de718 refactor(ionicons): update to ionicons v5 (#19670)
* refactor(ionicons): update to ionicons v5

* refactor(back-button): update back button icon to v5 ionicons

* refactor(item): update default detail icon to chevron-forward

* refactor(reorder): update reorder icon for ionicons v5

* refactor(searchbar): use search-sharp

* refactor(searchIcon): update v5 ionicon

* refactor(clearIcon): update searchbar clear icon

* refactor(cancelButton): update to arrow-back-sharp

* refactor(menuIcon): update to v5 ionicons

* api readme updates

* update react and vue ionicons

* add ionicons to react deps

* add ionicons to ionic/vue deps

* add icon to react test

* updates

* fix back button regression for no icon

* update tests

* fix more tests

* fix more icons

* update ionicons version

* fix circle icons

* add correct ellipsis
2019-11-20 09:53:32 -05:00
Brandy Carney
5bbb95fae1 feat(list-header): redesign list header for iOS spec (#19915) 2019-11-19 14:53:37 -05:00
Matthew Harris
abdaaf320b test(app): use cancel role in toast not close (#19944) 2019-11-19 10:37:03 -05:00
Matthew Harris
d521f65053 docs(css): update directive references to classes in css utils (#19941) 2019-11-18 18:08:40 -05:00
Matthew Harris
9e9f72a87f docs(): fix occurred typo (#19916)
* docs(searchbar): typo ocurred / occurred

* docs(textarea): occurred typo

* docs(input): occurred typo

* docs(regenerate): occurred typo fix
2019-11-18 09:20:21 -05:00
Liam DeBeasi
fc4bb2db5c fix(header): support collapsible header with multiple toolbars (#19909)
* begin fix collapsible title with multi toolbars

* fix back button

* adjust large title positioning

* a few adjustments

* remove whitespace

* add types

* fix type
2019-11-18 08:57:56 -05:00
Liam DeBeasi
3298fddc09 merge release-4.11.5
Sync 4.11.5
2019-11-14 15:57:20 -05:00
Liam DeBeasi
28b4221b19 4.11.5 2019-11-14 15:24:17 -05:00
Ely Lucas
790eb6e15e fix(react): improving lifecycle hooks to deal with stale closures, fixes #19873 (#19874) 2019-11-14 15:22:17 -05:00
Adam Bradley
0d40d3f3b7 refactor(back-button): convert to shadow component (#19411)
references #18899
2019-11-14 14:39:35 -05:00
Stefanos Anagnostou
b793214fe1 docs(virtual-scroll): update virtualTrackBy header (#19508) 2019-11-14 12:23:55 -05:00
Liam DeBeasi
407db752a0 chore(angular): update Config deprecation message (#19908)
* update deprecation msg

* add exact release
2019-11-14 11:30:25 -05:00
David
768e3ae2cf fix(item): handle multiple inputs inside ion-item correctly (#18348)
fixes #15850
2019-11-13 17:28:15 -05:00
841 changed files with 44087 additions and 18253 deletions

View File

@@ -310,9 +310,6 @@ jobs:
- run:
command: npm install
working_directory: /tmp/workspace/angular/test/test-app
- run:
command: npm run sync
working_directory: /tmp/workspace/angular/test/test-app
- run:
command: npm test
working_directory: /tmp/workspace/angular/test/test-app

443
.github/COMPONENT-GUIDE.md vendored Normal file
View File

@@ -0,0 +1,443 @@
# Ionic Component Implementation Guide
- [Button States](#button-states)
* [Component Structure](#component-structure)
* [Activated](#activated)
* [Disabled](#disabled)
* [Focused](#focused)
* [Hover](#hover)
* [Ripple Effect](#ripple-effect)
* [Example Components](#example-components)
* [References](#references)
- [Rendering Anchor or Button](#rendering-anchor-or-button)
* [Example Components](#example-components-1)
* [Component Structure](#component-structure-1)
- [Converting Scoped to Shadow](#converting-scoped-to-shadow)
## Button States
Any component that renders a button should have the following states: [`activated`](#activated), [`disabled`](#disabled), [`focused`](#focused), [`hover`](#hover). It should also have a [Ripple Effect](#ripple-effect) component added for Material Design.
### Component Structure
#### JavaScript
A component that renders a native button should use the following structure:
```jsx
<Host>
<button class="button-native">
<span class="button-inner">
<slot></slot>
</span>
</button>
</Host>
```
Any other attributes and classes that are included are irrelevant to the button states, but it's important that this structure is followed and the classes above exist. In some cases they may be named something else that makes more sense, such as in item.
#### CSS
A mixin called `button-state()` has been added to make it easier to setup the states in each component.
```scss
@mixin button-state() {
@include position(0, 0, 0, 0);
position: absolute;
content: "";
opacity: 0;
}
```
The following styles should be set for the CSS to work properly. Note that the `button-state()` mixin is included in the `::after` pseudo element of the native button.
```scss
.button-native {
/**
* All other CSS in this selector is irrelevant to button states
* but the following are required styles
*/
position: relative;
overflow: hidden;
}
.button-native::after {
@include button-state();
}
.button-inner {
/**
* All other CSS in this selector is irrelevant to button states
* but the following are required styles
*/
position: relative;
z-index: 1;
}
```
### Activated
The activated state should be enabled for elements with actions on "press". It usually changes the opacity or background of an element.
> Make sure the component has the correct [component structure](#component-structure) before continuing.
#### JavaScript
The `ion-activatable` class needs to be set on an element that can be activated:
```jsx
render() {
return (
<Host class='ion-activatable'>
<slot></slot>
</Host>
);
}
```
Once that is done, the element will get the `ion-activated` class added on press.
In addition to setting that class, `ion-activatable-instant` can be set in order to have an instant press with no delay:
```jsx
<Host class='ion-activatable ion-activatable-instant'>
```
#### CSS
```css
/**
* @prop --color-activated: Color of the button when pressed
* @prop --background-activated: Background of the button when pressed
* @prop --background-activated-opacity: Opacity of the background when pressed
*/
```
Style the `ion-activated` class based on the spec for that element:
```scss
:host(.ion-activated) .button-native {
color: var(--color-activated);
&::after {
background: var(--background-activated);
opacity: var(--background-activated-opacity);
}
}
```
> Order is important! Activated should be before the focused & hover states.
#### User Customization
Setting the activated state on the `::after` pseudo-element allows the user to customize the activated state without knowing what the default opacity is set at. A user can customize in the following ways to have a solid red background on press, or they can leave out `--background-activated-opacity` and the button will use the default activated opacity to match the spec.
```css
ion-button {
--background-activated: red;
--background-activated-opacity: 1;
}
```
### Disabled
The disabled state should be set via prop on all components that render a native button. Setting a disabled state will change the opacity or color of the button and remove click events from firing.
#### JavaScript
The `disabled` property should be set on the component:
```jsx
/**
* If `true`, the user cannot interact with the button.
*/
@Prop({ reflectToAttr: true }) disabled = false;
```
Then, the render function should add the [`aria-disabled`](https://www.w3.org/WAI/PF/aria/states_and_properties#aria-disabled) role to the host, a class that is the element tag name followed by `disabled`, and pass the `disabled` attribute to the native button:
```jsx
render() {
const { disabled } = this;
return (
<Host
aria-disabled={disabled ? 'true' : null}
class={{
'button-disabled': disabled
}}
>
<button disabled={disabled}>
<slot></slot>
</button>
</Host>
);
}
```
> Note: if the class being added was for `ion-back-button` it would be `back-button-disabled`.
#### CSS
The following CSS _at the bare minimum_ should be added for the disabled class, but it should be styled to match the spec:
```css
:host(.button-disabled) {
cursor: default;
opacity: .5;
pointer-events: none;
}
```
#### User Customization
TODO
### Focused
The focused state should be enabled for elements with actions when tabbed to via the keyboard. This will only work inside of an `ion-app`. It usually changes the opacity or background of an element.
> Make sure the component has the correct [component structure](#component-structure) before continuing.
#### JavaScript
The `ion-focusable` class needs to be set on an element that can be focused:
```jsx
render() {
return (
<Host class='ion-focusable'>
<slot></slot>
</Host>
);
}
```
Once that is done, the element will get the `ion-focused` class added when the element is tabbed to.
#### CSS
Components should be written to include the following focused variables for styling:
```css
/**
* @prop --color-focused: Color of the button when tabbed to with the keyboard
* @prop --background-focused: Background of the button when tabbed to with the keyboard
* @prop --background-focused-opacity: Opacity of the background when tabbed to with the keyboard
*/
```
Style the `ion-focused` class based on the spec for that element:
```scss
:host(.ion-focused) .button-native {
color: var(--color-focused);
&::after {
background: var(--background-focused);
opacity: var(--background-focused-opacity);
}
}
```
> Order is important! Focused should be after the activated and before the hover state.
#### User Customization
Setting the focused state on the `::after` pseudo-element allows the user to customize the focused state without knowing what the default opacity is set at. A user can customize in the following ways to have a solid red background on focus, or they can leave out `--background-focused-opacity` and the button will use the default focus opacity to match the spec.
```css
ion-button {
--background-focused: red;
--background-focused-opacity: 1;
}
```
### Hover
The [hover state](https://developer.mozilla.org/en-US/docs/Web/CSS/:hover) happens when a user moves their cursor on top of an element without pressing on it. It should not happen on mobile, only on desktop devices that support hover.
> Make sure the component has the correct [component structure](#component-structure) before continuing.
#### CSS
Components should be written to include the following hover variables for styling:
```css
/**
* @prop --color-hover: Color of the button on hover
* @prop --background-hover: Background of the button on hover
* @prop --background-hover-opacity: Opacity of the background on hover
*/
```
Style the `:hover` based on the spec for that element:
```scss
@media (any-hover: hover) {
:host(:hover) .button-native {
color: var(--color-hover);
&::after {
background: var(--background-hover);
opacity: var(--background-hover-opacity);
}
}
}
```
> Order is important! Hover should be after the activated and focused states.
#### User Customization
Setting the hover state on the `::after` pseudo-element allows the user to customize the hover state without knowing what the default opacity is set at. A user can customize in the following ways to have a solid red background on hover, or they can leave out `--background-hover-opacity` and the button will use the default hover opacity to match the spec.
```css
ion-button {
--background-hover: red;
--background-hover-opacity: 1;
}
```
### Ripple Effect
The ripple effect should be added to elements for Material Design. It *requires* the `ion-activatable` class to be set on the parent element to work, and relative positioning on the parent.
```jsx
render() {
const mode = getIonMode(this);
return (
<Host
class={{
'ion-activatable': true,
}}
>
<button>
<slot></slot>
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
</button>
</Host>
);
```
The ripple effect can also accept a different `type`. By default it is `"bounded"` which will expand the ripple effect from the click position outwards. To add a ripple effect that always starts in the center of the element and expands in a circle, set the type to `"unbounded"`. An unbounded ripple will exceed the container, so add `overflow: hidden` to the parent to prevent this.
Make sure to style the ripple effect for that component to accept a color:
```css
ion-ripple-effect {
color: var(--ripple-color);
}
```
### Example Components
- [ion-button](https://github.com/ionic-team/ionic/tree/master/core/src/components/button)
- [ion-back-button](https://github.com/ionic-team/ionic/tree/master/core/src/components/back-button)
- [ion-menu-button](https://github.com/ionic-team/ionic/tree/master/core/src/components/menu-button)
### References
- [Material Design States](https://material.io/design/interaction/states.html)
- [iOS Buttons](https://developer.apple.com/design/human-interface-guidelines/ios/controls/buttons/)
## Rendering Anchor or Button
Certain components can render an `<a>` or a `<button>` depending on the presence of an `href` attribute.
### Example Components
- [ion-button](https://github.com/ionic-team/ionic/tree/master/core/src/components/button)
- [ion-card](https://github.com/ionic-team/ionic/tree/master/core/src/components/card)
- [ion-fab-button](https://github.com/ionic-team/ionic/tree/master/core/src/components/fab-button)
- [ion-item-option](https://github.com/ionic-team/ionic/tree/master/core/src/components/item-option)
- [ion-item](https://github.com/ionic-team/ionic/tree/master/core/src/components/item)
### Component Structure
#### JavaScript
In order to implement a component with a dynamic tag type, set the property that it uses to switch between them, we use `href`:
```jsx
/**
* Contains a URL or a URL fragment that the hyperlink points to.
* If this property is set, an anchor tag will be rendered.
*/
@Prop() href: string | undefined;
```
Then use that in order to render the tag:
```jsx
render() {
const TagType = href === undefined ? 'button' : 'a' as any;
return (
<Host>
<TagType>
<slot></slot>
</TagType>
</Host>
);
}
```
If the component can render an `<a>`, `<button>` or a `<div>` add in more properties such as a `button` attribute in order to check if it should render a button.
## Converting Scoped to Shadow
### CSS
There will be some CSS issues when converting to shadow. Below are some of the differences.
**Targeting host + slotted child**
```css
/* IN SCOPED */
:host(.ion-color)::slotted(ion-segment-button)
/* IN SHADOW*/
:host(.ion-color) ::slotted(ion-segment-button)
```
**Targeting host-context + host (with a :not)**
```css
/* IN SCOPED */
:host-context(ion-toolbar.ion-color):not(.ion-color) {
/* IN SHADOW */
:host-context(ion-toolbar.ion-color):host(:not(.ion-color)) {
```
**Targeting host-context + host (with a :not) > slotted child**
```css
/* IN SCOPED */
:host-context(ion-toolbar:not(.ion-color)):not(.ion-color)::slotted(ion-segment-button) {
/* IN SHADOW*/
:host-context(ion-toolbar:not(.ion-color)):host(:not(.ion-color)) ::slotted(ion-segment-button) {
```

View File

@@ -4,6 +4,7 @@ Thanks for your interest in contributing to the Ionic Framework! :tada:
- [Contributing Etiquette](#contributing-etiquette)
- [Creating an Issue](#creating-an-issue)
* [Creating a Good Code Reproduction](#creating-a-good-code-reproduction)
- [Creating a Pull Request](#creating-a-pull-request)
* [Setup](#setup)
* [Core](#core)
@@ -40,13 +41,40 @@ Please see our [Contributor Code of Conduct](https://github.com/ionic-team/ionic
* The issue list of this repository is exclusively for bug reports and feature requests. Non-conforming issues will be closed immediately.
* Issues with no clear steps to reproduce will not be triaged. If an issue is labeled with "needs: reply" and receives no further replies from the author of the issue for more than 30 days, it will be closed.
* Issues with no clear steps to reproduce will not be triaged. If an issue is labeled with "needs: reply" and receives no further replies from the author of the issue for more than 14 days, it will be closed.
* If you think you have found a bug, or have a new feature idea, please start by making sure it hasn't already been [reported](https://github.com/ionic-team/ionic/issues?utf8=%E2%9C%93&q=is%3Aissue). You can search through existing issues to see if there is a similar one reported. Include closed issues as it may have been closed with a solution.
* Next, [create a new issue](https://github.com/ionic-team/ionic/issues/new/choose) that thoroughly explains the problem. Please fill out the populated issue form before submitting the issue.
## Creating a Good Code Reproduction
### What is a Code Reproduction?
A code reproduction is a small application that is built to demonstrate a particular issue. The code reproduction should contain the minimum amount of code needed to recreate the issue and should focus on a single issue.
### Why Should You Create a Reproduction?
A code reproduction of the issue you are experiencing helps us better isolate the cause of the problem. This is an important first step to getting any bug fixed!
Without a reliable code reproduction, it is unlikely we will be able to resolve the issue, leading to it being closed. In other words, creating a code reproduction of the issue helps us help you.
### How to Create a Reproduction
* Create a new Ionic application using one of our starter templates. The `blank` starter application is a great choice for this. You can create one using the following Ionic CLI command: `ionic start myApp blank`
* Add the minimum amount of code needed to recreate the issue you are experiencing. Do not include anything that is not required to reproduce the issue. This includes any 3rd party plugins you have installed.
* Publish the application on GitHub and include a link to it when [creating an issue](#creating-an-issue).
* Be sure to include steps to reproduce the issue. These steps should be clear and easy to follow.
### Benefits of Creating a Reproduction
* **Uses the latest version of Ionic:** By creating a new Ionic application, you are ensuring that you are testing against the latest version of the framework. Sometimes the issues you are experiencing have already been resolved in a newer version of the framework!
* **Minimal surface area:** By removing code that is not needed in order to reproduce the issue, it makes it easier to identify the cause of the issue.
* **No secret code needed:** Creating a minimal reproduction of the issue prevents you from having to publish any proprietary code used in your project.
* **Get help fixing the issue:** If we can reliably reproduce an issue, there is a good chance we will be able to address it.
## Creating a Pull Request
* We appreciate you taking the time to contribute! Before submitting a pull request, we ask that you please [create an issue](#creating-an-issue) that explains the bug or feature request and let us know that you plan on creating a pull request for it. If an issue already exists, please comment on that issue letting us know you would like to submit a pull request for it. This helps us to keep track of the pull request and make sure there isn't duplicated effort.

View File

@@ -10,6 +10,7 @@
<!-- (For Ionic 1.x issues, please use https://github.com/ionic-team/ionic-v1) -->
<!-- (For Ionic 2.x & 3.x issues, please use https://github.com/ionic-team/ionic-v3) -->
[x] **4.x**
[ ] **5.x**
**I'm submitting a ...**
<!-- (check one with "x") -->

View File

@@ -21,6 +21,16 @@ comment:
Thank you!
- label: "ionitron: needs reproduction"
message: >
Thanks for the issue! This issue has been labeled as `needs reproduction`. This label
is added to issues that need a code reproduction.
Please provide a reproduction with the minimum amount of code required to reproduce the issue. Without a reliable code reproduction, it is unlikely we will be able to resolve the issue, leading to it being closed.
For a guide on how to create a good reproduction, see our [Contributing Guide](https://ionicframework.com/docs/contributing/how-to-contribute#creating-a-good-code-reproduction).
dryRun: false
closeAndLock:
@@ -65,8 +75,10 @@ stale:
days: 365
maxIssuesPerRun: 100
exemptLabels:
- good first issue
- triage
- "good first issue"
- "triage"
- "type: bug"
- "type: feature request"
exemptAssigned: true
exemptProjects: true
exemptMilestones: true
@@ -83,7 +95,7 @@ stale:
dryRun: false
noReply:
days: 30
days: 14
maxIssuesPerRun: 100
label: "needs: reply"
responseLabel: triage
@@ -95,6 +107,24 @@ noReply:
template is fully filled out.
Thank you for using Ionic!
close: true
lock: true
dryRun: false
noReproduction:
days: 14
maxIssuesPerRun: 100
label: "ionitron: needs reproduction"
responseLabel: triage
exemptProjects: true
exemptMilestones: true
message: >
Thanks for the issue! This issue is being closed due to the lack of a code reproduction. 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

View File

@@ -1,7 +0,0 @@
# Configuration for weekly-digest - https://github.com/apps/weekly-digest
publishDay: wed
canPublishIssues: true
canPublishPullRequests: true
canPublishContributors: true
canPublishStargazers: true
canPublishCommits: true

View File

@@ -4,7 +4,7 @@ const execa = require('execa');
const inquirer = require('inquirer');
const Listr = require('listr');
const semver = require('semver');
const tc = require('turbocolor');
const { bold, cyan, dim } = require('colorette');
const rootDir = path.join(__dirname, '../');
@@ -13,7 +13,8 @@ const packages = [
'docs',
'angular',
'packages/react',
'packages/react-router'
'packages/react-router',
'packages/angular-server'
];
function readPkg(project) {
@@ -35,13 +36,13 @@ function projectPath(project) {
return path.join(rootDir, project);
}
async function askTag() {
async function askNpmTag(version) {
const prompts = [
{
type: 'list',
name: 'tag',
name: 'npmTag',
message: 'Select npm tag or specify a new tag',
choices: ['latest', 'next']
choices: ['latest', 'next', 'v4-lts']
.concat([
new inquirer.Separator(),
{
@@ -54,13 +55,13 @@ async function askTag() {
type: 'confirm',
name: 'confirm',
message: answers => {
return `Will publish to ${tc.cyan(answers.tag)}. Continue?`;
return `Will publish ${cyan(version)} to ${cyan(answers.npmTag)}. Continue?`;
}
}
];
const { tag, confirm } = await inquirer.prompt(prompts);
return { tag, confirm };
const { npmTag, confirm } = await inquirer.prompt(prompts);
return { npmTag, confirm };
}
function checkGit(tasks) {
@@ -151,21 +152,26 @@ function preparePackage(tasks, package, version, install) {
}
}
// Lint, Test, Bump Core dependency
if (version) {
projectTasks.push({
title: `${pkg.name}: lint`,
task: () => execa('npm', ['run', 'lint'], { cwd: projectRoot })
});
projectTasks.push({
title: `${pkg.name}: test`,
task: async () => await execa('npm', ['test'], { cwd: projectRoot })
});
// TODO will not work due to https://github.com/ionic-team/ionic/issues/20136
// projectTasks.push({
// title: `${pkg.name}: test`,
// task: async () => await execa('npm', ['test'], { cwd: projectRoot })
// });
}
// Build
projectTasks.push({
title: `${pkg.name}: build`,
task: () => execa('npm', ['run', 'build'], { cwd: projectRoot })
});
// Link core or react for sub projects
if (package === 'core' || package === 'packages/react') {
projectTasks.push({
title: `${pkg.name}: npm link`,
@@ -186,7 +192,7 @@ function preparePackage(tasks, package, version, install) {
// Add project tasks
tasks.push({
title: `Prepare ${tc.bold(pkg.name)}`,
title: `Prepare ${bold(pkg.name)}`,
task: () => new Listr(projectTasks)
});
}
@@ -228,7 +234,7 @@ function prepareDevPackage(tasks, package, version) {
// Add project tasks
tasks.push({
title: `Prepare dev build: ${tc.bold(pkg.name)}`,
title: `Prepare dev build: ${bold(pkg.name)}`,
task: () => new Listr(projectTasks)
});
}
@@ -238,7 +244,7 @@ function updatePackageVersions(tasks, packages, version) {
updatePackageVersion(tasks, package, version);
tasks.push({
title: `${package} update @ionic/core dependency, if present ${tc.dim(`(${version})`)}`,
title: `${package} update @ionic/core dependency, if present ${dim(`(${version})`)}`,
task: async () => {
if (package !== 'core') {
const pkg = readPkg(package);
@@ -247,9 +253,26 @@ function updatePackageVersions(tasks, packages, version) {
}
}
});
// angular & angular-server need to update their dist versions
if (package === 'angular' || package === 'packages/angular-server') {
const distPackage = path.join(package, 'dist');
updatePackageVersion(tasks, distPackage, version);
tasks.push({
title: `${package} update @ionic/core dependency, if present ${dim(`(${version})`)}`,
task: async () => {
const pkg = readPkg(distPackage);
updateDependency(pkg, '@ionic/core', version);
writePkg(distPackage, pkg);
}
});
}
if (package === 'packages/react-router') {
tasks.push({
title: `${package} update @ionic/react dependency, if present ${tc.dim(`(${version})`)}`,
title: `${package} update @ionic/react dependency, if present ${dim(`(${version})`)}`,
task: async () => {
const pkg = readPkg(package);
updateDependency(pkg, '@ionic/react', version);
@@ -264,14 +287,30 @@ function updatePackageVersion(tasks, package, version) {
const projectRoot = projectPath(package);
tasks.push({
title: `${package}: update package.json ${tc.dim(`(${version})`)}`,
title: `${package}: update package.json ${dim(`(${version})`)}`,
task: async () => {
await execa('npm', ['version', version], { cwd: projectRoot });
}
});
}
function publishPackages(tasks, packages, version, tag = 'latest') {
function copyPackageToDist(tasks, packages) {
packages.forEach(package => {
const projectRoot = projectPath(package);
// angular and angular-server are the only packages that publish dist
if (package !== 'angular' && package !== 'packages/angular-server') {
return;
}
tasks.push({
title: `${package}: Copy package.json to dist`,
task: () => execa('node', ['copy-package.js', package], { cwd: path.join(rootDir, '.scripts') })
});
});
}
function publishPackages(tasks, packages, version, npmTag = 'latest') {
// first verify version
packages.forEach(package => {
if (package === 'core') {
@@ -290,14 +329,18 @@ function publishPackages(tasks, packages, version, tag = 'latest') {
});
});
// next publish
// Publish
packages.forEach(package => {
const projectRoot = projectPath(package);
let projectRoot = projectPath(package);
if (package === 'packages/angular-server' || package === 'angular') {
projectRoot = path.join(projectRoot, 'dist')
}
tasks.push({
title: `${package}: publish to ${tag} tag`,
title: `${package}: publish to ${npmTag} tag`,
task: async () => {
await execa('npm', ['publish', '--tag', tag], { cwd: projectRoot });
await execa('npm', ['publish', '--tag', npmTag], { cwd: projectRoot });
}
});
});
@@ -332,10 +375,11 @@ function copyCDNLoader(tasks, version) {
module.exports = {
checkTestDist,
checkGit,
askTag,
askNpmTag,
isValidVersion,
isVersionGreater,
copyCDNLoader,
copyPackageToDist,
packages,
packagePath,
prepareDevPackage,

View File

@@ -2,7 +2,7 @@
* Deploy script adopted from https://github.com/sindresorhus/np
* MIT License (c) Sindre Sorhus (sindresorhus.com)
*/
const tc = require('turbocolor');
const { cyan, dim, red, reset } = require('colorette');
const execa = require('execa');
const inquirer = require('inquirer');
const Listr = require('listr');
@@ -34,7 +34,7 @@ async function main() {
console.log(` npm run release\n`);
} catch(err) {
console.log('\n', tc.red(err), '\n');
console.log('\n', red(err), '\n');
process.exit(1);
}
}
@@ -84,7 +84,7 @@ async function askVersion() {
type: 'confirm',
name: 'confirm',
message: answers => {
return `Will bump from ${tc.cyan(oldVersion)} to ${tc.cyan(answers.version)}. Continue?`;
return `Will bump from ${cyan(oldVersion)} to ${cyan(answers.version)}. Continue?`;
}
}
];
@@ -131,7 +131,7 @@ async function preparePackages(packages, version, install) {
function validateGit(tasks, version) {
tasks.push(
{
title: `Validate git tag ${tc.dim(`(v${version})`)}`,
title: `Validate git tag ${dim(`(v${version})`)}`,
task: () => execa('git', ['fetch'])
.then(() => {
return execa.stdout('npm', ['config', 'get', 'tag-version-prefix']);
@@ -198,17 +198,17 @@ function prettyVersionDiff(oldVersion, inc) {
for (let i = 0; i < newVersion.length; i++) {
if ((newVersion[i] !== oldVersion[i] && !firstVersionChange)) {
output.push(`${tc.dim.cyan(newVersion[i])}`);
output.push(`${dim(cyan(newVersion[i]))}`);
firstVersionChange = true;
} else if (newVersion[i].indexOf('-') >= 1) {
let preVersion = [];
preVersion = newVersion[i].split('-');
output.push(`${tc.dim.cyan(`${preVersion[0]}-${preVersion[1]}`)}`);
output.push(`${dim(cyan(`${preVersion[0]}-${preVersion[1]}`))}`);
} else {
output.push(tc.reset.dim(newVersion[i]));
output.push(reset(dim(newVersion[i])));
}
}
return output.join(tc.reset.dim('.'));
return output.join(reset(dim('.')));
}
main();

View File

@@ -1,4 +1,4 @@
const tc = require('turbocolor');
const { cyan, red } = require('colorette');
const semver = require('semver');
const execa = require('execa');
const inquirer = require('inquirer');
@@ -47,7 +47,7 @@ async function main() {
console.log(`\nionic ${devVersion} published!! 🎉\n`);
} catch (err) {
console.log('\n', tc.red(err), '\n');
console.log('\n', red(err), '\n');
process.exit(1);
}
@@ -64,7 +64,7 @@ async function askDevVersion(devVersion) {
name: 'confirm',
value: true,
message: () => {
return `Publish the dev build ${tc.cyan(devVersion)}?`;
return `Publish the dev build ${cyan(devVersion)}?`;
}
}
];

View File

@@ -2,11 +2,11 @@
* Deploy script adopted from https://github.com/sindresorhus/np
* MIT License (c) Sindre Sorhus (sindresorhus.com)
*/
const tc = require('turbocolor');
const { cyan, dim, green, red, yellow } = require('colorette');
const execa = require('execa');
const Listr = require('listr');
const path = require('path');
const octokit = require('@octokit/rest')()
const { Octokit } = require('@octokit/rest');
const common = require('./common');
const fs = require('fs-extra');
@@ -28,7 +28,7 @@ async function main() {
// repo must be clean
common.checkGit(tasks);
const { tag, confirm } = await common.askTag();
const { npmTag, confirm } = await common.askNpmTag(version);
if (!confirm) {
return;
@@ -36,10 +36,10 @@ async function main() {
if(!dryRun) {
// publish each package in NPM
common.publishPackages(tasks, common.packages, version, tag);
common.publishPackages(tasks, common.packages, version, npmTag);
// push tag to git remote
publishGit(tasks, version, changelog);
publishGit(tasks, version, changelog, npmTag);
}
const listr = new Listr(tasks);
@@ -48,14 +48,14 @@ async function main() {
// Dry run doesn't publish to npm or git
if (dryRun) {
console.log(`
\n${tc.yellow('Did not publish. Remove the "--dry-run" flag to publish:')}\n${tc.green(version)} to ${tc.cyan(tag)}\n
\n${yellow('Did not publish. Remove the "--dry-run" flag to publish:')}\n${green(version)} to ${cyan(npmTag)}\n
`);
} else {
console.log(`\nionic ${version} published to ${tag}!! 🎉\n`);
console.log(`\nionic ${version} published to ${npmTag}!! 🎉\n`);
}
} catch (err) {
console.log('\n', tc.red(err), '\n');
console.log('\n', red(err), '\n');
process.exit(1);
}
}
@@ -70,13 +70,13 @@ function checkProductionRelease() {
}
}
function publishGit(tasks, version, changelog) {
const tag = `v${version}`;
function publishGit(tasks, version, changelog, npmTag) {
const gitTag = `v${version}`;
tasks.push(
{
title: `Tag latest commit ${tc.dim(`(${tag})`)}`,
task: () => execa('git', ['tag', `${tag}`], { cwd: common.rootDir })
title: `Tag latest commit ${dim(`(${gitTag})`)}`,
task: () => execa('git', ['tag', `${gitTag}`], { cwd: common.rootDir })
},
{
title: 'Push branches to remote',
@@ -88,7 +88,7 @@ function publishGit(tasks, version, changelog) {
},
{
title: 'Publish Github release',
task: () => publishGithub(version, tag, changelog)
task: () => publishGithub(version, gitTag, changelog, npmTag)
}
);
}
@@ -100,7 +100,7 @@ function findChangelog() {
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (line.startsWith('# [')) {
if (line.startsWith('## [') || line.startsWith('# [')) {
if (start === -1) {
start = i + 1;
} else {
@@ -116,10 +116,12 @@ function findChangelog() {
return lines.slice(start, end).join('\n').trim();
}
async function publishGithub(version, tag, changelog) {
octokit.authenticate({
type: 'oauth',
token: process.env.GH_TOKEN
async function publishGithub(version, gitTag, changelog, npmTag) {
// If the npm tag is next then publish as a prerelease
const prerelease = npmTag === 'next' ? true : false;
const octokit = new Octokit({
auth: process.env.GH_TOKEN
});
let branch = await execa.stdout('git', ['symbolic-ref', '--short', 'HEAD']);
@@ -132,9 +134,10 @@ async function publishGithub(version, tag, changelog) {
owner: 'ionic-team',
repo: 'ionic',
target_commitish: branch,
tag_name: tag,
tag_name: gitTag,
name: version,
body: changelog,
prerelease: prerelease
});
}

View File

@@ -11,7 +11,22 @@ const fs = require('fs');
},
// angular
{
files: ['../angular/dist/fesm5.cjs.js']
files: [
'../angular/dist/schematics/collection.json',
'../angular/dist/fesm5/ionic-angular.js',
'../angular/dist/fesm2015/ionic-angular.js',
'../angular/dist/ionic-angular.d.ts',
'../angular/dist/ionic-angular.metadata.json'
]
},
// angular-server
{
files: [
'../packages/angular-server/dist/fesm5/ionic-angular-server.js',
'../packages/angular-server/dist/fesm2015/ionic-angular-server.js',
'../packages/angular-server/dist/ionic-angular-server.d.ts',
'../packages/angular-server/dist/ionic-angular-server.metadata.json'
]
},
// react
{

View File

@@ -1,3 +1,671 @@
# Breaking Changes
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).
This is a comprehensive list of the breaking changes introduced in the major version releases of Ionic Framework.
## Versions
- [Version 5.x](#version-5x)
- [Version 4.x](#version-4x)
- [Legacy](#legacy)
## Version 5.x
- [CSS](#css)
* [CSS Utilities](#css-utilities)
* [Display Classes](#display-classes)
* [Activated, Focused, Hover States](#activated-focused-hover-states)
* [Distributed Sass](#distributed-sass)
- [Components](#components)
* [Action Sheet](#action-sheet)
* [Anchor](#anchor)
* [Back Button](#back-button)
* [Button](#button)
* [Card](#card)
* [Controllers](#controllers)
* [FAB Button](#fab-button)
* [Item](#item)
* [Header / Footer](#header---footer)
* [List Header](#list-header)
* [Menu](#menu)
* [Menu Button](#menu-button)
* [Nav Link](#nav-link)
* [Radio](#radio)
* [Searchbar](#searchbar)
* [Segment](#segment)
* [Segment Button](#segment-button)
* [Select Option](#select-option)
* [Skeleton Text](#skeleton-text)
* [Split Pane](#split-pane)
* [Toast](#toast)
* [Tabs](#tabs)
- [Colors](#colors)
- [Events](#events)
- [Mode](#mode)
- [Ionicons](#ionicons)
### CSS
#### CSS Utilities
We originally added CSS utility attributes for styling components because it was a quick and easy way to wrap text or add padding to an element. Once we added support for multiple frameworks as part of our "Ionic for everyone" approach, we quickly determined there were problems with using CSS attributes with frameworks that use JSX and Typescript. In order to solve this we added CSS classes. Rather than support CSS attributes in certain frameworks and classes in others, we decided to remove the CSS attributes and support what works in all of them, classes, for consistency. In addition to this, changing to classes prefixed with `ion` avoids conflict with native attributes and user's CSS. In the latest version of Ionic 4, there are deprecation warnings printed in the console to show what the new classes are, and the documentation has been updated since support for classes was added to remove all references to attributes: https://ionicframework.com/docs/layout/css-utilities.
Some examples of what's changed are below. *This is not all-inclusive, see the documentation linked above for all of the available CSS utility classes.*
**Before**
```html
<ion-header text-center></ion-header>
<ion-content padding></ion-content>
<ion-label text-wrap></ion-label>
<ion-item wrap></ion-item>
```
**After**
```html
<ion-header class="ion-text-center"></ion-header>
<ion-content class="ion-padding"></ion-content>
<ion-label class="ion-text-wrap"></ion-label>
<ion-item class="ion-wrap"></ion-item>
```
#### Display Classes
The responsive display classes found in the `display.css` file have had their media queries updated to better reflect how they should work. Instead of using the maximum value of the breakpoint for `.ion-hide-{breakpoint}-down` classes it will use the minimum of that breakpoint.
The [Ionic breakpoints](https://ionicframework.com/docs/layout/css-utilities#ionic-breakpoints) are the following:
| Breakpoint Name | Width |
| ----------------| --------|
| xs | 0 |
| sm | 576px |
| md | 768px |
| lg | 992px |
| xl | 1200px |
Previously, if you added the class `ion-hide-md-down` to an element, it would hide the element when the screen size was `991px` (the maximum of the `md` breakpoint) or smaller. Now, using this same class will hide the element when the maximum screen size is `768px`.
Below is a table of how the media queries have changed for each class:
| Class Name | Ionic 4 | Ionic 5 |
| --------------------| -----------------------------| -----------------------------|
| `.ion-hide-down` | `@media (max-width: 575px)` | all screen sizes |
| `.ion-hide-sm-down` | `@media (max-width: 767px)` | `@media (max-width: 576px)` |
| `.ion-hide-md-down` | `@media (max-width: 991px)` | `@media (max-width: 768px)` |
| `.ion-hide-lg-down` | `@media (max-width: 1199px)` | `@media (max-width: 992px)` |
| `.ion-hide-xl-down` | all screen sizes | `@media (max-width: 1200px)` |
_Note that no changes were made to the `.ion-hide-{breakpoint}-up` classes._
See the [CSS Utilities responsive display documentation](https://ionicframework.com/docs/layout/css-utilities#responsive-display-attributes) for more information.
#### Activated, Focused, Hover States
The `.activated` class that is automatically added to clickable components has been renamed to `.ion-activated`.
The way the CSS variables are used for targeting the activated, focused and hover backgrounds have been updated on the following components:
- Action Sheet
- Back Button
- Button
- FAB Button
- Item
- Menu Button
- Segment Button
- Tab Button
Previously, in order to update any of the background colors for the states you would have to know what the opacity was set to. Using the Material Design spec as an example, it would require you to know that the hover state uses a white overlay with an opacity of `.08`. This means that if we had the following set by default:
```css
--background-hover: rgba(255, 255, 255, 0.08);
```
If you wanted to change the hover overlay to use black but still match the spec, you'd have to set it to:
```css
--background-hover: rgba(0, 0, 0, 0.08);
```
The new way adds the following variables:
```css
--background-activated-opacity
--background-focused-opacity
--background-hover-opacity
```
It also updates the Action Sheet component so that the variables will be prefixed with `button`. See the [Action Sheet](#action-sheet) section in this document for all of the new variable names.
This allows you to still have control over the opacity if desired, but when updating the state, you only have to set the main variables: `--background-activated`, `--background-focused`, `--background-hover` and the button will still match the spec. This is most important when changing the global theme, as updating the toolbar color will automatically update the hover states for all of the buttons in a toolbar, regardless of their fill and without having to know what each opacity is.
##### Examples
```css
/* Setting the button background on hover to solid red */
ion-button {
--background-hover: red;
--background-hover-opacity: 1;
}
/* Setting the action sheet button background on focus to an opaque green */
ion-action-sheet {
--button-background-focus: green;
--button-background-focus-opacity: 0.5;
}
/*
* Setting the fab button background on hover to match the text color with
* the default --background-hover-opacity on md
*/
.md ion-fab-button {
--color: #222;
--background-hover: #222;
}
```
##### Global CSS Properties
Some variables were renamed, removed or added. See the chart below for the changes.
| Old variable | Status | New variable |
| ----------------------------------------| --------|-------------------------------------------|
| `--ion-toolbar-color-unchecked` | renamed | `--ion-toolbar-segment-color` |
| `--ion-toolbar-color-checked` | renamed | `--ion-toolbar-segment-color-checked` |
| `--ion-toolbar-background-unchecked` | renamed | `--ion-toolbar-segment-background` |
| `--ion-toolbar-background-checked` | renamed | `--ion-toolbar-segment-background-checked`|
| `--ion-tab-bar-color-activated` | renamed | `--ion-tab-bar-color-selected` |
| | added | `--ion-toolbar-segment-indicator-color` |
| `--ion-toolbar-color-activated` | removed | |
| `--ion-item-background-activated` | removed | |
| `--ion-item-background-focused` | removed | |
| `--ion-item-background-hover` | removed | |
#### Distributed Sass
The `scss` files have been removed from `dist/`. CSS variables should be used to theme instead.
### Components
#### Action Sheet
The following CSS variables have been renamed or added:
| Old | New |
|--------------------------| -------------------------------------------|
| | `--button-background` |
| `--background-activated` | `--button-background-activated` |
| | `--button-background-activated-opacity` |
| `--background-selected` | `--button-background-selected` |
| | `--button-background-focused` |
| | `--button-background-focused-opacity` |
| | `--button-background-hover` |
| | `--button-background-hover-opacity` |
| | `--button-background-selected` |
| | `--button-background-selected-opacity` |
| | `--button-color` |
| | `--button-color-activated` |
| | `--button-color-focused` |
| | `--button-color-hover` |
| | `--button-color-selected` |
See the [Action Sheet CSS Custom Properties](https://ionicframework.com/docs/api/action-sheet#css-custom-properties) documentation for descriptions.
#### Anchor
The `ion-anchor` component has been renamed to `ion-router-link` as this is a better description of which component it should be used with. This component should still only be used in vanilla and Stencil JavaScript projects. Angular projects should use an `<a>` and `routerLink` with the Angular router. See the [documentation for router-link](https://ionicframework.com/docs/api/router-link) for more information.
#### Back Button
- Converted `ion-back-button` to use [shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM).
- [Focused, Hover States](#activated-focused-hover-states) have been updated.
#### Button
- [Activated, Focused, Hover States](#activated-focused-hover-states) have been updated.
#### Card
Converted `ion-card` to use [shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM).
#### Controllers
The controller components (`ion-action-sheet-controller`, `ion-alert-controller`, `ion-loading-controller`, `ion-menu-controller`, `ion-modal-controller`, `ion-picker-controller`, `ion-popover-controller`, `ion-toast-controller`) have been removed from Ionic core as elements. They should be imported from `@ionic/core` instead. This will not affect projects that use Angular or React. Below is an example of the loading controller change in a JavaScript project, but this change applies to all controller elements.
**Before**
```html
<ion-loading-controller></ion-loading-controller>
<script>
async function presentLoading() {
const loadingController = document.querySelector('ion-loading-controller');
const loading = await loadingController.create({
message: 'Hello',
duration: 2000
});
await loading.present();
}
</script>
```
**After**
```html
<script type="module">
import { loadingController } from '@ionic/core';
window.loadingController = loadingController;
</script>
<script>
async function presentLoading() {
const loading = await loadingController.create({
message: 'Hello',
duration: 2000
});
await loading.present();
}
</script>
```
#### FAB Button
- [Activated, Focused, Hover States](#activated-focused-hover-states) have been updated.
#### Item
- [Activated, Focused, Hover States](#activated-focused-hover-states) have been updated.
#### Header / Footer
The `no-border` attribute has been removed, use `ion-no-border` class instead. See [CSS Utilities](#css-utilities) above for more information on why this change was made.
#### List Header
The list header has been redesigned to match the latest iOS spec. This may break the design of your application as the previous design had a small font size with uppercase text. The latest design includes a larger, bolder text.
In addition, any text content inside of an `<ion-list-header>` should be wrapped in an `<ion-label>` in order to get the proper styling of the new design. If the label is missing, the button alignment in the list header may look off.
**Before**
```html
<ion-list-header>
New This Week
<ion-button>See All</ion-button>
</ion-list-header>
```
**After**
```html
<ion-list-header>
<ion-label>New This Week</ion-label>
<ion-button>See All</ion-button>
</ion-list-header>
```
The button has also been updated to default to `fill="clear"` and `size="small"` when inside of a list header. If the old look of the list header or buttons is desired, use custom CSS or button properties to achieve it.
For more information see the [List Header usage](https://ionicframework.com/docs/api/list-header#usage).
#### Menu
- The `swipeEnable()` function has been removed in Angular, use `swipeGesture()` instead.
- The `side` values `left` and `right` have been removed, use `start` and `end` instead.
- Removed the `main` attribute, use `content-id` (for vanilla JS / Vue) and `contentId` (for Angular / React) instead.
**Before**
```html
<ion-menu>...</ion-menu>
<ion-content main>...</ion-content>
```
**After**
```html
<ion-menu content-id="main"></ion-menu>
<ion-content id="main">...</ion-content>
```
- The presentation type in `ios` now defaults to `"overlay"`.
#### Menu Button
- [Focused, Hover States](#activated-focused-hover-states) have been updated.
#### Nav Link
The `ion-nav-push`, `ion-nav-back`, and `ion-nav-set-root` components have been removed in favor of using `ion-nav-link` with a `router-direction` property which accepts `”root”`, `“forward”`, and `“back”`. This reduces the need for maintaining multiple components when they all do the same thing with different transition directions. See the [documentation for nav-link](https://ionicframework.com/docs/api/nav-link) for more information.
#### Radio
The `ion-radio` must be used inside of an `ion-radio-group` even if there is only one `ion-radio`. Additionally, the `checked` property has been removed. Developers should set the `value` property on the parent `ion-radio-group` to match the value of the desired checked radio button.
`ion-radio` no longer emits an `ionSelect` event. Developers should listen for an `ionChange` event to be emitted on `ion-radio-group` instead.
**Before**
```html
<ion-radio checked>One</ion-radio>
<ion-radio-group>
<ion-radio>One</ion-radio>
<ion-radio checked>Two</ion-radio>
</ion-radio-group>
```
**After**
```html
<ion-radio-group value="one">
<ion-radio value="one">One</ion-radio>
</ion-radio-group>
<ion-radio-group value="two">
<ion-radio value="one">One</ion-radio>
<ion-radio value="two">Two</ion-radio>
</ion-radio-group>
```
#### Searchbar
##### Show Cancel Button
The `show-cancel-button` property of the searchbar no longer accepts boolean values. Accepted values are strings: `"focus"`, `"always"`, `"never"`.
**Before**
```html
<ion-searchbar show-cancel-button>
<ion-searchbar show-cancel-button="true">
<ion-searchbar show-cancel-button="false">
```
**After**
```html
<ion-searchbar show-cancel-button="focus">
<ion-searchbar show-cancel-button="focus">
<ion-searchbar show-cancel-button="never">
```
See the [Searchbar documentation](https://ionicframework.com/docs/api/searchbar#properties) for more information.
##### Inputmode
The `inputmode` property for `ion-searchbar` now defaults to `undefined`. To get the old behavior, set the inputmode property to `"search"`.
#### Segment
Segment was completely revamped to use the new iOS design including an all new gesture that applies for both Material Design and iOS. Due to these changes, some breaking changes were inevitably introduced in order to support the new design.
##### Renamed Events
`ion-segment` no longer emits an `ionSelect` event. Developers should listen for an `ionChange` event to be emitted on `ion-segment` instead.
##### Button States
- The activated styles and custom CSS properties have been removed. These are no longer being used in the latest spec as the indicator and ripple are used to show activation. Properties removed:
```
--color-activated
--background-activated
```
- The [Focused & Hover States](#activated-focused-hover-states) have been updated.
##### Indicator Color
- `--indicator-color` now applies to the checked segment button (for both `ios` and `md`)
- `--indicator-color-checked` has been removed
- The Material Design spec does not include an indicator color on non-checked buttons: https://material.io/components/tabs/
- In order to style the Segment to match the old spec, please use custom CSS. For example, to update Material Design to include a bottom line all of the time:
```css
.md ion-segment::after {
position: absolute;
bottom: 0;
height: 2px;
width: 100%;
content: '';
background: rgba(0,0,0,0.5);
z-index: -1;
}
```
##### Background & Color
A `--background` variable has been added to style the `ion-segment` component. As a result of this, the following background variables for a child segment button must now be set on the `ion-segment-button`:
```
--background: Background of the segment button
--background-checked: Background of the checked segment button
--background-disabled: Background of the disabled segment button
--background-hover: Background of the segment button on hover
```
> Note: iOS no longer checks the button background, so setting the `--background-checked` variable may have an undesired outcome. Instead, Segment uses an indicator to slide between the buttons, showing which one is checked. See the previous section on the indicator color variables.
The above variables *will not* be inherited in the button if set on the `ion-segment`. In addition to this, all color variables should also be set on the button for consistency:
```
--color: Color of the segment button
--color-checked: Color of the checked segment button
--color-disabled: Color of the disabled segment button
--color-hover: Color of the segment button on hover
```
###### Removed variables
The following variables were removed due to the current spec no longer using them.
- `--color-checked-disabled`
- `--background-disabled`
- `--color-disabled`
- `--background-activated`
- `--color-activated`
##### Global CSS Properties
Some variables were renamed or added. See the chart below for the new names.
| Old variable | Status | New variable |
| ----------------------------------------| --------|-------------------------------------------|
| `--ion-toolbar-color-unchecked` | renamed | `--ion-toolbar-segment-color` |
| `--ion-toolbar-color-checked` | renamed | `--ion-toolbar-segment-color-checked` |
| `--ion-toolbar-background-unchecked` | renamed | `--ion-toolbar-segment-background` |
| `--ion-toolbar-background-checked` | renamed | `--ion-toolbar-segment-background-checked`|
| | added | `--ion-toolbar-segment-indicator-color` |
#### Segment Button
The `checked` property has been removed. Developers should set the `value` property on the parent `ion-segment` to match the value of the desired checked segment button.
**Before**
```html
<ion-segment>
<ion-segment-button>One</ion-segment-button>
<ion-segment-button checked>Two</ion-segment-button>
<ion-segment-button>Three</ion-segment-button>
</ion-segment>
```
**After**
```html
<ion-segment value="two">
<ion-segment-button value="one">One</ion-segment-button>
<ion-segment-button value="two">Two</ion-segment-button>
<ion-segment-button value="three">Three</ion-segment-button>
</ion-segment>
```
#### Select Option
The `selected` property has been removed. Developers should set the `value` property on the parent `ion-select` to match the desired selected option.
**Before**
```html
<ion-select>
<ion-select-option>One</ion-select-option>
<ion-select-option selected>Two</ion-select-option>
</ion-select>
```
**After**
```html
<ion-select value="two">
<ion-select-option value="one">One</ion-select-option>
<ion-select-option value="two">Two</ion-select-option>
</ion-select>
```
#### Skeleton Text
The `width` property has been removed in favor of using CSS styling.
#### Split Pane
- Converted to use [shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM).
- Removed the `main` attribute, use `content-id` (for vanilla JS / Vue) and `contentId` (for Angular / React) instead.
**Before**
```html
<ion-split-pane>
...
<div main>...</div>
</ion-split-pane>
```
**After**
```html
<ion-split-pane content-id="main">
...
<div id="main">...</div>
</ion-split-pane>
```
#### Tabs
- [Focused State](#activated-focused-hover-states) have been updated.
#### Toast
The close button properties (`showCloseButton` and `closeButtonText`) have been removed. Use the `buttons` array instead with `role: 'cancel'`. See the [usage documentation](https://ionicframework.com/docs/api/toast#usage) for more information.
**Before**
```javascript
async presentToast() {
const toast = await this.toastController.create({
message: 'Your settings have been saved.',
showCloseButton: true,
closeButtonText: 'Close'
});
toast.present();
}
```
**After**
```javascript
async presentToast() {
const toast = await this.toastController.create({
message: 'Your settings have been saved.',
buttons: [
{
text: 'Close',
role: 'cancel',
handler: () => {
console.log('Close clicked');
}
}
]
});
toast.present();
}
```
### Colors
The default Ionic colors have been updated to the following:
```scss
primary: #3880ff
secondary: #3dc2ff
tertiary: #5260ff
success: #2dd36f
warning: #ffc409
danger: #eb445a
light: #f4f5f8
medium: #92949c
dark: #222428
```
`primary`, `light` and `dark` have not changed. The contrast color for `warning` has been updated to `#000`.
This will only be a breaking change in your app if you are not using one of our starters and not overriding the defaults. If you are overriding the defaults already these will need to be manually updated if desired.
### Events
The `@ionic/angular` Events service has been removed.
- Use "Observables" for a similar pub/sub architecture: https://angular.io/guide/observables
- Use "Redux" for advanced state management: https://ngrx.io
### Mode
Mode is now cascaded from the parent to the child component. Previously, if you wanted to update a component and its children to use the same mode, you'd have to set it on all components. For example, if you wanted to use a `md` segment no matter the mode, you'd have to write the following:
```html
<ion-segment mode="md">
<ion-segment-button mode="md">Button</ion-segment-button>
<ion-segment-button mode="md">Button</ion-segment-button>
</ion-segment>
```
Now, the `mode` only needs to be set on the `ion-segment` and it will be inherited. If this behavior is not desired set a different mode on the child component.
### Ionicons
Ionicons 5 has been released! :tada: This brings many changes including a top to bottom re-draw of every icon, variants for each icon (filled, outline, and sharp), and the removal of auto-switching icons based on the platform.
For more information, check out the [Ionicons Changelog](https://github.com/ionic-team/ionicons/blob/master/CHANGELOG.md)!
--------------------------------------------------------------------------------------------------
## Version 4.x
The list of the breaking changes introduced in Ionic Angular v4 can be found in [angular/BREAKING.md](https://github.com/ionic-team/ionic/blob/master/angular/BREAKING.md).
## Legacy
For the breaking changes of the older legacy versions (versions 2.x & 3.x) of Ionic Framework, see the [v3 changelog](https://github.com/ionic-team/ionic-v3/blob/master/CHANGELOG.md).

View File

@@ -1,3 +1,612 @@
# [5.2.0](https://github.com/ionic-team/ionic/compare/v5.1.1...v5.2.0) (2020-06-10)
### Bug Fixes
* **action-sheet, toast:** allow button handler to return `Promise<void>` ([#21259](https://github.com/ionic-team/ionic/issues/21259)) ([7703da2](https://github.com/ionic-team/ionic/commit/7703da28f8181b02390b97a7d4d02df99b2ad34c))
* **angular:** patch FormControl methods to properly sync Ionic form classes ([#21429](https://github.com/ionic-team/ionic/issues/21429)) ([e95b481](https://github.com/ionic-team/ionic/commit/e95b481a53191582bca635f322ad07eadbd62d64))
* **datetime:** ensure year-only values are not affected by timezone when parsing ([#21309](https://github.com/ionic-team/ionic/issues/21309)) ([3937101](https://github.com/ionic-team/ionic/commit/3937101e5c2b181a6b7926eb8386c22b0f887716))
* **header:** large title transition now works on older versions of iOS ([#21339](https://github.com/ionic-team/ionic/issues/21339)) ([2dac12c](https://github.com/ionic-team/ionic/commit/2dac12c577e0c7a5310857389dbda2b2b3dfadd1))
* **img:** use setTimeout fallback on older versions of chrome ([#21358](https://github.com/ionic-team/ionic/issues/21358)) ([0bf9449](https://github.com/ionic-team/ionic/commit/0bf9449ee1f9b2498e35f61511cb3e018814c6ca))
* **ios:** add haptic drag gesture for action sheet and alert components ([#21060](https://github.com/ionic-team/ionic/issues/21060)) ([33be1f0](https://github.com/ionic-team/ionic/commit/33be1f061ebbe27ee22e357c394f112af42ec360))
* **item:** inherit align-items from parent item ([#19278](https://github.com/ionic-team/ionic/issues/19278)) ([882f8fe](https://github.com/ionic-team/ionic/commit/882f8fef07dfb6ebda17ca09046d1af281075098)), closes [#18703](https://github.com/ionic-team/ionic/issues/18703)
* **item:** input-wrapper now inherits overflow ([#21282](https://github.com/ionic-team/ionic/issues/21282)) ([29d208d](https://github.com/ionic-team/ionic/commit/29d208de88f340e216e22badb6366bba4eda8bfb))
* **menu-button:** screen readers now properly announce menu button ([#21324](https://github.com/ionic-team/ionic/issues/21324)) ([eaf4fb6](https://github.com/ionic-team/ionic/commit/eaf4fb6b2a6d68f5c3d8d49ef41b4885f096070d))
* **modal:** card style modal no longer gets stuck when swiping quickly ([#21224](https://github.com/ionic-team/ionic/issues/21224)) ([448dfa0](https://github.com/ionic-team/ionic/commit/448dfa0a6955008ce4dc73354f5b8319ae1a1cc2))
* **modal:** set card-style modal height using the --height css variable ([#21453](https://github.com/ionic-team/ionic/issues/21453)) ([a4f0bdb](https://github.com/ionic-team/ionic/commit/a4f0bdb4c3ceeeaf902d520e9aa72e04a6ec2302))
* **reorder-group:** revert item to original position when passing false to complete ([#21396](https://github.com/ionic-team/ionic/issues/21396)) ([5f2001c](https://github.com/ionic-team/ionic/commit/5f2001c43c0846ec8973cbb8eb5662976ba7e31a)), closes [#19128](https://github.com/ionic-team/ionic/issues/19128)
* **router:** use correct nav transition when going back ([#21301](https://github.com/ionic-team/ionic/issues/21301)) ([c8db0d5](https://github.com/ionic-team/ionic/commit/c8db0d5eeba6f10d1492e95e6df6b4d871d43400))
* **scroll-assist:** improve scroll detection accuracy ([#21416](https://github.com/ionic-team/ionic/issues/21416)) ([137c49d](https://github.com/ionic-team/ionic/commit/137c49d70be45e1b0ee73d41fed6e9d69a2caa32))
* **slides:** update Swiper dependency to resolve error when doing SSR ([#21350](https://github.com/ionic-team/ionic/issues/21350)) ([3290604](https://github.com/ionic-team/ionic/commit/32906048a491961ec7340ba2e085807ea8a9c118))
* **textarea:** native textarea inherits max/min width and height ([#21333](https://github.com/ionic-team/ionic/issues/21333)) ([2377480](https://github.com/ionic-team/ionic/commit/237748049c7644ae8a7a74101ece5cfd7a160470))
### Features
* **alert:** add destructive role to alert buttons ([#21269](https://github.com/ionic-team/ionic/issues/21269)) ([e53f024](https://github.com/ionic-team/ionic/commit/e53f0241e2bf91461c55097fde271ae85ca644ea))
* **alert:** add support for custom input attributes ([#21365](https://github.com/ionic-team/ionic/issues/21365)) ([1ed8169](https://github.com/ionic-team/ionic/commit/1ed81693f225b6801a0897ef1a8314999c122484))
* **all:** add all autocomplete values to input and searchbar ([#21297](https://github.com/ionic-team/ionic/issues/21297)) ([4fd7c0c](https://github.com/ionic-team/ionic/commit/4fd7c0cc5a6c97100fa380e4ff1be0bb84c7006b))
* **all:** add optional generic typings for overlay component methods ([#21393](https://github.com/ionic-team/ionic/issues/21393)) ([5bf83b8](https://github.com/ionic-team/ionic/commit/5bf83b80d7d2749719dd1a280ae8e205fbc4b2a9))
* **all:** add shadow parts to missing components ([#21436](https://github.com/ionic-team/ionic/issues/21436)) ([17375d2](https://github.com/ionic-team/ionic/commit/17375d232500b47ef1cacd7c028c38990d307984))
* **all:** add support for configuring animations on a per-page basis ([#21433](https://github.com/ionic-team/ionic/issues/21433)) ([f34d375](https://github.com/ionic-team/ionic/commit/f34d3752e3462c9d81487fc86af5ec185cc3d1e3))
* **angular:** expose activatedView ([#21302](https://github.com/ionic-team/ionic/issues/21302)) ([829a0d9](https://github.com/ionic-team/ionic/commit/829a0d9be5a20c5fc96b5c5f18fedc4eb5e5b9ec))
* **angular:** expose getPlatforms and isPlatform ([#21308](https://github.com/ionic-team/ionic/issues/21308)) ([4af54a2](https://github.com/ionic-team/ionic/commit/4af54a2fea5d9cef843b1ebce849fb4a5c206f0b))
* **angular:** add strongly typed Ionic lifecycle hooks ([#18044](https://github.com/ionic-team/ionic/issues/18044)) ([53fc8e3](https://github.com/ionic-team/ionic/commit/53fc8e37c89cea793d0e00246d52805166730108)), closes [#18043](https://github.com/ionic-team/ionic/issues/18043)
* **fab-button:** add close icon font size css variable ([#19628](https://github.com/ionic-team/ionic/issues/19628)) ([df408f9](https://github.com/ionic-team/ionic/commit/df408f91f1aef903adaa5e635fef9bc7542e8739))
* **fab-button:** add closeIcon property ([#19626](https://github.com/ionic-team/ionic/issues/19626)) ([698e526](https://github.com/ionic-team/ionic/commit/698e526b9f882e98efc4bf160999182c645b772c))
* **select-option:** pass class from the option to the interface for individual styling ([#21304](https://github.com/ionic-team/ionic/issues/21304)) ([5285824](https://github.com/ionic-team/ionic/commit/5285824da5258ea638420fc60c50e0a19952f89c))
## [5.1.1](https://github.com/ionic-team/ionic/compare/v5.1.0...v5.1.1) (2020-05-13)
### Bug Fixes
* **all:** improve scroll assist reliability for below the fold inputs ([#21206](https://github.com/ionic-team/ionic/issues/21206)) ([7166a29](https://github.com/ionic-team/ionic/commit/7166a290cc1dd728e5bab2f7e39b8d41954e3808))
* **all:** overlay components no longer display outline when focused ([#21226](https://github.com/ionic-team/ionic/issues/21226)) ([bb62023](https://github.com/ionic-team/ionic/commit/bb62023a0cdc5a64e956766c7d1704797fc8c9ae))
* **display:** remove 1px gap between mutually exclusive breakpoints ([#21276](https://github.com/ionic-team/ionic/issues/21276)) ([703ef5c](https://github.com/ionic-team/ionic/commit/703ef5c99284f1e2b8d63c3af411c945dc756e20)), closes [#20993](https://github.com/ionic-team/ionic/issues/20993) [#20743](https://github.com/ionic-team/ionic/issues/20743)
* **header:** do not error on collapsible header on devices that do not support IntersectionObserve ([#21222](https://github.com/ionic-team/ionic/issues/21222)) ([0c13f25](https://github.com/ionic-team/ionic/commit/0c13f25bbb4d4674e76cd19b098900f698e7146e))
* **input:** check for tabindex and pass it properly to native input ([#21170](https://github.com/ionic-team/ionic/issues/21170)) ([dd4cb70](https://github.com/ionic-team/ionic/commit/dd4cb706ffeebc2069645ea03f0e7a96d6b14d43)), closes [#17515](https://github.com/ionic-team/ionic/issues/17515)
* **ios:** position page transition shadow properly under footer ([#21095](https://github.com/ionic-team/ionic/issues/21095)) ([50678c0](https://github.com/ionic-team/ionic/commit/50678c03c9829a87408633dabd77b21da1650a84))
* **md:** do not hide page when swipe gesture is cancelled ([#21247](https://github.com/ionic-team/ionic/issues/21247)) ([f334e83](https://github.com/ionic-team/ionic/commit/f334e83a43f855ac1e36eaf73954df6ee27a03af))
* **overlays:** respect keyboardClose property when opening overlays ([#21240](https://github.com/ionic-team/ionic/issues/21240)) ([9d0dcbb](https://github.com/ionic-team/ionic/commit/9d0dcbbd31fc34ad8952eacb9864ad1b31636113))
* **picker:** haptics now work properly ([#21268](https://github.com/ionic-team/ionic/issues/21268)) ([8e11ecc](https://github.com/ionic-team/ionic/commit/8e11ecc136c61e925e76c0e48ab21611e09b5898))
* **refresher:** correctly select shadow root on older browsers ([#21237](https://github.com/ionic-team/ionic/issues/21237)) ([f23f1cb](https://github.com/ionic-team/ionic/commit/f23f1cb37eef02307c357fbb48c0db729974cdc4))
* **refresher:** refresher completes even after switching to a new tab ([#21236](https://github.com/ionic-team/ionic/issues/21236)) ([1e6f923](https://github.com/ionic-team/ionic/commit/1e6f92377aaf0804cfd0ddb9b06da7b4c9dc355f))
* **segment-button:** screen readers now announce selected state properly ([#21273](https://github.com/ionic-team/ionic/issues/21273)) ([85cc35e](https://github.com/ionic-team/ionic/commit/85cc35ee9163a38c48c6df466a3c036906437804))
* **toggle:** screen readers now announce toggle properly ([#21168](https://github.com/ionic-team/ionic/issues/21168)) ([1fbdb22](https://github.com/ionic-team/ionic/commit/1fbdb2255e4ff7fccf22d9ccc12b7f9bb4c3a064))
# [5.1.0 Aluminum](https://github.com/ionic-team/ionic/compare/v5.0.7...v5.1.0) (2020-04-30)
### Bug Fixes
* **action-sheet:** show correct cancel button background on dark mode ([#21084](https://github.com/ionic-team/ionic/issues/21084)) ([e442324](https://github.com/ionic-team/ionic/commit/e4423247537cbcda174305ab9fdde4a57c50a88e)), closes [#21082](https://github.com/ionic-team/ionic/issues/21082)
* **all:** correctly default gestures to use a passive listener ([#21038](https://github.com/ionic-team/ionic/issues/21038)) ([dea9248](https://github.com/ionic-team/ionic/commit/dea9248763737164e17678119c775cdfc0e53ccd))
* **angular:** do not navigate to the same tab if already active ([#21085](https://github.com/ionic-team/ionic/issues/21085)) ([15203de](https://github.com/ionic-team/ionic/commit/15203de08bf97f27e33f35994444c2c4843b3a44)), closes [#21074](https://github.com/ionic-team/ionic/issues/21074) [#19943](https://github.com/ionic-team/ionic/issues/19943)
* **back-button:** announce back button text correctly by screen readers ([#21053](https://github.com/ionic-team/ionic/issues/21053)) ([14c226c](https://github.com/ionic-team/ionic/commit/14c226ce75958da14b66821028d6f3a6852d695c)), closes [#21043](https://github.com/ionic-team/ionic/issues/21043)
* **datetime:** locale inputs are now reactive ([#20826](https://github.com/ionic-team/ionic/issues/20826)) ([a75e8f3](https://github.com/ionic-team/ionic/commit/a75e8f34d608c167f8d429ddbf39e94173204a61)), closes [#20367](https://github.com/ionic-team/ionic/issues/20367)
* **ios:** account for nested tabs with page transition ([#20955](https://github.com/ionic-team/ionic/issues/20955)) ([e23dec5](https://github.com/ionic-team/ionic/commit/e23dec5eb9fbb58eedffabefca8d7d643f49f7b9)), closes [#20948](https://github.com/ionic-team/ionic/issues/20948)
* **ios:** properly animate content when navigating from a tabbed page ([#20918](https://github.com/ionic-team/ionic/issues/20918)) ([8a02b28](https://github.com/ionic-team/ionic/commit/8a02b28efeca81c25176ff52508b4005441e8314)), closes [#20912](https://github.com/ionic-team/ionic/issues/20912)
* **loading:** correctly announce spinner by screen readers ([#21116](https://github.com/ionic-team/ionic/issues/21116)) ([63d8f62](https://github.com/ionic-team/ionic/commit/63d8f6239cc39e6a111108bd1a2557c297a256ae)), closes [#21107](https://github.com/ionic-team/ionic/issues/21107)
* **md:** do not display blank screen when using MD page transition and swipe gesture ([#21058](https://github.com/ionic-team/ionic/issues/21058)) ([4973807](https://github.com/ionic-team/ionic/commit/497380743df4461688455bc8b8440d2f3cc7c247)), closes [#21056](https://github.com/ionic-team/ionic/issues/220800)
* **modal:** properly inherit border radius for modals on Safari ([#20887](https://github.com/ionic-team/ionic/issues/20887)) ([bd64509](https://github.com/ionic-team/ionic/commit/bd64509bae9dd4c960134d986ce8150dc1a9d3b4)), closes [#20878](https://github.com/ionic-team/ionic/issues/20878)
* **modal:** swipeToClose property is now reactive ([#21073](https://github.com/ionic-team/ionic/issues/21073)) ([4bd9134](https://github.com/ionic-team/ionic/commit/4bd91344730bd26c66a8d838436d94045dc21f78)), closes [#21072](https://github.com/ionic-team/ionic/issues/21072)
* **overlays:** focus overlay when presented ([#20997](https://github.com/ionic-team/ionic/issues/20997)) ([fc2be8d](https://github.com/ionic-team/ionic/commit/fc2be8d08bbb495df911783f808d7ca511942172)), closes [#19882](https://github.com/ionic-team/ionic/issues/19882) [#17126](https://github.com/ionic-team/ionic/issues/17126)
* **overlays:** prevent accidental clicks when dismissing overlays ([#21093](https://github.com/ionic-team/ionic/issues/21093)) ([671802f](https://github.com/ionic-team/ionic/commit/671802f9a2050d9942e9dfb2db9f9c58bdc58620)), closes [#21092](https://github.com/ionic-team/ionic/issues/21092)
* **react:** IonTabBar properly extends IonicReactProps ([#21009](https://github.com/ionic-team/ionic/issues/21009)) ([102a842](https://github.com/ionic-team/ionic/commit/102a842bd2a967c04a3cf42ed4e0811929bd4d99)), closes [#21006](https://github.com/ionic-team/ionic/issues/21006)
* **refresher:** properly check for Haptics plugin on web ([#21156](https://github.com/ionic-team/ionic/issues/21156)) ([c53b136](https://github.com/ionic-team/ionic/commit/c53b136dbe7ed7fc0fc298593f8b677a66c77910)), closes [#21148](https://github.com/ionic-team/ionic/issues/21148)
* **refresher:** properly calculate content dimensions in native ion-refresher ([#21157](https://github.com/ionic-team/ionic/issues/21157)) ([83dcc71](https://github.com/ionic-team/ionic/commit/83dcc7168a48bc5b05583fb7c01b5eff9d1a67f8))
* **router:** account for query string when pushing page ([#21071](https://github.com/ionic-team/ionic/issues/21071)) ([eab3373](https://github.com/ionic-team/ionic/commit/eab33732133bd43ca6788bba6e93a9b545ee058a))
* **searchbar:** correctly announce the cancel button text by screen readers ([#21049](https://github.com/ionic-team/ionic/issues/21049)) ([15a603b](https://github.com/ionic-team/ionic/commit/15a603b39797dee6baf7e33d58907f98ced7e86d)), closes [#21013](https://github.com/ionic-team/ionic/issues/21013)
* **select:** account for MutationObserver when performing SSR ([#21068](https://github.com/ionic-team/ionic/issues/21068)) ([66e8e64](https://github.com/ionic-team/ionic/commit/66e8e6404d87a2767e71b13bed19706b29ad1b9c)), closes [#21063](https://github.com/ionic-team/ionic/issues/21063)
* **slides:** slides no longer break with Angular Ivy enabled ([#20899](https://github.com/ionic-team/ionic/issues/20899)) ([3123a31](https://github.com/ionic-team/ionic/commit/3123a318b6755dbf8fde8476f81c37e6ffa9b70e)), closes [#20356](https://github.com/ionic-team/ionic/issues/20356)
* **split-pane:** properly show border in rtl mode ([#20995](https://github.com/ionic-team/ionic/issues/20995)) ([7a21708](https://github.com/ionic-team/ionic/commit/7a21708d24bab6a388e1b55c88337e3d0f7922eb)), closes [#20994](https://github.com/ionic-team/ionic/issues/20994)
* **textarea:** height is set correctly when using autoGrow in modals ([#20971](https://github.com/ionic-team/ionic/issues/20971)) ([32ee040](https://github.com/ionic-team/ionic/commit/32ee040e3f0d7012790f190856097d0c6fa0eaa2)), closes [#18993](https://github.com/ionic-team/ionic/issues/18993)
### Features
* **all:** add ability to continue processing hardware back button events ([#20613](https://github.com/ionic-team/ionic/issues/20613)) ([3821c04](https://github.com/ionic-team/ionic/commit/3821c0463ae9a02e67c835a221c4ea01fab306d1)), closes [#17824](https://github.com/ionic-team/ionic/issues/17824)
* **all:** add ability to eject from Ionic sanitizer ([#20457](https://github.com/ionic-team/ionic/issues/20457)) ([fa9ddc9](https://github.com/ionic-team/ionic/commit/fa9ddc91bc9fefc2bb247cfe7511384f77335476)), closes [#18277](https://github.com/ionic-team/ionic/issues/18277)
* **angular:** support multi-app for ng-add schematic ([#20768](https://github.com/ionic-team/ionic/issues/20768)) ([39e6c8f](https://github.com/ionic-team/ionic/commit/39e6c8f55b514b0c7330dd3a790c859bb3410404))
* **animation:** add option to clean up old animation stylesheets ([#20940](https://github.com/ionic-team/ionic/issues/20940)) ([5b98405](https://github.com/ionic-team/ionic/commit/5b9840508faf6a2c985726be889c1f2fca0e0733)), closes [#20610](https://github.com/ionic-team/ionic/issues/20610)
* **app:** add keyboard open and close events (ionKeyboardDidShow and ionKeyboardDidHide) ([#18478](https://github.com/ionic-team/ionic/issues/18478)) ([ae5f1dd](https://github.com/ionic-team/ionic/commit/ae5f1ddff0c0799167a154abbb418b2ad3434d47))
* **back-button:** add backButtonDefaultHref property to Ionic Config ([#20491](https://github.com/ionic-team/ionic/issues/20491)) ([1b11ff7](https://github.com/ionic-team/ionic/commit/1b11ff7fb92b75f5c869c79d5e0d5dfd8889597f)), closes [#19305](https://github.com/ionic-team/ionic/issues/19305)
* **checkbox:** add parts support for container, mark ([#20950](https://github.com/ionic-team/ionic/issues/20950)) ([d4b9151](https://github.com/ionic-team/ionic/commit/d4b9151396aed6d7a29d8f40d6e607bf6258b4ef))
* **content:** add parts support for background, scroll ([#20929](https://github.com/ionic-team/ionic/issues/20929)) ([578ab93](https://github.com/ionic-team/ionic/commit/578ab93d297f101ac899b6b6b099445ac679c71f))
* **datetime:** add parts support for placeholder, text ([#20930](https://github.com/ionic-team/ionic/issues/20930)) ([76ca475](https://github.com/ionic-team/ionic/commit/76ca475734e13404886bdf70117c0c39bbd7ce70))
* **gesture:** add option to run inside NgZone for Angular apps ([#20685](https://github.com/ionic-team/ionic/issues/20685)) ([429edb0](https://github.com/ionic-team/ionic/commit/429edb053bf2a5e778665770c373e31fc7d3bfd2)), closes [#20529](https://github.com/ionic-team/ionic/issues/20529)
* **gesture:** add support for blurring active inputs on gesture start ([#20638](https://github.com/ionic-team/ionic/issues/20638)) ([32ecdd6](https://github.com/ionic-team/ionic/commit/32ecdd67536f07f9d95e331e44661afb2cf7b470)), closes [#20588](https://github.com/ionic-team/ionic/issues/20588)
* **img:** add parts support for image ([#20943](https://github.com/ionic-team/ionic/issues/20943)) ([63c75ed](https://github.com/ionic-team/ionic/commit/63c75edd21387f28387c8a8529ba638317a9d9b8))
* **input:** add support for enterkeyhint ([#21035](https://github.com/ionic-team/ionic/issues/21035)) ([3efaf43](https://github.com/ionic-team/ionic/commit/3efaf4382175d40902968cabb7edd672ffc7cc2b)), closes [#21034](https://github.com/ionic-team/ionic/issues/21034)
* **item:** add parts support for detail-icon ([#20979](https://github.com/ionic-team/ionic/issues/20979)) ([6414496](https://github.com/ionic-team/ionic/commit/64144960b06e056a99aa3d352486a495b6bb43ed))
* **menu:** add parts support for backdrop, container ([#20978](https://github.com/ionic-team/ionic/issues/20978)) ([50bc212](https://github.com/ionic-team/ionic/commit/50bc212d0b30919c136d6be60a9d458ec7d50dde))
* **radio:** add parts support for container, mark ([#20952](https://github.com/ionic-team/ionic/issues/20952)) ([228ca2b](https://github.com/ionic-team/ionic/commit/228ca2b093215aba91fe925b301049471ffaa169))
* **range:** add parts support for bar, bar-active, knob, pin, tick, tick-active ([#20961](https://github.com/ionic-team/ionic/issues/20961)) ([619f67a](https://github.com/ionic-team/ionic/commit/619f67a00baa387d0f2bf3f6219e21bc87c03313))
* **react:** expose selectTab method and activeTab, closes [#19935](https://github.com/ionic-team/ionic/issues/19935) ([#21171](https://github.com/ionic-team/ionic/issues/21171)) ([43f9d24](https://github.com/ionic-team/ionic/commit/43f9d24824e4c1b679b350b3db05a6830d98fc0a))
* **reorder:** add parts support for icon ([#20960](https://github.com/ionic-team/ionic/issues/20960)) ([ba20209](https://github.com/ionic-team/ionic/commit/ba20209604666048619ae5f4358be0e65ef36e4f))
* **searchbar:** add border-radius css variable ([#20662](https://github.com/ionic-team/ionic/issues/20662)) ([acaa1d9](https://github.com/ionic-team/ionic/commit/acaa1d9ef7e4037913159c0d32829183ddc1860b)), closes [#17426](https://github.com/ionic-team/ionic/issues/17426) [#18247](https://github.com/ionic-team/ionic/issues/18247)
* **searchbar:** add support for enterkeyhint ([#21036](https://github.com/ionic-team/ionic/issues/21036)) ([e90683a](https://github.com/ionic-team/ionic/commit/e90683a713cb45d1e1283dd41343ea6b672a9e3a)), closes [#21034](https://github.com/ionic-team/ionic/issues/21034)
* **select:** add parts support for placeholder, icon, text ([#21108](https://github.com/ionic-team/ionic/issues/21108)) ([30a1c89](https://github.com/ionic-team/ionic/commit/30a1c896883e971ab87ef7d5d8790e9a60632fc2))
* **slides:** update to swiper 5 ([#20917](https://github.com/ionic-team/ionic/issues/20917)) ([4e28445](https://github.com/ionic-team/ionic/commit/4e28445ecb029f8d225acf9313209e5f61114dc4)), closes [#20033](https://github.com/ionic-team/ionic/issues/20033)
* **textarea:** add support for inputmode and enterkeyhint ([#21106](https://github.com/ionic-team/ionic/issues/21106)) ([1622d9b](https://github.com/ionic-team/ionic/commit/1622d9bb3c7f2aeed7dc823620204737619a5b0d))
* **toast:** add white-space variable for toast message ([#20729](https://github.com/ionic-team/ionic/issues/20729)) ([e5e02d4](https://github.com/ionic-team/ionic/commit/e5e02d4f88abbcc7dbc626db6d5adf4292d8e776)), closes [#20727](https://github.com/ionic-team/ionic/issues/20727)
* **toggle:** add parts support for handle, track ([#20962](https://github.com/ionic-team/ionic/issues/20962)) ([d2b772f](https://github.com/ionic-team/ionic/commit/d2b772f19fde71bcec72300cb4cf8234321b35bc))
* **toggle:** improve customization with css vars and auto-adjust handle width and height ([#21050](https://github.com/ionic-team/ionic/issues/21050)) ([04ace4c](https://github.com/ionic-team/ionic/commit/04ace4c98346fde5bad343224657f049beb3e868)), closes [#19868](https://github.com/ionic-team/ionic/issues/19868) [#20474](https://github.com/ionic-team/ionic/issues/20474)
### Performance Improvements
* **all:** improve scroll assist responsiveness ([#20987](https://github.com/ionic-team/ionic/issues/20987)) ([6f13b8c](https://github.com/ionic-team/ionic/commit/6f13b8c7922f638cac4eb3b111ff9643e6995491)), closes [#20922](https://github.com/ionic-team/ionic/issues/20922)
## [5.0.7](https://github.com/ionic-team/ionic/compare/v5.0.6...v5.0.7) (2020-03-26)
### Bug Fixes
* **modal:** properly target card modal for iPadOS styles ([#20884](https://github.com/ionic-team/ionic/issues/20884)) ([5816cf5](https://github.com/ionic-team/ionic/commit/5816cf52a779acc4613c2d2da28b97c511360cc2))
## [5.0.6](https://github.com/ionic-team/ionic/compare/v5.0.5...v5.0.6) (2020-03-25)
### Bug Fixes
* **all** only warn invalid mode if used on an ionic component ([#20828](https://github.com/ionic-team/ionic/issues/20828)) ([6ed1c51](https://github.com/ionic-team/ionic/commit/6ed1c51321d781ff92efbf623790af91cb16a5af)), closes [#20055](https://github.com/ionic-team/ionic/issues/20055)
* **all** properly scroll to input with scroll assist ([#20742](https://github.com/ionic-team/ionic/issues/20742)) ([e24060e](https://github.com/ionic-team/ionic/commit/e24060ecd9d803ece4bbb9c6beae23e761d7fb5e)), closes [#19589](https://github.com/ionic-team/ionic/issues/19589)
* **angular:** export Animation and Gesture related types ([#20766](https://github.com/ionic-team/ionic/issues/20766)) ([2ece194](https://github.com/ionic-team/ionic/commit/2ece194a085742b919cc68f643b1b365f7d85594))
* **angular:** respect animation property for ion-router-outlet ([#20767](https://github.com/ionic-team/ionic/issues/20767)) ([f2dbe1f](https://github.com/ionic-team/ionic/commit/f2dbe1ff3be44e6697b791de392a9ef46dbf27e8)), closes [#20764](https://github.com/ionic-team/ionic/issues/20764)
* **content:** apply --offset-top and --offset-bottom values correctly ([#20790](https://github.com/ionic-team/ionic/issues/20790)) ([2707289](https://github.com/ionic-team/ionic/commit/2707289b36883ae495f86cfb2f2b6c84e090551b)), closes [#20735](https://github.com/ionic-team/ionic/issues/20735)
* **content:** set overscroll-behavior based on the scroll direction ([#20011](https://github.com/ionic-team/ionic/issues/20011)) ([a3fc77b](https://github.com/ionic-team/ionic/commit/a3fc77be91ead6edc3f07c6127879753a063bd18)), closes [#20010](https://github.com/ionic-team/ionic/issues/20010)
* **item-divider:** update design to match native iOS ([#20854](https://github.com/ionic-team/ionic/issues/20854)) ([d91e22d](https://github.com/ionic-team/ionic/commit/d91e22d820f170ecfdfad835ca56701ad70e6f3d))
* **item-sliding:** account for swipe to go back gesture when opening item-options ([#20777](https://github.com/ionic-team/ionic/issues/20777)) ([f23ac44](https://github.com/ionic-team/ionic/commit/f23ac44c9a6646129762bb861cae6145690ca5a1)), closes [#20773](https://github.com/ionic-team/ionic/issues/20773)
* **list:** show bottom border on last item in a list followed by a list ([#20798](https://github.com/ionic-team/ionic/issues/20798)) ([7bc5191](https://github.com/ionic-team/ionic/commit/7bc51911f6c538be8b91d1e569675b19832cb000))
* **modal:** backdrop and box shadows no longer stack when opening multiple modals ([#20801](https://github.com/ionic-team/ionic/issues/20801)) ([253cd96](https://github.com/ionic-team/ionic/commit/253cd96164914a803f6bb42ff95ca74880c940d0)), closes [#20800](https://github.com/ionic-team/ionic/issues/20800)
* **modal:** backdrop is no longer tappable on card-style modal on smaller screens ([#20802](https://github.com/ionic-team/ionic/issues/20802)) ([12932dd](https://github.com/ionic-team/ionic/commit/12932dd20212bec7d780650166c70819d125f75a)), closes [#20783](https://github.com/ionic-team/ionic/issues/20783)
* **modal:** properly apply border radius on card-style modal ([#20852](https://github.com/ionic-team/ionic/issues/20852)) ([dff3816](https://github.com/ionic-team/ionic/commit/dff3816c049a1c051f94d3176c8b903a69603912)), closes [#20851](https://github.com/ionic-team/ionic/issues/20851)
* **modal:** properly remove safe area padding on card-modal ([#20853](https://github.com/ionic-team/ionic/issues/20853)) ([71f1182](https://github.com/ionic-team/ionic/commit/71f118201b0918f60c1a078d55afd10b39f17e86)), closes [#20799](https://github.com/ionic-team/ionic/issues/20799)
* **modal:** respect card-style modal spec for iPadOS ([#20750](https://github.com/ionic-team/ionic/issues/20750)) ([75bae40](https://github.com/ionic-team/ionic/commit/75bae403e917b20645675343734440ee95d31634)), closes [#20700](https://github.com/ionic-team/ionic/issues/20700)
* **react:** expose correct type for CreateAnimation ([#20775](https://github.com/ionic-team/ionic/issues/20775)) ([0897c3f](https://github.com/ionic-team/ionic/commit/0897c3f9c2591442b3f80d28a25ec4471da3c9d7)), closes [#20771](https://github.com/ionic-team/ionic/issues/20771)
* **refresher:** properly dismiss refresher when completed synchronously ([#20815](https://github.com/ionic-team/ionic/issues/20815)) ([b1a87c8](https://github.com/ionic-team/ionic/commit/b1a87c88923201fd0b31bf55d81b97acc09ddf1c)), closes [#20803](https://github.com/ionic-team/ionic/issues/20803)
* **segment:** automatically expand width for scrollable segment buttons ([#20763](https://github.com/ionic-team/ionic/issues/20763)) ([cdfd50b](https://github.com/ionic-team/ionic/commit/cdfd50b554d1d8f89c3d9948c7613ce75ede1e52)), closes [#20566](https://github.com/ionic-team/ionic/issues/20566)
* **segment:** scrollable segments only show scrollbar if they overflow ([#20760](https://github.com/ionic-team/ionic/issues/20760)) ([ab146c9](https://github.com/ionic-team/ionic/commit/ab146c96ec5cbc962eed629c30b2c5c446f3098d)), closes [#20758](https://github.com/ionic-team/ionic/issues/20758)
* **slides:** check that mutation observer is defined for ssr ([#20791](https://github.com/ionic-team/ionic/issues/20791)) ([2d5d251](https://github.com/ionic-team/ionic/commit/2d5d2515be86496a280d93847185ab332e5d47a2))
* **textarea:** properly adjust auto-grow textarea in scrolled content ([#19776](https://github.com/ionic-team/ionic/issues/19776)) ([8bd5bac](https://github.com/ionic-team/ionic/commit/8bd5bace73670dfe351b3734b51cbf3aa87517dc)), closes [#19193](https://github.com/ionic-team/ionic/issues/19193)
* **title:** improve reliability of large title ios nav transition ([#20861](https://github.com/ionic-team/ionic/issues/20861)) ([3bd6b5d](https://github.com/ionic-team/ionic/commit/3bd6b5def2877f6a918c587de25a10ccc82f88f1))
* **title:** large title now inherits global color styling during nav transition ([#20862](https://github.com/ionic-team/ionic/issues/20862)) ([321140f](https://github.com/ionic-team/ionic/commit/321140ff736b46d2631a9e87a7b070009c5e1b2c))
## [5.0.5](https://github.com/ionic-team/ionic/compare/v5.0.4...v5.0.5) (2020-03-11)
### Bug Fixes
* **button:** allow overflow to be overridden by the CSS variable ([#20738](https://github.com/ionic-team/ionic/issues/20738)) ([7ecde36](https://github.com/ionic-team/ionic/commit/7ecde36f9d31327a45f7b5023ed533edbb9cc709)), closes [#20726](https://github.com/ionic-team/ionic/issues/20726)
* **datetime:** account for max property when hour, minute, or second is set to 0 ([#20665](https://github.com/ionic-team/ionic/issues/20665)) ([2177461](https://github.com/ionic-team/ionic/commit/21774612d8d70ab7eda3eab0e6e9ac039b5c87d8)), closes [#20652](https://github.com/ionic-team/ionic/issues/20652)
* **header:** collapsable header should default to using content background ([#20736](https://github.com/ionic-team/ionic/issues/20736)) ([f6c3ba7](https://github.com/ionic-team/ionic/commit/f6c3ba7e5af2af9e32f75306cde7704509e82263)), closes [#20691](https://github.com/ionic-team/ionic/issues/20691)
* **header:** resolve undefined error on collapsible header when navigating quickly ([#20728](https://github.com/ionic-team/ionic/issues/20728)) ([87a2721](https://github.com/ionic-team/ionic/commit/87a27216d011f1d02ac0fc0aeb3ae0400ecfbd8c)), closes [#20725](https://github.com/ionic-team/ionic/issues/20725)
* **ios:** large title animation now works properly in a modal ([#20703](https://github.com/ionic-team/ionic/issues/20703)) ([ec4878a](https://github.com/ionic-team/ionic/commit/ec4878ac085d8ff92cb8b2ea0852523f174ab01b)), closes [#20696](https://github.com/ionic-team/ionic/issues/20696)
* **item:** apply proper margin left for slotted icon in RTL ([#20684](https://github.com/ionic-team/ionic/issues/20684)) ([d53595e](https://github.com/ionic-team/ionic/commit/d53595eb1629e0d60f7e832414e84c544e184346)), closes [#20653](https://github.com/ionic-team/ionic/issues/20653)
* **label:** text overflow for slotted headings ([#20690](https://github.com/ionic-team/ionic/issues/20690)) ([4d34ce6](https://github.com/ionic-team/ionic/commit/4d34ce6a31eaa19859699646cc614f5be6239e10)), closes [#17087](https://github.com/ionic-team/ionic/issues/17087)
* **modal:** leave animation transitions modal completely out of viewport on ipad ([#20702](https://github.com/ionic-team/ionic/issues/20702)) ([22d5256](https://github.com/ionic-team/ionic/commit/22d52568100d8096ee36e3a61a19614f0d63d45f)), closes [#20697](https://github.com/ionic-team/ionic/issues/20697)
* **angular** exclude components from ssr ([#20674](https://github.com/ionic-team/ionic/issues/20674)) ([f64b142](https://github.com/ionic-team/ionic/commit/f64b1420aead39b9056dc25cfdbcf95bc4f6f621))
* **modal:** swipeable modal now works in firefox ([#20714](https://github.com/ionic-team/ionic/issues/20714)) ([7d260b9](https://github.com/ionic-team/ionic/commit/7d260b96a73958709fa93a4fe58f816a445471ee)), closes [#20706](https://github.com/ionic-team/ionic/issues/20706)
* **overlays:** prevent accidental dismiss of overlays when tapping screen twice ([#20683](https://github.com/ionic-team/ionic/issues/20683)) ([b6c2a77](https://github.com/ionic-team/ionic/commit/b6c2a77deb1c09eb1fd414f7737794e208ab5081)), closes [#20608](https://github.com/ionic-team/ionic/issues/20608)
* **segment:** allow routerLink to work on segment buttons ([#20682](https://github.com/ionic-team/ionic/issues/20682)) ([314dbb1](https://github.com/ionic-team/ionic/commit/314dbb1a4d970327fcbb2f3fbdec0627c626fe4d)), closes [#20678](https://github.com/ionic-team/ionic/issues/20678)
* **segment:** iOS mode segment now works on older Android devices ([#20673](https://github.com/ionic-team/ionic/issues/20673)) ([44993b7](https://github.com/ionic-team/ionic/commit/44993b7987031b6618409675fdbb1f15ec4ea343)), closes [#20648](https://github.com/ionic-team/ionic/issues/20648)
## [5.0.4](https://github.com/ionic-team/ionic/compare/v5.0.3...v5.0.4) (2020-02-27)
### Bug Fixes
* **animation:** reset all temporary flags when interrupting an animation ([#20627](https://github.com/ionic-team/ionic/issues/20627)) ([0e0e401](https://github.com/ionic-team/ionic/commit/0e0e401d86dabaa1dc804656e4d384154d6fdd05)), closes [#20602](https://github.com/ionic-team/ionic/issues/20602)
* **buttons:** use proper button colors based on CSS variables when inside of a toolbar ([#20633](https://github.com/ionic-team/ionic/issues/20633)) ([c1d7bf2](https://github.com/ionic-team/ionic/commit/c1d7bf229d10d0a12f90b6d2730d6d8ac78b48cd))
## [5.0.3](https://github.com/ionic-team/ionic/compare/v5.0.2...v5.0.3) (2020-02-26)
### Bug Fixes
* **menu:** allow ssr to work properly with hardware back button updates ([#20629](https://github.com/ionic-team/ionic/issues/20629)) ([fe8d74d](https://github.com/ionic-team/ionic/commit/fe8d74d08cb919ed1c685262f0aed4a544c3a7e1))
## [5.0.2](https://github.com/ionic-team/ionic/compare/v5.0.1...v5.0.2) (2020-02-26)
### Bug Fixes
* **ios:** large title transition works properly in tabbed applications ([#20555](https://github.com/ionic-team/ionic/issues/20555)) ([7187541](https://github.com/ionic-team/ionic/commit/71875417f207d26bd7115655f239251460a1e3d8)), closes [#20482](https://github.com/ionic-team/ionic/issues/20482)
* **menu:** hardware back button now dismisses side menu if open in Cordova/Capacitor app ([#20558](https://github.com/ionic-team/ionic/issues/20558)) ([6b2a929](https://github.com/ionic-team/ionic/commit/6b2a929cd7e70b16383cb3336b399a1aee2d6101)), closes [#20559](https://github.com/ionic-team/ionic/issues/20559)
* **modal:** allow swipe to close animation to be overridden ([#20585](https://github.com/ionic-team/ionic/issues/20585)) ([8d3ce8d](https://github.com/ionic-team/ionic/commit/8d3ce8d29c9abd89ce47c882e0d7b2ac0f861966)), closes [#20577](https://github.com/ionic-team/ionic/issues/20577)
* **modal:** card style modal now adds appropriate contrast ([#20604](https://github.com/ionic-team/ionic/issues/20604)) ([b5310ef](https://github.com/ionic-team/ionic/commit/b5310effe3f9b47459f22221da1853a55dbb0279))
* **modal:** allow swipeable modal background to be overridden ([#20584](https://github.com/ionic-team/ionic/issues/20584)) ([ad6fac8](https://github.com/ionic-team/ionic/commit/ad6fac83cb7c4acb377b4b1620ab1a3f852bc6d3)), closes [#20572](https://github.com/ionic-team/ionic/issues/20572)
* **modal:** swipeable modal styles only apply to ios ([#20571](https://github.com/ionic-team/ionic/issues/20571)) ([3a2d828](https://github.com/ionic-team/ionic/commit/3a2d82814b22a3987a5abfe4412d83a93a97b6b7)), closes [#20569](https://github.com/ionic-team/ionic/issues/20569)
* **refresher:** ensure that translate is cleaned up to avoid stacking context ([#20621](https://github.com/ionic-team/ionic/issues/20621)) ([e3e5c69](https://github.com/ionic-team/ionic/commit/e3e5c69681f376cbc4b1305f719fc6895b21a9b7)), closes [#17949](https://github.com/ionic-team/ionic/issues/17949)
* **segment:** segment functions properly on older versions of Android ([#20554](https://github.com/ionic-team/ionic/issues/20554)) ([0224bed](https://github.com/ionic-team/ionic/commit/0224bed0c9f91bcb54bb4b3064df56928cf5ed8a)), closes [#20466](https://github.com/ionic-team/ionic/issues/20466)
* **select:** properly align text, add icon-inner and placeholder part ([#20605](https://github.com/ionic-team/ionic/issues/20605)) ([926ac3f](https://github.com/ionic-team/ionic/commit/926ac3fb47228be19146ccdfab92a05cf6677ff4))
* **slides:** set height to 100% for vertical slides ([#20603](https://github.com/ionic-team/ionic/issues/20603)) ([20af652](https://github.com/ionic-team/ionic/commit/20af652a1be5e1aff2836422489642c8baed6939)), closes [#17341](https://github.com/ionic-team/ionic/issues/17341)
## [5.0.1](https://github.com/ionic-team/ionic/compare/v5.0.0...v5.0.1) (2020-02-19)
### Bug Fixes
* **button:** reduce font size of icon only button in toolbar on iOS ([#20547](https://github.com/ionic-team/ionic/issues/20547)) ([59fa340](https://github.com/ionic-team/ionic/commit/59fa340650840b2abf86bd643350da7064ee9ead))
* **card:** inherit background in inner button ([#20461](https://github.com/ionic-team/ionic/issues/20461)) ([c16de96](https://github.com/ionic-team/ionic/commit/c16de9663329993698c10e4251dbb0b75167701f)), closes [#20458](https://github.com/ionic-team/ionic/issues/20458)
* **fab:** add close icon to internal icons for react ([#20490](https://github.com/ionic-team/ionic/issues/20490)) ([c4fb314](https://github.com/ionic-team/ionic/commit/c4fb31403eb4704bcf04e6c32bfa46422f08bf4f)), closes [#20489](https://github.com/ionic-team/ionic/issues/20489)
* **fab:** show close icon on hover, focused, activated ([#20497](https://github.com/ionic-team/ionic/issues/20497)) ([e42c85d](https://github.com/ionic-team/ionic/commit/e42c85d64161b7fac7147325cb6c2ceff990042b))
* **input:** do not clear input if "Enter" key pressed ([#20462](https://github.com/ionic-team/ionic/issues/20462)) ([89bf08b](https://github.com/ionic-team/ionic/commit/89bf08b6276f2a25d66fc0e74ba3303f923af652)), closes [#20442](https://github.com/ionic-team/ionic/issues/20442)
* **ios:** clamp out of bounds values for swipe to go back ([#20540](https://github.com/ionic-team/ionic/issues/20540)) ([dd32a5e](https://github.com/ionic-team/ionic/commit/dd32a5e2788a11a5c2be0d1840f5775c7307c57f)), closes [#20505](https://github.com/ionic-team/ionic/issues/20505)
* **menu:** swipe gesture should not open menu when a modal is displayed ([#20546](https://github.com/ionic-team/ionic/issues/20546)) ([3252c2f](https://github.com/ionic-team/ionic/commit/3252c2f8dc46e0853a7f626baa6023a01ac21a25)), closes [#20467](https://github.com/ionic-team/ionic/issues/20467)
* **modal:** presenting multiple card-style modals now adds border radius properly ([#20476](https://github.com/ionic-team/ionic/issues/20476)) ([abf594a](https://github.com/ionic-team/ionic/commit/abf594aa611562a76e3baecfa38456d41a1410f3)), closes [#20475](https://github.com/ionic-team/ionic/issues/20475)
* **modal:** prevent card style modal styles from being overridden ([#20470](https://github.com/ionic-team/ionic/issues/20470)) ([86ab77a](https://github.com/ionic-team/ionic/commit/86ab77a6e2cb124510c244110fc78a4bc0654cd1)), closes [#20469](https://github.com/ionic-team/ionic/issues/20469)
* **react:** do a better job matching up route to sync ([#20446](https://github.com/ionic-team/ionic/issues/20446)) ([c0aadd6](https://github.com/ionic-team/ionic/commit/c0aadd60077e5ba379959d93006e3a9c1418263c)), closes [#20363](https://github.com/ionic-team/ionic/issues/20363)
* **react:** do not remove pages when navigating between tabs ([#20431](https://github.com/ionic-team/ionic/issues/20431)) ([b6fbe98](https://github.com/ionic-team/ionic/commit/b6fbe98812fbab5ef9e0723802605c0711581dd2)), closes [#20398](https://github.com/ionic-team/ionic/issues/20398)
* **react:** icons with MD set should work in browser ([#20463](https://github.com/ionic-team/ionic/issues/20463)) ([82670fe](https://github.com/ionic-team/ionic/commit/82670fe4d0592451cbc243b3008beb3f8f483c30))
* **react:** update paths of tab buttons when href changes in ion buttons ([#20480](https://github.com/ionic-team/ionic/issues/20480)) ([45d03ba](https://github.com/ionic-team/ionic/commit/45d03baf981d0e10eb1fe689908532adef2ba31d)), closes [#20321](https://github.com/ionic-team/ionic/issues/20321)
* **searchbar:** properly align placeholder ([#20460](https://github.com/ionic-team/ionic/issues/20460)) ([4d6e15a](https://github.com/ionic-team/ionic/commit/4d6e15ab18fc894c3826b89362163256adc227f4)), closes [#20456](https://github.com/ionic-team/ionic/issues/20456)
* **segment:** border radius applies to indicator on ios ([#20541](https://github.com/ionic-team/ionic/issues/20541)) ([9b5854d](https://github.com/ionic-team/ionic/commit/9b5854d79712356f8a3772442c0cc412db09d5e0)), closes [#20539](https://github.com/ionic-team/ionic/issues/20539)
* **segment:** do not show ripple effect if disabled via config ([#20542](https://github.com/ionic-team/ionic/issues/20542)) ([7a461c5](https://github.com/ionic-team/ionic/commit/7a461c59c5d9a23de0bcdd53397f452d17251fd6)), closes [#20533](https://github.com/ionic-team/ionic/issues/20533)
* **segment:** inner div no longer interferes with click events ([#20522](https://github.com/ionic-team/ionic/issues/20522)) ([06b828b](https://github.com/ionic-team/ionic/commit/06b828b4ffb12b076b0805274f53fa158ee65c5a)), closes [#20381](https://github.com/ionic-team/ionic/issues/20381)
* **segment:** only emit ionChange when user releases pointer from screen ([#20495](https://github.com/ionic-team/ionic/issues/20495)) ([4d50064](https://github.com/ionic-team/ionic/commit/4d5006476479bc376d3bb4edad6db0b3ce806ef7)), closes [#20500](https://github.com/ionic-team/ionic/issues/20500) [#20257](https://github.com/ionic-team/ionic/issues/20257)
* **tab-bar:** update ios icon and label design to match native ([#20548](https://github.com/ionic-team/ionic/issues/20548)) ([34f8576](https://github.com/ionic-team/ionic/commit/34f8576b959d41896502e4f7b0c4240156e001eb))
# [5.0.0 Magnesium](https://github.com/ionic-team/ionic/compare/v4.11.10...v5.0.0) (2020-02-11)
Enjoy! :fire:
> We recommend updating to version `4.11.10` before updating to this version in order to see deprecation warnings related to your app [in the developer console](https://javascript.info/devtools).
Run the following commands based on your project type:
```
# for an angular app
npm i @ionic/angular@latest --save
# for a react app
npm i @ionic/react@latest --save
npm i @ionic/react-router@latest --save
npm i ionicons@latest --save
# for a stencil / vanilla JS app
npm i @ionic/core@latest --save
```
Then take a look at the [Breaking Changes](./BREAKING.md) file for API changes.
# [5.0.0-rc.5](https://github.com/ionic-team/ionic/compare/v5.0.0-rc.4...v5.0.0-rc.5) (2020-02-11)
### Bug Fixes
* **angular:** correct path for angular projects ([#20436](https://github.com/ionic-team/ionic/issues/20436)) ([fd9c7a9](https://github.com/ionic-team/ionic/commit/fd9c7a9601e7f21b74c76be1f8bb305bf008915c)), closes [#20435](https://github.com/ionic-team/ionic/issues/20435)
# [5.0.0-rc.4](https://github.com/ionic-team/ionic/compare/v5.0.0-rc.3...v5.0.0-rc.4) (2020-02-10)
### Bug Fixes
* **content:** only emit scroll events if enabled ([#20401](https://github.com/ionic-team/ionic/issues/20401)) ([fd1b44a](https://github.com/ionic-team/ionic/commit/fd1b44a40b741088e099f6538dd14caa0dc5540c))
* **header:** backdrop filter no longer distorts content with collapsible header ([#20388](https://github.com/ionic-team/ionic/issues/20388)) ([11d3945](https://github.com/ionic-team/ionic/commit/11d39457d56c091e9c41c180391d27464ae748b5)), closes [#20385](https://github.com/ionic-team/ionic/issues/20385)
* **item:** remove unneeded box-shadow CSS variable ([#20412](https://github.com/ionic-team/ionic/issues/20412)) ([a6764c4](https://github.com/ionic-team/ionic/commit/a6764c4724e1e7eed19a1902b563aeb61bfde38e)), closes [#20392](https://github.com/ionic-team/ionic/issues/20392)
* **label:** remove subpixel font-size to prevent visual glitches ([#20415](https://github.com/ionic-team/ionic/issues/20415)) ([3d6f287](https://github.com/ionic-team/ionic/commit/3d6f287d87bfaa0d81a34182baf38192e08fb3c1)), closes [#20407](https://github.com/ionic-team/ionic/issues/20407)
* **segment:** add activated class directly to segment button ([#20400](https://github.com/ionic-team/ionic/issues/20400)) ([e8886e9](https://github.com/ionic-team/ionic/commit/e8886e98f188044227bf5757892341cb598fdd27))
# [5.0.0-rc.3](https://github.com/ionic-team/ionic/compare/v5.0.0-rc.2...v5.0.0-rc.3) (2020-02-05)
### Bug Fixes
* **refresher:** ensure gesture does not interfere with item-sliding ([#20380](https://github.com/ionic-team/ionic/issues/20380)) ([8983c70](https://github.com/ionic-team/ionic/commit/8983c7006e54743873cd45ae1acdfa974d74547a)), closes [#20379](https://github.com/ionic-team/ionic/issues/20379)
* **refresher:** translate background content when refreshing ([#20378](https://github.com/ionic-team/ionic/issues/20378)) ([cf70916](https://github.com/ionic-team/ionic/commit/cf7091625ecb46c3f9882ae9eff5c946523fab75)), closes [#20377](https://github.com/ionic-team/ionic/issues/20377)
* **segment:** allow background to be set on iOS segment in a toolbar ([#20350](https://github.com/ionic-team/ionic/issues/20350)) ([0f31624](https://github.com/ionic-team/ionic/commit/0f31624104d195367df197eda9b8d6c5bda4cf75))
* **toolbar:** properly apply safe area and border ([#20375](https://github.com/ionic-team/ionic/issues/20375)) ([4971499](https://github.com/ionic-team/ionic/commit/4971499026fcee70a32cc9480302bb14a1bebcb7)), closes [#20354](https://github.com/ionic-team/ionic/issues/20354)
# [5.0.0-rc.2](https://github.com/ionic-team/ionic/compare/v5.0.0-rc.1...v5.0.0-rc.2) (2020-01-30)
### Bug Fixes
* **header:** fix race condition in collapsible header ([#20334](https://github.com/ionic-team/ionic/issues/20334)) ([215d55f](https://github.com/ionic-team/ionic/commit/215d55f1ebeb93988b513c5869faae14d1d51919))
* **ios:** translucent toolbar blur no longer obscures entering page toolbar content ([#20314](https://github.com/ionic-team/ionic/issues/20314)) ([e580b88](https://github.com/ionic-team/ionic/commit/e580b884770a086ee5d8acf61588ea50181786e6)), closes [#19158](https://github.com/ionic-team/ionic/issues/19158)
* **radio:** do not clear radio group value from radio ([#20343](https://github.com/ionic-team/ionic/issues/20343)) ([ff78e6e](https://github.com/ionic-team/ionic/commit/ff78e6e8ca8ae4dc2a6d401b377dd3977c48824a)), closes [#20323](https://github.com/ionic-team/ionic/issues/20323)
* **radio:** set default radio value if undefined ([#20329](https://github.com/ionic-team/ionic/issues/20329)) ([eb57723](https://github.com/ionic-team/ionic/commit/eb57723785ce5b05585bf48bf9c8ae1b62235ba2))
* **refresher:** add correct fallbacks for native refreshers ([#20333](https://github.com/ionic-team/ionic/issues/20333)) ([fd55427](https://github.com/ionic-team/ionic/commit/fd55427991e94488d86971aaa10acb13d7fa1c23))
* **refresher:** resolve undefined issues when updating component ([#20322](https://github.com/ionic-team/ionic/issues/20322)) ([59d8687](https://github.com/ionic-team/ionic/commit/59d86873a2ab913358b084bb05180ba176893a8f)), closes [#20320](https://github.com/ionic-team/ionic/issues/20320)
# [5.0.0-rc.1](https://github.com/ionic-team/ionic/compare/v4.11.10...v5.0.0-rc.1) (2020-01-27)
### Bug Fixes
* **components:** use proper colors for button states and add back input highlight ([#20278](https://github.com/ionic-team/ionic/issues/20278)) ([628db18](https://github.com/ionic-team/ionic/commit/628db18a97293731ecfee8e4d2f0d8c1cf672c96)), closes [#20276](https://github.com/ionic-team/ionic/issues/20276)
* **components:** inherit text indent in all components with text inherit ([#20300](https://github.com/ionic-team/ionic/issues/20300)) ([767b005](https://github.com/ionic-team/ionic/commit/767b005eacf00b640973bfb381de4dcedf083399)), closes [#17786](https://github.com/ionic-team/ionic/issues/17786)
* **content:** resolve height inheritance issues ([#20309](https://github.com/ionic-team/ionic/issues/20309)) ([09bef71](https://github.com/ionic-team/ionic/commit/09bef71ccd5a261233180bc19023bc562b905764)), closes [#20305](https://github.com/ionic-team/ionic/issues/20305)
* **picker:** include showBackdrop in interface ([#20301](https://github.com/ionic-team/ionic/issues/20301)) ([33186ba](https://github.com/ionic-team/ionic/commit/33186ba716de77edc92ae8e7d307f90fff8b8ed1)), closes [#18893](https://github.com/ionic-team/ionic/issues/18893)
* **react:** export proper types of animations and gestures ([#20311](https://github.com/ionic-team/ionic/issues/20311)) ([0034088](https://github.com/ionic-team/ionic/commit/00340885fb031d3dbc7c458fddeed9d28a2deda4))
* **refresher:** update animation for dashed property values ([#20310](https://github.com/ionic-team/ionic/issues/20310)) ([44211c1](https://github.com/ionic-team/ionic/commit/44211c11ee929b9966d5e67e99fb6a495380432c))
* **toast:** inherit color in cancel button for a toast with color ([#20299](https://github.com/ionic-team/ionic/issues/20299)) ([7b44ae2](https://github.com/ionic-team/ionic/commit/7b44ae2a400bb0c0616012e9c42bfc67edbfc793)), closes [#20139](https://github.com/ionic-team/ionic/issues/20139)
## [4.11.10](https://github.com/ionic-team/ionic/compare/v4.11.9...v4.11.10) (2020-01-24)
### Bug Fixes
* **input:** revert previous type change ([db1fd1d](https://github.com/ionic-team/ionic/commit/db1fd1d72a8a0ade824ad2309d1adb2953731f37))
# [5.0.0-rc.0](https://github.com/ionic-team/ionic/compare/v5.0.0-beta.6...v5.0.0-rc.0) (2020-01-23)
Release Candidate is here! :tada:
# [5.0.0-beta.6](https://github.com/ionic-team/ionic/compare/v4.11.9...v5.0.0-beta.6) (2020-01-23)
### Bug Fixes
* **animation:** add property conversions for CSS Animations ([#20252](https://github.com/ionic-team/ionic/issues/20252)), fixes [#20251](https://github.com/ionic-team/ionic/issues/20251) ([32a7401](https://github.com/ionic-team/ionic/commit/32a7401576a9c91fdee66d2cede06b6a16884d35))
* **content:** set min-height to allow for sticky headers ([#20265](https://github.com/ionic-team/ionic/issues/20252)), fixes [#20258](https://github.com/ionic-team/ionic/issues/20258) ([e613f63](https://github.com/ionic-team/ionic/commit/e613f63590f3d6a4fa4f3a361811224394ba0be2))
* **modal:** card-style modal now opens at full width on larger devices ([#20256](https://github.com/ionic-team/ionic/issues/20256)), fixes [#20255](https://github.com/ionic-team/ionic/issues/20255) ([443cbd9](https://github.com/ionic-team/ionic/commit/443cbd9eb273767d8405b6a05ffabee037e9f3b7))
* **segment:** clicking disabled button no longer adds ripple to active button ([#20254](https://github.com/ionic-team/ionic/issues/20254)), fixes [#20253](https://github.com/ionic-team/ionic/issues/20253) ([f896821](https://github.com/ionic-team/ionic/commit/f8968217533ff60948047510064d2f15d01c249c))
### Features
* **components:** improve button states and add new css properties ([#19440](https://github.com/ionic-team/ionic/issues/19440)) ([9415929](https://github.com/ionic-team/ionic/commit/94159291b27ddf1a859c8f3f87a0d6e54a8b5f13)), closes [#20213](https://github.com/ionic-team/ionic/issues/20213) [#19965](https://github.com/ionic-team/ionic/issues/19965)
* **react:** add Ionic Animations wrapper (experimental) ([#20273](https://github.com/ionic-team/ionic/issues/20273)) ([b59d764](https://github.com/ionic-team/ionic/commit/b59d7647fd6f9a645a4ec0fe9aca526ea5eda4e0))
* **segment-button:** add --indicator-height property to segment button ([#19653](https://github.com/ionic-team/ionic/issues/19653)) ([d76a503](https://github.com/ionic-team/ionic/commit/d76a5031c4c96b5fdf691a56ed61d3dcc4e4dafb))
### BREAKING CHANGES
> We recommend updating to the latest version of 4.x before trying out version 5 in order to see deprecation warnings related to your app [in the developer console](https://javascript.info/devtools).
*Activated Class*
The `activated` class that is automatically added to buttons on press has been renamed to `ion-activated`. This will be more consistent with our `ion-focused` class we add and also will reduce conflicts with users' CSS.
*CSS Variables*
The `--background-hover`, `--background-focused` and `--background-activated` CSS variables on components that render native buttons will now have an opacity automatically set. If you are setting any of these like the following:
```
--background-hover: rgba(44, 44, 44, 0.08);
```
You will likely not see a hover state anymore. It should be updated to only set the desired color:
```
--background-hover: rgba(44, 44, 44);
```
If the opacity desired is something other than what the spec asks for, use:
```
--background-hover: rgba(44, 44, 44);
--background-hover-opacity: 1;
```
## [4.11.9](https://github.com/ionic-team/ionic/compare/v4.11.8...v4.11.9) (2020-01-23)
### Bug Fixes
* **core:** updating type of input value to accept numbers, fixes [#20173](https://github.com/ionic-team/ionic/issues/20173) ([#20267](https://github.com/ionic-team/ionic/issues/20267)) ([7080205](https://github.com/ionic-team/ionic/commit/708020551f9c51ca3b32d7b49bf4572db3dda12e))
* **react:** adding missing overlay component events, fixes [#19923](https://github.com/ionic-team/ionic/issues/19923) ([#20266](https://github.com/ionic-team/ionic/issues/20266)) ([ec6a8dd](https://github.com/ionic-team/ionic/commit/ec6a8dd86f3854edba367f79a6ebac7d60eed839))
* **react:** Don't render overlay children if isOpen is false, fixes [#20225](https://github.com/ionic-team/ionic/issues/20225) ([#20226](https://github.com/ionic-team/ionic/issues/20226)) ([aff9612](https://github.com/ionic-team/ionic/commit/aff9612d1197dca48eab6eff9d749032c380cf82))
* **react:** re attach props on update, fixes 20192 ([#20228](https://github.com/ionic-team/ionic/issues/20228)) ([9e35ebe](https://github.com/ionic-team/ionic/commit/9e35ebed4a1590ef2521f5f8c393bdd9dea32a04))
* **react:** remove leaving view when routerdirection is back, fixes [#20124](https://github.com/ionic-team/ionic/issues/20124) ([#20268](https://github.com/ionic-team/ionic/issues/20268)) ([63d4e87](https://github.com/ionic-team/ionic/commit/63d4e877fb18c90d70c4cbd5f66ffccb8ee6489c))
* **react:** support routes without a path for notfound routes, fixes [#20259](https://github.com/ionic-team/ionic/issues/20259) ([#20261](https://github.com/ionic-team/ionic/issues/20261)) ([2f8c13b](https://github.com/ionic-team/ionic/commit/2f8c13b6960f9bcfb941c36fa6e1742b96f80ba9))
* **react:** update icon types to be a string as well, fixes [#20229](https://github.com/ionic-team/ionic/issues/20229) ([#20230](https://github.com/ionic-team/ionic/issues/20230)) ([1411d8a](https://github.com/ionic-team/ionic/commit/1411d8a173bfefd7db5241218fd5641b7e9da823))
# [5.0.0-beta.5](https://github.com/ionic-team/ionic/compare/v4.11.8...v5.0.0-beta.5) (2020-01-17)
### Bug Fixes
* **action-sheet:** allow scrollable action sheet with many options ([#20145](https://github.com/ionic-team/ionic/issues/20145)) ([53fad97](https://github.com/ionic-team/ionic/commit/53fad978c5a57efe34671db6cbede49c4a5af866)), closes [#17311](https://github.com/ionic-team/ionic/issues/17311)
* **card:** remove top padding of content in iOS if under header ([#20223](https://github.com/ionic-team/ionic/issues/20223)) ([9232f16](https://github.com/ionic-team/ionic/commit/9232f16eea8163c1ac0797abd9b6e92da44bacb1))
* **content:** scroll-content div now takes up full height of container ([#20194](https://github.com/ionic-team/ionic/issues/20194)) ([9d63b41](https://github.com/ionic-team/ionic/commit/9d63b41a5296688524c64f828f92090d73d6b556)), closes [#20185](https://github.com/ionic-team/ionic/issues/20185)
* **header:** header opacity properly resets on collapsible titles ([#20202](https://github.com/ionic-team/ionic/issues/20202)) ([8e11f79](https://github.com/ionic-team/ionic/commit/8e11f79fcca94a9c50ccc7e18e0fe44ef9764b1d))
* **modal:** prevent double dismiss via gesture and backdrop tap on card-style modal ([#20203](https://github.com/ionic-team/ionic/issues/20203)) ([5b0400d](https://github.com/ionic-team/ionic/commit/5b0400d5afec308861408967a5f61c9b93af0004))
* **picker:** pick correct option at low velocities ([#19660](https://github.com/ionic-team/ionic/issues/19660)) ([39d1262](https://github.com/ionic-team/ionic/commit/39d12629dbc12e4a86037b09350ec1c49ed6e2e4)), closes [#19659](https://github.com/ionic-team/ionic/issues/19659)
* **react:** updating icon type and add caret to internal icons ([#20216](https://github.com/ionic-team/ionic/issues/20216)) ([dc78f98](https://github.com/ionic-team/ionic/commit/dc78f981531960791a425b3b1b81d45d5065a263))
* **ssr:** add reflect content-id attribute to applicable properties ([#20169](https://github.com/ionic-team/ionic/issues/20169)) ([3aa47e6](https://github.com/ionic-team/ionic/commit/3aa47e6e2f18c3a07f2c0560a0946571e8e6815d))
### Code Refactoring
* removed checked/selected properties in favor of setting value on parent ([#19449](https://github.com/ionic-team/ionic/issues/19449)) ([a5229d9](https://github.com/ionic-team/ionic/commit/a5229d90ca2a608e8bf4db0c8f71c86d481dd649))
### Features
* **datetime:** add custom timezone display property ([#19519](https://github.com/ionic-team/ionic/issues/19519)) ([7b032c5](https://github.com/ionic-team/ionic/commit/7b032c5e9b396fcfb0b0e313aff1bebcbc43305e)), closes [#19401](https://github.com/ionic-team/ionic/issues/19401)
* **segment:** update design for iOS and MD spec ([#19036](https://github.com/ionic-team/ionic/issues/19036)) ([dc66ce4](https://github.com/ionic-team/ionic/commit/dc66ce48e1f210ca57cecae5c89e5dc3b7e95de5)), closes [#18663](https://github.com/ionic-team/ionic/issues/18663)
* **toast:** expose shadow parts ([#20146](https://github.com/ionic-team/ionic/issues/20146)) ([3b4988a](https://github.com/ionic-team/ionic/commit/3b4988aa60dc6d31e1bc3367cb8f5e8d85710ac6))
### BREAKING CHANGES
> We recommend updating to the latest version of 4.x before trying out version 5 in order to see deprecation warnings related to your app [in the developer console](https://javascript.info/devtools).
* The following components have been updated to remove the checked or selected properties:
- Radio
- Segment Button
- Select
Developers should set the value property on the respective parent components in order to managed checked/selected status. See the [Breaking Changes](./BREAKING.md) document for updated usage examples.
* Controller components have been removed. Developers should user their respective imports instead. This only affects vanilla JS applications.
Before:
```html
<ion-modal-controller></ion-modal-controller>
```
After:
```javascript
import { modalController } from '@ionic/core';
```
## [4.11.8](https://github.com/ionic-team/ionic/compare/v4.11.7...v4.11.8) (2020-01-13)
* **react:** add missing react memory router ([8a5aba2](https://github.com/ionic-team/ionic/commit/8a5aba206865ce2af7f8bb85f4e7cd8dec37831d))
* **react:** fixing type of icon in ToastOptions, ActionSheetOptions, fixes [#20100](https://github.com/ionic-team/ionic/issues/20100) ([857bab6](https://github.com/ionic-team/ionic/commit/857bab66419a851c6d189cd1456cd67c1c2d934c))
* **react:** supporting ios and md props on icons ([#20170](https://github.com/ionic-team/ionic/issues/20170)) ([676cc19](https://github.com/ionic-team/ionic/commit/676cc19b89cd6374346aaac9cc3292872c7148fa))
# [5.0.0-beta.4](https://github.com/ionic-team/ionic/compare/v5.0.0-beta.3...v5.0.0-beta.4) (2020-01-06)
### Features
* **refresher:** add MD native refresher ([#20096](https://github.com/ionic-team/ionic/issues/20096)) ([5b81bdf](https://github.com/ionic-team/ionic/commit/5b81bdfcf18ed182bde14bbea4957b49ea886322)), closes [#17316](https://github.com/ionic-team/ionic/issues/17316)
# [5.0.0-beta.3](https://github.com/ionic-team/ionic/compare/v4.11.7...v5.0.0-beta.3) (2020-01-03)
### Bug Fixes
* **animation:** support css animation on older devices ([#20020](https://github.com/ionic-team/ionic/issues/20020)) ([49c394c](https://github.com/ionic-team/ionic/commit/49c394c3d335795fd100f54a5b29db009d413dff)), closes [#20017](https://github.com/ionic-team/ionic/issues/20017)
* **icons:** fix the ellipsis fill in ionicons ([#20137](https://github.com/ionic-team/ionic/issues/20137)) ([9318d24](https://github.com/ionic-team/ionic/commit/9318d2418ec144bbce4a3b7ead33cf099d6ec25b))
* **modal:** account for safe area on devices with a notch ([#20072](https://github.com/ionic-team/ionic/issues/20072)) ([1cabb53](https://github.com/ionic-team/ionic/commit/1cabb5365097d0675447a36223583824a58a140c))
* **react:** fire lifecycle events on initial render, fixes [#20071](https://github.com/ionic-team/ionic/issues/20071) ([2dcf3ee](https://github.com/ionic-team/ionic/commit/2dcf3ee7b570be73be35c52f03ccfa09baf5d830))
### Code Refactoring
* **searchbar:** set inputmode default to undefined ([#20080](https://github.com/ionic-team/ionic/issues/20080)) ([6612604](https://github.com/ionic-team/ionic/commit/6612604733ac1b3e46546625f24ef6efa5be1538)), closes [#20074](https://github.com/ionic-team/ionic/issues/20074)
### Features
* **angular:** angular 9 support ([#19515](https://github.com/ionic-team/ionic/issues/19515)) ([2344d0b](https://github.com/ionic-team/ionic/commit/2344d0b272105e368c00ef611f28909215162f7c))
* **checkbox:** add --checkmark-width variable ([#19933](https://github.com/ionic-team/ionic/issues/19933)) ([c32a7bc](https://github.com/ionic-team/ionic/commit/c32a7bcd202993056923857a5d9eed14f5be8580)), closes [#16803](https://github.com/ionic-team/ionic/issues/16803)
* **radio:** add --border-radius and --inner-border-radius variables ([#20140](https://github.com/ionic-team/ionic/issues/20140)) ([a01c102](https://github.com/ionic-team/ionic/commit/a01c10267e18a48f30af2f552c556d31dad582e9))
* **refresher:** add iOS native refresher ([#20037](https://github.com/ionic-team/ionic/issues/20037)) ([04e7c03](https://github.com/ionic-team/ionic/commit/04e7c031326ec551531af291ef1a03878d168378)), closes [#18664](https://github.com/ionic-team/ionic/issues/18664)
* **toggle:** add --border-radius and --handle-border-radius variables ([#20141](https://github.com/ionic-team/ionic/issues/20141)) ([02a46a1](https://github.com/ionic-team/ionic/commit/02a46a1007dde820cb158d34d4e3f243c07251dc))
### BREAKING CHANGES
> We recommend updating to the latest version of 4.x before trying out version 5 in order to see deprecation warnings related to your app [in the developer console](https://javascript.info/devtools).
* **searchbar:** The `inputmode` property for `ion-searchbar` now defaults to `undefined`. To get the old behavior, set the `inputmode` property to `"search"`.
## [4.11.7](https://github.com/ionic-team/ionic/compare/v4.11.6...v4.11.7) (2019-12-12)
### Bug Fixes
* **react:** fire lifecycle events on initial render, fixes [#20071](https://github.com/ionic-team/ionic/issues/20071) ([9ea75eb](https://github.com/ionic-team/ionic/commit/9ea75ebec7b1367fc0e319fe61c1f42516357e10))
# [5.0.0-beta.2](https://github.com/ionic-team/ionic/compare/v5.0.0-beta.1...v5.0.0-beta.2) (2019-12-11)
### Bug Fixes
* **animation:** convert hyphenated properties to camel case when using Web Animations ([#20059](https://github.com/ionic-team/ionic/issues/20059)) ([56f67bd](https://github.com/ionic-team/ionic/commit/56f67bd9a5c8c81768e310560b2605e44bf7a9f0)), closes [#20058](https://github.com/ionic-team/ionic/issues/20058)
* **animation:** properly update Web Animation object ([#19964](https://github.com/ionic-team/ionic/issues/19964)) ([e766194](https://github.com/ionic-team/ionic/commit/e76619478c3c49469fcc22e264cc831d498abf8d))
* **picker:** pass selected value to handler on dismiss ([#20042](https://github.com/ionic-team/ionic/issues/20042)) ([6e0b9c4](https://github.com/ionic-team/ionic/commit/6e0b9c45489889266620ee2ca38c33fdf8ce3f3b)), closes [#20036](https://github.com/ionic-team/ionic/issues/20036)
* **tabs:** preserve route navigation extras when changing tabs ([#18493](https://github.com/ionic-team/ionic/issues/18493)) ([4c8f32f](https://github.com/ionic-team/ionic/commit/4c8f32fae99db4022aa9dc75187e2f161e8e678e)), closes [#18717](https://github.com/ionic-team/ionic/issues/18717)
* **title:** add correct safe area to large title nav transition ([#20029](https://github.com/ionic-team/ionic/issues/20029)) ([300d543](https://github.com/ionic-team/ionic/commit/300d54356df925bb94f22b6805e48c88d1e56a26)), closes [#20028](https://github.com/ionic-team/ionic/issues/20028)
### Features
* **modal:** add card-style presentation with swipe to close gesture ([#19428](https://github.com/ionic-team/ionic/issues/19428)) ([b3b3312](https://github.com/ionic-team/ionic/commit/b3b33127115bb966980a1288a0005dfb09306881)), closes [#18660](https://github.com/ionic-team/ionic/issues/18660)
## [4.11.6](https://github.com/ionic-team/ionic/compare/v4.11.5...v4.11.6) (2019-12-11)
### Bug Fixes
* **react:** don't show back button when not appropriate ([684293d](https://github.com/ionic-team/ionic/commit/684293ddbf1ad4edce590d56f7ff66fcd6c817a5))
* **react:** first render performance improvements ([1c7d1e5](https://github.com/ionic-team/ionic/commit/1c7d1e5cf1ad7e53ebbee2566e8fa89f567f7fb5))
* **react:** fix refs for controllers, overlays, ionpage, and ionrouteroutlet, fixes [#19924](https://github.com/ionic-team/ionic/issues/19924) ([#20012](https://github.com/ionic-team/ionic/issues/20012)) ([eef55bb](https://github.com/ionic-team/ionic/commit/eef55bb0072a9e54b1fd7d1c8c69e7fd43b2a5c5))
* **react:** support for 'root' router direction, fixes [#19982](https://github.com/ionic-team/ionic/issues/19982) ([#20052](https://github.com/ionic-team/ionic/issues/20052)) ([e116712](https://github.com/ionic-team/ionic/commit/e1167122758b23221935e897bcd65839b75c59aa))
* **react:** support navigating to same page and route updates in IonRouterOutlet, fixes [#19891](https://github.com/ionic-team/ionic/issues/19891), [#19892](https://github.com/ionic-team/ionic/issues/19892), [#19986](https://github.com/ionic-team/ionic/issues/19986) ([f9bf8db](https://github.com/ionic-team/ionic/commit/f9bf8dbe6f952ee53b6b213a4c0d043d25f49b93))
### Upgrade Note
If you run into a "Property 'translate' is missing in type" error building after updating to 4.11.6, update your React Typings library to the latest:
npm i @types/react@latest @types/react-dom@latest
# [5.0.0-beta.1](https://github.com/ionic-team/ionic/compare/v5.0.0-beta.0...v5.0.0-beta.1) (2019-11-20)
### Bug Fixes
* **animation:** track correctly when updating CSS Animation ([#19813](https://github.com/ionic-team/ionic/issues/19813)) ([7bd4412](https://github.com/ionic-team/ionic/commit/7bd44128895b9fa4992142c0cc30cf75092cb794))
* **card:** update background to use the same as item ([#19602](https://github.com/ionic-team/ionic/issues/19602)) ([1a8b7a4](https://github.com/ionic-team/ionic/commit/1a8b7a4559860b3efa4778a78c905e30f18587bf))
* **content:** set fixed content to position absolute ([#19867](https://github.com/ionic-team/ionic/issues/19867)) ([fce3e24](https://github.com/ionic-team/ionic/commit/fce3e24600be6f04b285cda62fe2f21c49d809e2)), closes [#17754](https://github.com/ionic-team/ionic/issues/17754)
* **gesture:** release gesture when disabling ([#19855](https://github.com/ionic-team/ionic/issues/19855)) ([21484f1](https://github.com/ionic-team/ionic/commit/21484f1f3a9ebe46096c979fe3f2035892a53a62)), closes [#19848](https://github.com/ionic-team/ionic/issues/19848)
* **header:** avoid flicker on collapsible header load ([#19682](https://github.com/ionic-team/ionic/issues/19682)) ([0a7aae2](https://github.com/ionic-team/ionic/commit/0a7aae28a7eb0270cdcd100933c01850403b66db))
* **header:** avoid flicker when collapsing ([#19850](https://github.com/ionic-team/ionic/issues/19850)) ([a3666dd](https://github.com/ionic-team/ionic/commit/a3666ddf0ccc44c696121a8d6107015dbe7aeabb)), closes [#19839](https://github.com/ionic-team/ionic/issues/19839)
* **header:** support collapsible header with multiple toolbars ([#19909](https://github.com/ionic-team/ionic/issues/19909)) ([fc4bb2d](https://github.com/ionic-team/ionic/commit/fc4bb2db5c5715841347135bdfa1bf66718d647d))
* **header:** translucent toolbars now work with collapsible header ([#19774](https://github.com/ionic-team/ionic/issues/19774)) ([b642b53](https://github.com/ionic-team/ionic/commit/b642b532e8846042f1317dc936191d0934b23945)), closes [#19773](https://github.com/ionic-team/ionic/issues/19773)
* **title:** only animate large title if back button is in start slot ([#19846](https://github.com/ionic-team/ionic/issues/19846)) ([cace1b3](https://github.com/ionic-team/ionic/commit/cace1b357e5acd54d49f2b662ecee5de90add708)), closes [#19840](https://github.com/ionic-team/ionic/issues/19840)
* **nav-params:** set generic type on navigation parameters get() ([#19195](https://github.com/ionic-team/ionic/issues/19195)) ([504051d](https://github.com/ionic-team/ionic/commit/504051d709c8afe08d588747866d2ee924baf804))
* **picker:** pass data and role to dismiss ([#19787](https://github.com/ionic-team/ionic/issues/19787)) ([7988720](https://github.com/ionic-team/ionic/commit/7988720b1cf46a651d9c140f0fe95726d3feb48c)), closes [#18454](https://github.com/ionic-team/ionic/issues/18454)
* **searchbar:** use back button config value for cancel icon ([#19353](https://github.com/ionic-team/ionic/issues/19353)) ([3d6f3b9](https://github.com/ionic-team/ionic/commit/ed6f3b9f3f42ef85f3f2d083fa7fe37a69b491c8))
* **textarea:** remove padding from textarea placeholder ([#19694](https://github.com/ionic-team/ionic/issues/19694)) ([f63d37a](https://github.com/ionic-team/ionic/commit/f63d37a4c506801a19b9bf6e5ef05d415d680b0c)), closes [#19616](https://github.com/ionic-team/ionic/issues/19616)
* **toast:** call button handler on cancel ([#19793](https://github.com/ionic-team/ionic/issues/19793)) ([420aa66](https://github.com/ionic-team/ionic/commit/420aa6639214e7d2e7b7413e699ace3d7fd35e40)), closes [#19791](https://github.com/ionic-team/ionic/issues/19791)
### Features
* **animation:** animation identifiers ([#19771](https://github.com/ionic-team/ionic/issues/19771)) ([7d41715](https://github.com/ionic-team/ionic/commit/7d417154c5f1ba89e0a30084807ff7e164dd6eba)), closes [#19550](https://github.com/ionic-team/ionic/issues/19550)
* **animation:** cubic-bezier easing conversion utility (experimental) ([#19788](https://github.com/ionic-team/ionic/issues/19788)) ([96a5e60](https://github.com/ionic-team/ionic/commit/96a5e600e563489d93a26d5956d210f246f6fea5)), closes [#19789](https://github.com/ionic-team/ionic/issues/19789)
* **alert:** add support for textarea inputs ([#16851](https://github.com/ionic-team/ionic/issues/16851)) ([b28cf02](https://github.com/ionic-team/ionic/commit/b28cf02ef3979c844c498a8e30ee977937984828)), closes [#14153](https://github.com/ionic-team/ionic/issues/14153)
* **angular:** expose Ionic Animations via AnimationController ([#19745](https://github.com/ionic-team/ionic/issues/19745)) ([67a7e23](https://github.com/ionic-team/ionic/commit/67a7e232b9058620653feec5ed99e0ebf22b6620))
* **angular:** expose Ionic Gestures via GestureController ([#19864](https://github.com/ionic-team/ionic/issues/19864)) ([48a7662](https://github.com/ionic-team/ionic/commit/48a766246d08170c709345bba235275eef0bd020))
* **searchbar:** add --box-shadow variable to style searchbar input ([#19838](https://github.com/ionic-team/ionic/issues/19838)) ([1ab7066](https://github.com/ionic-team/ionic/commit/1ab7066aa085bc0185a6dd3d162439f7f82415fa))
* **select:** add --placeholder-opacity and --placeholder-color, expose shadow parts ([#19893](https://github.com/ionic-team/ionic/issues/19893)) ([bef0f53](https://github.com/ionic-team/ionic/commit/bef0f53d0dcb15c58221c2dec8c4c274d3b5c77e)), closes [#17446](https://github.com/ionic-team/ionic/issues/17446)
* **split-pane:** convert to shadow component, add width, max-width, and min-width vars ([#19754](https://github.com/ionic-team/ionic/issues/19754)) ([d80f455](https://github.com/ionic-team/ionic/commit/d80f45516d5dca62b77db1773206ef274d42f3ef)), closes [#17088](https://github.com/ionic-team/ionic/issues/17088)
### Breaking Changes
> We recommend updating to the latest version of 4.x before trying out version 5 in order to see deprecation warnings related to your app [in the developer console](https://javascript.info/devtools).
* **back-button:** convert back button to shadow ([#19411](https://github.com/ionic-team/ionic/pull/19411)) ([0d40d3f](https://github.com/ionic-team/ionic/commit/0d40d3f3b72aac7932ac71e6573d8bbb65a01515))
* **ionicons:** update to Ionicons v5. See https://ionicons.com for more information. ([#19670](https://github.com/ionic-team/ionic/pull/19670)) ([69e10de](https://github.com/ionic-team/ionic/commit/69e10de718dcba4d43e82bd37aeacd2585dd9a79))
* **list-header:** redesign list header to match latest iOS spec ([#19915](https://github.com/ionic-team/ionic/issues/19915)) ([5bbb95f](https://github.com/ionic-team/ionic/commit/5bbb95fae1e371021d6a0edc17fbb021a598b285))
* **split-pane:** convert split-pane to shadow ([#19754](https://github.com/ionic-team/ionic/issues/19754)) ([d80f455](https://github.com/ionic-team/ionic/commit/d80f45516d5dca62b77db1773206ef274d42f3ef))
## [4.11.5](https://github.com/ionic-team/ionic/compare/v4.11.0...v4.11.5) (2019-11-14)
### Bug Fixes
* **react:** improved lifecycle hooks to deal with stale closures, fixes [#19873](https://github.com/ionic-team/ionic/issues/19873) ([#19874](https://github.com/ionic-team/ionic/issues/19874)) ([5ff786a](https://github.com/ionic-team/ionic/commit/5ff786a23d5aa32281bbf5daaa7f8156de39caca))
## [4.11.4](https://github.com/ionic-team/ionic/compare/v4.11.1...v4.11.4) (2019-11-07)
@@ -72,7 +681,7 @@
### Breaking Changes
> We recommend updating to the latest version of 4.x before trying out version 5 in order to see deprecation warnings related to your app in the console.
> We recommend updating to the latest version of 4.x before trying out version 5 in order to see deprecation warnings related to your app [in the developer console](https://javascript.info/devtools).
* **all:** mode is now cascaded from parent to child component. If this is not desired set a different mode on the child component. ([#19369](https://github.com/ionic-team/ionic/issues/19369)) ([55462d7](https://github.com/ionic-team/ionic/commit/55462d7a0935f57b6855f9bd1bf788bfcf532bc3))
* **anchor:** remove `ion-anchor`, use `ion-router-link` instead. ([#18935](https://github.com/ionic-team/ionic/issues/18935)) ([e7cd197](https://github.com/ionic-team/ionic/commit/e7cd197af79cdf87f04bc769e0367c7e93c0aa0b))

View File

@@ -507,7 +507,7 @@ _In the following examples, `{breakpoint}` refers to the optional screen breakpo
- `push-{breakpoint}-{value}` attributes have been renamed to `push-{breakpoint}=“{value}”`
- `pull-{breakpoint}-{value}` attributes have been renamed to `pull-{breakpoint}=“{value}”`
Customizing the padding and width of a grid should now be done with CSS variables. For more information, see [Grid Layout](https://github.com/ionic-team/ionic-docs/blob/master/src/content/layout/grid.md).
Customizing the padding and width of a grid should now be done with CSS variables. For more information, see [Grid Layout](https://github.com/ionic-team/ionic-docs/blob/master/src/pages/layout/grid.md).
## Icon

View File

@@ -23,7 +23,7 @@ Ionic Angular specific building blocks on top of [@ionic/core](https://www.npmjs
1. Pull the latest from master
2. Build ionic/angular: `npm run build`
3. Run `npm link` from ionic/angular directory
3. Run `npm link` from `ionic/angular/dist` directory
4. Create a blank angular project
```

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/angular",
"version": "5.0.0-beta.0",
"version": "5.2.0",
"description": "Angular specific wrappers for @ionic/core",
"keywords": [
"ionic",
@@ -24,11 +24,11 @@
},
"homepage": "https://ionicframework.com/",
"scripts": {
"build": "npm run clean && npm run build.core && npm run build.ng && npm run clean-generated",
"build": "npm run clean && npm run build.ng && npm run build.core && npm run clean-generated",
"build.core": "node scripts/build-core.js",
"build.fesm": "rollup --config ./scripts/rollup.config.js",
"build.link": "npm run build && node scripts/link-copy.js",
"build.ng": "npm run build.es2015 && npm run build.es5",
"build.ng": "ng-packagr -p package.json",
"build.es2015": "ngc -p tsconfig.json && rollup --config ./scripts/rollup.config.js",
"build.es5": "ngc -p tsconfig.legacy.json && rollup --config ./scripts/rollup.config.legacy.js",
"clean": "node scripts/clean.js",
@@ -41,53 +41,46 @@
"tsc": "tsc -p .",
"validate": "npm i && npm run lint && npm run test && npm run build"
},
"module": "dist/fesm5.js",
"main": "dist/fesm5.cjs.js",
"types": "dist/core.d.ts",
"files": [
"dist/",
"css/"
],
"dependencies": {
"@ionic/core": "5.0.0-beta.0",
"@ionic/core": "5.2.0",
"tslib": "^1.9.3"
},
"peerDependencies": {
"@angular-devkit/core": "7.2.1 - 8",
"@angular-devkit/schematics": "7.2.1 - 8",
"@angular/core": "7.2.1 - 8",
"@angular/common": "7.2.1 - 8",
"@angular/forms": "7.2.1 - 8",
"@angular/router": "7.2.1 - 8",
"@angular/compiler": "7.2.1 - 8",
"@angular/compiler-cli": "7.2.1 - 8",
"@angular/platform-browser": "7.2.1 - 8",
"@angular/platform-browser-dynamic": "7.2.1 - 8",
"@angular/core": ">=8.2.7",
"@angular/forms": ">=8.2.7",
"@angular/router": ">=8.2.7",
"rxjs": ">=6.2.0",
"zone.js": ">=0.8.26"
},
"devDependencies": {
"@angular-devkit/core": "^7.2.1",
"@angular-devkit/schematics": "^7.2.1",
"@angular/common": "^7.2.1",
"@angular/compiler": "^7.2.1",
"@angular/compiler-cli": "^7.2.1",
"@angular/core": "^7.2.1",
"@angular/forms": "^7.2.1",
"@angular/platform-browser": "^7.2.1",
"@angular/platform-browser-dynamic": "^7.2.1",
"@angular/router": "^7.2.1",
"@types/node": "~12.0.12",
"@angular-devkit/core": "8.3.17",
"@angular-devkit/schematics": "8.3.17",
"@angular/common": "8.2.13",
"@angular/compiler": "8.2.13",
"@angular/compiler-cli": "8.2.13",
"@angular/core": "8.2.13",
"@angular/forms": "8.2.13",
"@angular/router": "8.2.13",
"@types/node": "12.12.5",
"fs-extra": "^7.0.0",
"glob": "^7.1.4",
"ng-packagr": "^9.1.5",
"rollup": "~1.17.0",
"rollup-plugin-node-resolve": "~5.2.0",
"rxjs": "^6.5.2",
"tsickle": "^0.34.0",
"tslint": "^5.12.1",
"tslint-ionic-rules": "0.0.21",
"typescript": "~3.2.2",
"zone.js": "~0.8.26"
"typescript": "3.4.5",
"zone.js": "^0.8.28"
},
"schematics": "./dist/schematics/collection.json"
"schematics": "./schematics/collection.json",
"ngPackage": {
"lib": {
"entryFile": "src/index.ts"
},
"whitelistedNonPeerDependencies": [
"@ionic/core"
]
}
}

View File

@@ -15,7 +15,7 @@ function copyIonicons() {
function copyCSS() {
const src = path.join(__dirname, '..', '..', 'core', 'css');
const dst = path.join(__dirname, '..', 'css');
const dst = path.join(__dirname, '..','dist', 'css');
fs.removeSync(dst);
fs.copySync(src, dst);

View File

@@ -16,7 +16,7 @@ export default {
},
plugins: [
resolve({
module: true,
mainFields: ['module']
})
]
};
};

View File

@@ -10,7 +10,7 @@ let didInitialize = false;
export const appInitialize = (config: Config, doc: Document, zone: NgZone) => {
return (): any => {
const win: IonicWindow | undefined = doc.defaultView as any;
if (win) {
if (win && typeof (window as any) !== 'undefined') {
if (didInitialize) {
console.warn('Ionic Angular was already initialized. Make sure IonicModule.forRoot() is just called once.');
}

View File

@@ -1,4 +1,4 @@
import { Directive, ElementRef, HostListener } from '@angular/core';
import { Directive, ElementRef, HostListener, Injector } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { ValueAccessor, setIonicClasses } from './value-accessor';
@@ -16,8 +16,8 @@ import { ValueAccessor, setIonicClasses } from './value-accessor';
})
export class BooleanValueAccessor extends ValueAccessor {
constructor(el: ElementRef) {
super(el);
constructor(injector: Injector, el: ElementRef) {
super(injector, el);
}
writeValue(value: any) {

View File

@@ -1,4 +1,4 @@
import { Directive, ElementRef, HostListener } from '@angular/core';
import { Directive, ElementRef, HostListener, Injector } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { ValueAccessor } from './value-accessor';
@@ -16,8 +16,8 @@ import { ValueAccessor } from './value-accessor';
})
export class NumericValueAccessor extends ValueAccessor {
constructor(el: ElementRef) {
super(el);
constructor(injector: Injector, el: ElementRef) {
super(injector, el);
}
@HostListener('ionChange', ['$event.target'])

View File

@@ -1,4 +1,4 @@
import { Directive, ElementRef, HostListener } from '@angular/core';
import { Directive, ElementRef, HostListener, Injector } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { ValueAccessor } from './value-accessor';
@@ -16,8 +16,8 @@ import { ValueAccessor } from './value-accessor';
})
export class RadioValueAccessor extends ValueAccessor {
constructor(el: ElementRef) {
super(el);
constructor(injector: Injector, el: ElementRef) {
super(injector, el);
}
@HostListener('ionSelect', ['$event.target'])

View File

@@ -1,4 +1,4 @@
import { Directive, ElementRef, HostListener } from '@angular/core';
import { Directive, ElementRef, HostListener, Injector } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { ValueAccessor } from './value-accessor';
@@ -16,8 +16,8 @@ import { ValueAccessor } from './value-accessor';
})
export class SelectValueAccessor extends ValueAccessor {
constructor(el: ElementRef) {
super(el);
constructor(injector: Injector, el: ElementRef) {
super(injector, el);
}
@HostListener('ionChange', ['$event.target'])

View File

@@ -1,4 +1,4 @@
import { Directive, ElementRef, HostListener } from '@angular/core';
import { Directive, ElementRef, HostListener, Injector } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { ValueAccessor } from './value-accessor';
@@ -16,8 +16,8 @@ import { ValueAccessor } from './value-accessor';
})
export class TextValueAccessor extends ValueAccessor {
constructor(el: ElementRef) {
super(el);
constructor(injector: Injector, el: ElementRef) {
super(injector, el);
}
@HostListener('ionChange', ['$event.target'])

View File

@@ -1,17 +1,26 @@
import { ElementRef, HostListener } from '@angular/core';
import { ControlValueAccessor } from '@angular/forms';
import { AfterViewInit, ElementRef, HostListener, Injector, OnDestroy, Type } from '@angular/core';
import { ControlValueAccessor, NgControl } from '@angular/forms';
import { Subscription } from 'rxjs';
import { raf } from '../../util/util';
export class ValueAccessor implements ControlValueAccessor {
export class ValueAccessor implements ControlValueAccessor, AfterViewInit, OnDestroy {
private onChange: (value: any) => void = () => {/**/};
private onTouched: () => void = () => {/**/};
protected lastValue: any;
private statusChanges?: Subscription;
constructor(protected el: ElementRef) {}
constructor(protected injector: Injector, protected el: ElementRef) {}
writeValue(value: any) {
/**
* TODO for Ionic 6:
* Change `value == null ? '' : value;`
* to `value`. This was a fix for IE9, but IE9
* is no longer supported; however, this change
* is potentially a breaking change
*/
this.el.nativeElement.value = this.lastValue = value == null ? '' : value;
setIonicClasses(this.el);
}
@@ -45,6 +54,45 @@ export class ValueAccessor implements ControlValueAccessor {
setDisabledState(isDisabled: boolean) {
this.el.nativeElement.disabled = isDisabled;
}
ngOnDestroy() {
if (this.statusChanges) {
this.statusChanges.unsubscribe();
}
}
ngAfterViewInit() {
const ngControl = this.injector.get<NgControl>(NgControl as Type<NgControl>);
// Listen for changes in validity, disabled, or pending states
if (ngControl.statusChanges) {
this.statusChanges = ngControl.statusChanges.subscribe(() => setIonicClasses(this.el));
}
/**
* TODO Remove this in favor of https://github.com/angular/angular/issues/10887
* whenever it is implemented. Currently, Ionic's form status classes
* do not react to changes when developers manually call
* Angular form control methods such as markAsTouched.
* This results in Ionic's form status classes being out
* of sync with the ng form status classes.
* This patches the methods to manually sync
* the classes until this feature is implemented in Angular.
*/
const formControl = ngControl.control;
if (formControl) {
const methodsToPatch = ['markAsTouched', 'markAllAsTouched', 'markAsUntouched', 'markAsDirty', 'markAsPristine'];
methodsToPatch.forEach(method => {
if (formControl[method]) {
const oldFn = formControl[method].bind(formControl);
formControl[method] = (...params) => {
oldFn(...params);
setIonicClasses(this.el);
};
}
});
}
}
}
export const setIonicClasses = (element: ElementRef) => {

View File

@@ -1,20 +1,24 @@
import { Directive, HostListener, Optional } from '@angular/core';
import { AnimationBuilder } from '@ionic/core';
import { Config } from '../../providers/config';
import { NavController } from '../../providers/nav-controller';
import { IonRouterOutlet } from './ion-router-outlet';
@Directive({
selector: 'ion-back-button',
inputs: ['defaultHref']
inputs: ['defaultHref', 'routerAnimation'],
})
export class IonBackButtonDelegate {
defaultHref: string | undefined | null;
routerAnimation?: AnimationBuilder;
constructor(
@Optional() private routerOutlet: IonRouterOutlet,
private navCtrl: NavController
private navCtrl: NavController,
private config: Config
) {}
/**
@@ -22,11 +26,14 @@ export class IonBackButtonDelegate {
*/
@HostListener('click', ['$event'])
onClick(ev: Event) {
const defaultHref = this.defaultHref || this.config.get('backButtonDefaultHref');
if (this.routerOutlet && this.routerOutlet.canGoBack()) {
this.navCtrl.setDirection('back', undefined, undefined, this.routerAnimation);
this.routerOutlet.pop();
ev.preventDefault();
} else if (this.defaultHref != null) {
this.navCtrl.navigateBack(this.defaultHref);
} else if (defaultHref != null) {
this.navCtrl.navigateBack(defaultHref, { animation: this.routerAnimation });
ev.preventDefault();
}
}

View File

@@ -4,6 +4,7 @@ import { ActivatedRoute, ChildrenOutletContexts, OutletContext, PRIMARY_OUTLET,
import { BehaviorSubject, Observable } from 'rxjs';
import { distinctUntilChanged, filter, switchMap } from 'rxjs/operators';
import { AnimationBuilder } from '../../';
import { Config } from '../../providers/config';
import { NavController } from '../../providers/nav-controller';
@@ -13,17 +14,18 @@ import { RouteView, getUrl } from './stack-utils';
@Directive({
selector: 'ion-router-outlet',
exportAs: 'outlet',
inputs: ['animated', 'swipeGesture']
inputs: ['animated', 'animation', 'swipeGesture']
})
export class IonRouterOutlet implements OnDestroy, OnInit {
nativeEl: HTMLIonRouterOutletElement;
private activated: ComponentRef<any> | null = null;
private activatedView: RouteView | null = null;
activatedView: RouteView | null = null;
private _activatedRoute: ActivatedRoute | null = null;
private _swipeGesture?: boolean;
private name: string;
private stackCtrl: StackController;
private nativeEl: HTMLIonRouterOutletElement;
// Maintain map of activated route proxies for each component instance
private proxyMap = new WeakMap<any, ActivatedRoute>();
@@ -37,6 +39,10 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
@Output('activate') activateEvents = new EventEmitter<any>();
@Output('deactivate') deactivateEvents = new EventEmitter<any>();
set animation(animation: AnimationBuilder) {
this.nativeEl.animation = animation;
}
set animated(animated: boolean) {
this.nativeEl.animated = animated;
}
@@ -241,6 +247,22 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
return active ? active.url : undefined;
}
/**
* Returns the RouteView of the active page of each stack.
* @internal
*/
getLastRouteView(stackId?: string): RouteView | undefined {
return this.stackCtrl.getLastUrl(stackId);
}
/**
* Returns the root view in the tab stack.
* @internal
*/
getRootView(stackId?: string): RouteView | undefined {
return this.stackCtrl.getRootUrl(stackId);
}
/**
* Returns the active stack ID. In the context of ion-tabs, it means the active tab.
*/
@@ -314,7 +336,7 @@ class OutletInjector implements Injector {
private route: ActivatedRoute,
private childContexts: ChildrenOutletContexts,
private parent: Injector
) {}
) { }
get(token: any, notFoundValue?: any): any {
if (token === ActivatedRoute) {

View File

@@ -42,15 +42,15 @@ import { StackEvent } from './stack-utils';
})
export class IonTabs {
@ViewChild('outlet', { read: IonRouterOutlet }) outlet: IonRouterOutlet;
@ContentChild(IonTabBar) tabBar: IonTabBar | undefined;
@ViewChild('outlet', { read: IonRouterOutlet, static: false }) outlet: IonRouterOutlet;
@ContentChild(IonTabBar, { static: false }) tabBar: IonTabBar | undefined;
@Output() ionTabsWillChange = new EventEmitter<{tab: string}>();
@Output() ionTabsDidChange = new EventEmitter<{tab: string}>();
@Output() ionTabsWillChange = new EventEmitter<{ tab: string }>();
@Output() ionTabsDidChange = new EventEmitter<{ tab: string }>();
constructor(
private navCtrl: NavController,
) {}
) { }
/**
* @internal
@@ -66,18 +66,59 @@ export class IonTabs {
}
}
/**
* When a tab button is clicked, there are several scenarios:
* 1. If the selected tab is currently active (the tab button has been clicked
* again), then it should go to the root view for that tab.
*
* a. Get the saved root view from the router outlet. If the saved root view
* matches the tabRootUrl, set the route view to this view including the
* navigation extras.
* b. If the saved root view from the router outlet does
* not match, navigate to the tabRootUrl. No navigation extras are
* included.
*
* 2. If the current tab tab is not currently selected, get the last route
* view from the router outlet.
*
* a. If the last route view exists, navigate to that view including any
* navigation extras
* b. If the last route view doesn't exist, then navigate
* to the default tabRootUrl
*/
@HostListener('ionTabButtonClick', ['$event.detail.tab'])
select(tab: string) {
const alreadySelected = this.outlet.getActiveStackId() === tab;
const href = `${this.outlet.tabsPrefix}/${tab}`;
const url = alreadySelected
? href
: this.outlet.getLastUrl(tab) || href;
const tabRootUrl = `${this.outlet.tabsPrefix}/${tab}`;
if (alreadySelected) {
const activeStackId = this.outlet.getActiveStackId();
const activeView = this.outlet.getLastRouteView(activeStackId);
return this.navCtrl.navigateRoot(url, {
animated: true,
animationDirection: 'back'
});
// If on root tab, do not navigate to root tab again
if (activeView.url === tabRootUrl) { return; }
const rootView = this.outlet.getRootView(tab);
const navigationExtras = rootView && tabRootUrl === rootView.url && rootView.savedExtras;
return this.navCtrl.navigateRoot(tabRootUrl, {
...(navigationExtras),
animated: true,
animationDirection: 'back',
});
} else {
const lastRoute = this.outlet.getLastRouteView(tab);
/**
* If there is a lastRoute, goto that, otherwise goto the fallback url of the
* selected tab
*/
const url = lastRoute && lastRoute.url || tabRootUrl;
const navigationExtras = lastRoute && lastRoute.savedExtras;
return this.navCtrl.navigateRoot(url, {
...(navigationExtras),
animated: true,
animationDirection: 'back',
});
}
}
getSelected(): string | undefined {

View File

@@ -1,11 +1,17 @@
import { ComponentFactoryResolver, Directive, ElementRef, Injector, ViewContainerRef } from '@angular/core';
import { AngularDelegate } from '../../providers/angular-delegate';
import { ProxyCmp, proxyOutputs } from '../proxies-utils';
@ProxyCmp({
inputs: ['animated', 'animation', 'root', 'rootParams', 'swipeGesture'],
methods: ['push', 'insert', 'insertPages', 'pop', 'popTo', 'popToRoot', 'removeIndex', 'setRoot', 'setPages', 'getActive', 'getByIndex', 'canGoBack', 'getPrevious']
})
@Directive({
selector: 'ion-nav',
selector: 'ion-nav'
})
export class NavDelegate {
protected el: HTMLElement;
constructor(
ref: ElementRef,
resolver: ComponentFactoryResolver,
@@ -13,6 +19,8 @@ export class NavDelegate {
angularDelegate: AngularDelegate,
location: ViewContainerRef
) {
this.el = ref.nativeElement;
ref.nativeElement.delegate = angularDelegate.create(resolver, injector, location);
proxyOutputs(this, this.el, ['ionNavDidChange' , 'ionNavWillChange' ]);
}
}

View File

@@ -1,20 +1,21 @@
import { LocationStrategy } from '@angular/common';
import { Directive, ElementRef, HostListener, Optional } from '@angular/core';
import { Router, RouterLink } from '@angular/router';
import { RouterDirection } from '@ionic/core';
import { AnimationBuilder, RouterDirection } from '@ionic/core';
import { Subscription } from 'rxjs';
import { NavController } from '../../providers/nav-controller';
@Directive({
selector: '[routerLink]',
inputs: ['routerDirection']
inputs: ['routerDirection', 'routerAnimation']
})
export class RouterLinkDelegate {
private subscription?: Subscription;
routerDirection: RouterDirection = 'forward';
routerAnimation?: AnimationBuilder;
constructor(
private locationStrategy: LocationStrategy,
@@ -50,7 +51,7 @@ export class RouterLinkDelegate {
*/
@HostListener('click', ['$event'])
onClick(ev: UIEvent) {
this.navCtrl.setDirection(this.routerDirection);
this.navCtrl.setDirection(this.routerDirection, undefined, undefined, this.routerAnimation);
ev.preventDefault();
}
}

View File

@@ -1,7 +1,7 @@
import { Location } from '@angular/common';
import { ComponentRef, NgZone } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { RouterDirection } from '@ionic/core';
import { AnimationBuilder, RouterDirection } from '@ionic/core';
import { bindLifecycleEvents } from '../../providers/angular-delegate';
import { NavController } from '../../providers/nav-controller';
@@ -52,7 +52,8 @@ export class StackController {
}
setActive(enteringView: RouteView): Promise<StackEvent> {
let { direction, animation } = this.navCtrl.consumeTransition();
const consumeResult = this.navCtrl.consumeTransition();
let { direction, animation, animationBuilder } = consumeResult;
const leavingView = this.activeView;
const tabSwitch = isTabSwitch(enteringView, leavingView);
if (tabSwitch) {
@@ -70,7 +71,7 @@ export class StackController {
if (router.getCurrentNavigation) {
currentNavigation = router.getCurrentNavigation();
// Angular < 7.2.0
// Angular < 7.2.0
} else if (
router.navigations &&
router.navigations.value
@@ -105,6 +106,31 @@ export class StackController {
enteringView.ref.changeDetectorRef.detectChanges();
}
/**
* If we are going back from a page that
* was presented using a custom animation
* we should default to using that
* unless the developer explicitly
* provided another animation.
*/
const customAnimation = enteringView.animationBuilder;
if (
animationBuilder === undefined &&
direction === 'back' &&
!tabSwitch &&
customAnimation !== undefined
) {
animationBuilder = customAnimation;
}
/**
* Save any custom animation so that navigating
* back will use this custom animation by default.
*/
if (animationBuilder !== undefined && leavingView) {
leavingView.animationBuilder = animationBuilder;
}
// Wait until previous transitions finish
return this.zone.runOutsideAngular(() => {
return this.wait(() => {
@@ -116,7 +142,7 @@ export class StackController {
// In case the enteringView is the same as the leavingPage we need to reattach()
enteringView.ref.changeDetectorRef.reattach();
return this.transition(enteringView, leavingView, animation, this.canGoBack(1), false)
return this.transition(enteringView, leavingView, animation, this.canGoBack(1), false, animationBuilder)
.then(() => cleanupAsync(enteringView, views, viewsSnapshot, this.location))
.then(() => ({
enteringView,
@@ -154,8 +180,8 @@ export class StackController {
url = primaryOutlet.route._routerState.snapshot.url;
}
}
return this.navCtrl.navigateBack(url, view.savedExtras).then(() => true);
const { animationBuilder } = this.navCtrl.consumeTransition();
return this.navCtrl.navigateBack(url, { ...view.savedExtras, animation: animationBuilder }).then(() => true);
});
}
@@ -191,6 +217,14 @@ export class StackController {
return views.length > 0 ? views[views.length - 1] : undefined;
}
/**
* @internal
*/
getRootUrl(stackId?: string) {
const views = this.getStack(stackId);
return views.length > 0 ? views[0] : undefined;
}
getActiveStackId(): string | undefined {
return this.activeView ? this.activeView.stackId : undefined;
}
@@ -217,7 +251,8 @@ export class StackController {
leavingView: RouteView | undefined,
direction: 'forward' | 'back' | undefined,
showGoBack: boolean,
progressAnimation: boolean
progressAnimation: boolean,
animationBuilder?: AnimationBuilder
) {
if (this.skipTransition) {
this.skipTransition = false;
@@ -242,7 +277,8 @@ export class StackController {
duration: direction === undefined ? 0 : undefined,
direction,
showGoBack,
progressAnimation
progressAnimation,
animationBuilder
});
}
}

View File

@@ -1,6 +1,6 @@
import { ComponentRef } from '@angular/core';
import { ActivatedRoute, NavigationExtras, Router } from '@angular/router';
import { NavDirection, RouterDirection } from '@ionic/core';
import { AnimationBuilder, NavDirection, RouterDirection } from '@ionic/core';
export const insertView = (views: RouteView[], view: RouteView, direction: RouterDirection) => {
if (direction === 'root') {
@@ -96,4 +96,5 @@ export interface RouteView {
savedData?: any;
savedExtras?: NavigationExtras;
unlistenEvents: () => void;
animationBuilder?: AnimationBuilder;
}

View File

@@ -2,7 +2,7 @@
import * as d from './proxies';
export const DIRECTIVES = [
d.IonApp,
d.IonApp,
d.IonAvatar,
d.IonBackButton,
d.IonBackdrop,

View File

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

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, Component, ContentChild, ElementRef, EmbeddedViewRef, IterableDiffer, IterableDiffers, NgZone, SimpleChanges, TrackByFunction } from '@angular/core';
import { Cell, CellType, FooterHeightFn, HeaderFn, HeaderHeightFn, ItemHeightFn } from '@ionic/core';
import { proxyInputs, proxyMethods } from '../proxies-utils';
import { ProxyCmp } from '../proxies-utils';
import { VirtualFooter } from './virtual-footer';
import { VirtualHeader } from './virtual-header';
@@ -112,6 +112,10 @@ export declare interface IonVirtualScroll {
'positionForItem': (index: number) => Promise<number>;
}
@ProxyCmp({
inputs: ['approxItemHeight', 'approxHeaderHeight', 'approxFooterHeight', 'headerFn', 'footerFn', 'items', 'itemHeight', 'headerHeight', 'footerHeight'],
methods: ['checkEnd', 'checkRange', 'positionForItem']
})
@Component({
selector: 'ion-virtual-scroll',
template: '<ng-content></ng-content>',
@@ -133,11 +137,11 @@ export class IonVirtualScroll {
private differ?: IterableDiffer<any>;
private el: HTMLIonVirtualScrollElement;
private refMap = new WeakMap<HTMLElement, EmbeddedViewRef<VirtualContext>> ();
private refMap = new WeakMap<HTMLElement, EmbeddedViewRef<VirtualContext>>();
@ContentChild(VirtualItem) itmTmp!: VirtualItem;
@ContentChild(VirtualHeader) hdrTmp!: VirtualHeader;
@ContentChild(VirtualFooter) ftrTmp!: VirtualFooter;
@ContentChild(VirtualItem, { static: false }) itmTmp!: VirtualItem;
@ContentChild(VirtualHeader, { static: false }) hdrTmp!: VirtualHeader;
@ContentChild(VirtualFooter, { static: false }) ftrTmp!: VirtualFooter;
constructor(
private z: NgZone,
@@ -215,21 +219,3 @@ const getElement = (view: EmbeddedViewRef<VirtualContext>): HTMLElement => {
}
throw new Error('virtual element was not created');
};
proxyInputs(IonVirtualScroll, [
'approxItemHeight',
'approxHeaderHeight',
'approxFooterHeight',
'headerFn',
'footerFn',
'items',
'itemHeight',
'headerHeight',
'footerHeight'
]);
proxyMethods(IonVirtualScroll, [
'checkEnd',
'checkRange',
'positionForItem'
]);

View File

@@ -36,5 +36,14 @@ export { GestureController } from './providers/gesture-controller';
// ROUTER STRATEGY
export { IonicRouteStrategy } from './util/ionic-router-reuse-strategy';
// TYPES
export * from './types/ionic-lifecycle-hooks';
// PACKAGE MODULE
export { IonicModule } from './ionic-module';
// UTILS
export { IonicSafeString, getPlatforms, isPlatform } from '@ionic/core';
// CORE TYPES
export { Animation, AnimationBuilder, AnimationCallbackOptions, AnimationDirection, AnimationFill, AnimationKeyFrames, AnimationLifecycle, Gesture, GestureConfig, GestureDetail, mdTransitionAnimation, iosTransitionAnimation } from '@ionic/core';

View File

@@ -126,7 +126,7 @@ const DECLARATIONS = [
imports: [CommonModule]
})
export class IonicModule {
static forRoot(config?: IonicConfig): ModuleWithProviders {
static forRoot(config?: IonicConfig): ModuleWithProviders<IonicModule> {
return {
ngModule: IonicModule,
providers: [

View File

@@ -33,7 +33,7 @@ export class Config {
}
set(key: keyof IonicConfig, value?: any) {
console.warn(`[DEPRECATION][Config]: The Config.set() method is deprecated and will be removed in the next major release.`);
console.warn(`[DEPRECATION][Config]: The Config.set() method is deprecated and will be removed in Ionic Framework 6.0. Please see https://ionicframework.com/docs/angular/config for alternatives.`);
const c = getConfig();
if (c) {
c.set(key, value);

View File

@@ -1,14 +1,24 @@
import { Injectable } from '@angular/core';
import { Injectable, NgZone } from '@angular/core';
import { Gesture, GestureConfig, createGesture } from '@ionic/core';
@Injectable({
providedIn: 'root',
})
export class GestureController {
constructor(private zone: NgZone) {}
/**
* Create a new gesture
*/
create(opts: GestureConfig): Gesture {
create(opts: GestureConfig, runInsideAngularZone = false): Gesture {
if (runInsideAngularZone) {
Object.getOwnPropertyNames(opts).forEach(key => {
if (typeof opts[key] === 'function') {
const fn = opts[key];
opts[key] = (...props) => this.zone.run(() => fn(...props));
}
});
}
return createGesture(opts);
}
}

View File

@@ -1,7 +1,7 @@
import { Location } from '@angular/common';
import { Injectable, Optional } from '@angular/core';
import { NavigationExtras, NavigationStart, Router, UrlSerializer, UrlTree } from '@angular/router';
import { NavDirection, RouterDirection } from '@ionic/core';
import { AnimationBuilder, NavDirection, RouterDirection } from '@ionic/core';
import { IonRouterOutlet } from '../directives/navigation/ion-router-outlet';
@@ -9,6 +9,7 @@ import { Platform } from './platform';
export interface AnimationOptions {
animated?: boolean;
animation?: AnimationBuilder;
animationDirection?: 'forward' | 'back';
}
@@ -22,6 +23,7 @@ export class NavController {
private topOutlet?: IonRouterOutlet;
private direction: 'forward' | 'back' | 'root' | 'auto' = DEFAULT_DIRECTION;
private animated?: NavDirection = DEFAULT_ANIMATED;
private animationBuilder?: AnimationBuilder;
private guessDirection: RouterDirection = 'forward';
private guessAnimation?: NavDirection;
private lastNavId = -1;
@@ -45,7 +47,10 @@ export class NavController {
}
// Subscribe to backButton events
platform.backButton.subscribeWithPriority(0, () => this.pop());
platform.backButton.subscribeWithPriority(0, processNextHandler => {
this.pop();
processNextHandler();
});
}
/**
@@ -62,7 +67,7 @@ export class NavController {
* ```
*/
navigateForward(url: string | UrlTree | any[], options: NavigationOptions = {}): Promise<boolean> {
this.setDirection('forward', options.animated, options.animationDirection);
this.setDirection('forward', options.animated, options.animationDirection, options.animation);
return this.navigate(url, options);
}
@@ -85,7 +90,7 @@ export class NavController {
* ```
*/
navigateBack(url: string | UrlTree | any[], options: NavigationOptions = {}): Promise<boolean> {
this.setDirection('back', options.animated, options.animationDirection);
this.setDirection('back', options.animated, options.animationDirection, options.animation);
return this.navigate(url, options);
}
@@ -108,7 +113,7 @@ export class NavController {
* ```
*/
navigateRoot(url: string | UrlTree | any[], options: NavigationOptions = {}): Promise<boolean> {
this.setDirection('root', options.animated, options.animationDirection);
this.setDirection('root', options.animated, options.animationDirection, options.animation);
return this.navigate(url, options);
}
@@ -118,7 +123,7 @@ export class NavController {
* by default.
*/
back(options: AnimationOptions = { animated: true, animationDirection: 'back' }) {
this.setDirection('back', options.animated, options.animationDirection);
this.setDirection('back', options.animated, options.animationDirection, options.animation);
return this.location.back();
}
@@ -147,9 +152,10 @@ export class NavController {
*
* It's recommended to use `navigateForward()`, `navigateBack()` and `navigateRoot()` instead of `setDirection()`.
*/
setDirection(direction: RouterDirection, animated?: boolean, animationDirection?: 'forward' | 'back') {
setDirection(direction: RouterDirection, animated?: boolean, animationDirection?: 'forward' | 'back', animationBuilder?: AnimationBuilder) {
this.direction = direction;
this.animated = getAnimation(direction, animated, animationDirection);
this.animationBuilder = animationBuilder;
}
/**
@@ -165,6 +171,7 @@ export class NavController {
consumeTransition() {
let direction: RouterDirection = 'root';
let animation: NavDirection | undefined;
const animationBuilder = this.animationBuilder;
if (this.direction === 'auto') {
direction = this.guessDirection;
@@ -175,10 +182,12 @@ export class NavController {
}
this.direction = DEFAULT_DIRECTION;
this.animated = DEFAULT_ANIMATED;
this.animationBuilder = undefined;
return {
direction,
animation
animation,
animationBuilder
};
}

View File

@@ -1,10 +1,10 @@
import { DOCUMENT } from '@angular/common';
import { Inject, Injectable, NgZone } from '@angular/core';
import { BackButtonEventDetail, Platforms, getPlatforms, isPlatform } from '@ionic/core';
import { BackButtonEventDetail, KeyboardEventDetail, Platforms, getPlatforms, isPlatform } from '@ionic/core';
import { Subject, Subscription } from 'rxjs';
export interface BackButtonEmitter extends Subject<BackButtonEventDetail> {
subscribeWithPriority(priority: number, callback: () => Promise<any> | void): Subscription;
subscribeWithPriority(priority: number, callback: (processNextHandler: () => void) => Promise<any> | void): Subscription;
}
@Injectable({
@@ -20,6 +20,18 @@ export class Platform {
*/
backButton: BackButtonEmitter = new Subject<BackButtonEventDetail>() as any;
/**
* The keyboardDidShow event emits when the
* on-screen keyboard is presented.
*/
keyboardDidShow = new Subject<KeyboardEventDetail>() as any;
/**
* The keyboardDidHide event emits when the
* on-screen keyboard is hidden.
*/
keyboardDidHide = new Subject<void>();
/**
* The pause event emits when the native platform puts the application
* into the background, typically when the user switches to a different
@@ -46,15 +58,17 @@ export class Platform {
zone.run(() => {
this.win = doc.defaultView;
this.backButton.subscribeWithPriority = function(priority, callback) {
return this.subscribe(ev => (
ev.register(priority, () => zone.run(callback))
));
return this.subscribe(ev => {
return ev.register(priority, processNextHandler => zone.run(() => callback(processNextHandler)));
});
};
proxyEvent(this.pause, doc, 'pause');
proxyEvent(this.resume, doc, 'resume');
proxyEvent(this.backButton, doc, 'ionBackButton');
proxyEvent(this.resize, this.win, 'resize');
proxyEvent(this.keyboardDidShow, this.win, 'ionKeyboardDidShow');
proxyEvent(this.keyboardDidHide, this.win, 'ionKeyboardDidHide');
let readyResolve: (value: string) => void;
this._readyPromise = new Promise(res => { readyResolve = res; });

View File

@@ -2,7 +2,7 @@ import { join, Path } from '@angular-devkit/core';
import { apply, chain, mergeWith, move, Rule, SchematicContext, SchematicsException, template, Tree, url } from '@angular-devkit/schematics';
import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
import { addModuleImportToRootModule } from './../utils/ast';
import { addArchitectBuilder, addStyle, getWorkspace, addAsset } from './../utils/config';
import { addArchitectBuilder, addAsset, addStyle, getDefaultAngularAppName, getWorkspace, WorkspaceProject, WorkspaceSchema } from './../utils/config';
import { addPackageToPackageJson } from './../utils/package';
import { Schema as IonAddOptions } from './schema';
@@ -25,7 +25,7 @@ function addIonicAngularToolkitToPackageJson(): Rule {
};
}
function addIonicAngularModuleToAppModule(projectSourceRoot): Rule {
function addIonicAngularModuleToAppModule(projectSourceRoot: Path): Rule {
return (host: Tree) => {
addModuleImportToRootModule(
host,
@@ -37,7 +37,7 @@ function addIonicAngularModuleToAppModule(projectSourceRoot): Rule {
};
}
function addIonicStyles(): Rule {
function addIonicStyles(projectName: string, projectSourceRoot: Path): Rule {
return (host: Tree) => {
const ionicStyles = [
'node_modules/@ionic/angular/css/normalize.css',
@@ -49,49 +49,49 @@ function addIonicStyles(): Rule {
'node_modules/@ionic/angular/css/text-alignment.css',
'node_modules/@ionic/angular/css/text-transformation.css',
'node_modules/@ionic/angular/css/flex-utils.css',
'src/theme/variables.css'
`${projectSourceRoot}/theme/variables.css`
].forEach(entry => {
addStyle(host, entry);
addStyle(host, projectName, entry);
});
return host;
};
}
function addIonicons(): Rule {
function addIonicons(projectName: string): Rule {
return (host: Tree) => {
const ioniconsGlob = {
glob: '**/*.svg',
input: 'node_modules/ionicons/dist/ionicons/svg',
output: './svg'
};
addAsset(host, ioniconsGlob);
addAsset(host, projectName, ioniconsGlob);
return host;
};
}
function addIonicBuilder(): Rule {
function addIonicBuilder(projectName: string): Rule {
return (host: Tree) => {
addArchitectBuilder(host, 'ionic-cordova-serve', {
addArchitectBuilder(host, projectName, 'ionic-cordova-serve', {
builder: '@ionic/angular-toolkit:cordova-serve',
options: {
cordovaBuildTarget: 'app:ionic-cordova-build',
devServerTarget: 'app:serve'
cordovaBuildTarget: `${projectName}:ionic-cordova-build`,
devServerTarget: `${projectName}:serve`
},
configurations: {
production: {
cordovaBuildTarget: 'app:ionic-cordova-build:production',
devServerTarget: 'app:serve:production'
cordovaBuildTarget: `${projectName}:ionic-cordova-build:production`,
devServerTarget: `${projectName}:serve:production`
}
}
});
addArchitectBuilder(host, 'ionic-cordova-build', {
addArchitectBuilder(host, projectName, 'ionic-cordova-build', {
builder: '@ionic/angular-toolkit:cordova-build',
options: {
browserTarget: 'app:build'
browserTarget: `${projectName}:build`
},
configurations: {
production: {
browserTarget: 'app:build:production'
browserTarget: `${projectName}:build:production`
}
}
});
@@ -100,25 +100,24 @@ function addIonicBuilder(): Rule {
}
function installNodeDeps() {
return (host: Tree, context: SchematicContext) => {
return (_host: Tree, context: SchematicContext) => {
context.addTask(new NodePackageInstallTask());
};
}
export default function ngAdd(options: IonAddOptions): Rule {
return (host: Tree) => {
const workspace = getWorkspace(host);
const workspace: WorkspaceSchema = getWorkspace(host);
if (!options.project) {
options.project = Object.keys(workspace.projects)[0];
options.project = getDefaultAngularAppName(workspace);
}
const project = workspace.projects[options.project];
const project: WorkspaceProject = workspace.projects[options.project];
if (project.projectType !== 'application') {
throw new SchematicsException(
`Ionic Add requires a project type of "application".`
);
}
const sourcePath = join(project.root as Path, 'src');
const sourcePath: Path = join(project.sourceRoot as Path);
const rootTemplateSource = apply(url('./files/root'), [
template({ ...options }),
move(sourcePath)
@@ -128,9 +127,9 @@ export default function ngAdd(options: IonAddOptions): Rule {
addIonicAngularToPackageJson(),
addIonicAngularToolkitToPackageJson(),
addIonicAngularModuleToAppModule(sourcePath),
addIonicBuilder(),
addIonicStyles(),
addIonicons(),
addIonicBuilder(options.project),
addIonicStyles(options.project, sourcePath),
addIonicons(options.project),
mergeWith(rootTemplateSource),
// install freshly added dependencies
installNodeDeps()

View File

@@ -27,7 +27,7 @@ export function getSourceFile(host: Tree, path: string): ts.SourceFile {
*/
export function addModuleImportToRootModule(
host: Tree,
projectSourceRoot,
projectSourceRoot: string,
moduleName: string,
importSrc: string
) {

View File

@@ -21,7 +21,7 @@ function isAngularBrowserProject(projectConfig: any) {
return false;
}
export function getAngularAppName(config: any): string | null {
export function getDefaultAngularAppName(config: any): string {
const projects = config.projects;
const projectNames = Object.keys(projects);
@@ -32,63 +32,52 @@ export function getAngularAppName(config: any): string | null {
}
}
return null;
return projectNames[0];
}
export function getAngularAppConfig(config: any): any | null {
const projects = config.projects;
const projectNames = Object.keys(projects);
for (const projectName of projectNames) {
const projectConfig = projects[projectName];
if (isAngularBrowserProject(projectConfig)) {
return projectConfig;
}
export function getAngularAppConfig(config: any, projectName: string): any | never {
if (!config.projects.hasOwnProperty(projectName)) {
throw new SchematicsException(`Could not find project: ${projectName}`);
}
return null;
}
const projectConfig = config.projects[projectName];
if (isAngularBrowserProject(projectConfig)) {
return projectConfig;
}
export function addStyle(host: Tree, stylePath: string) {
const config = readConfig(host);
const appConfig = getAngularAppConfig(config);
if (appConfig) {
appConfig.architect.build.options.styles.push({
input: stylePath
});
writeConfig(host, config);
if (config.projectType !== 'application') {
throw new SchematicsException(`Invalid projectType for ${projectName}: ${config.projectType}`);
} else {
throw new SchematicsException(`Cannot find valid app`);
const buildConfig = projectConfig.architect.build;
throw new SchematicsException(`Invalid builder for ${projectName}: ${buildConfig.builder}`);
}
}
export function addAsset(host: Tree, asset: string | {glob: string; input: string; output: string}) {
export function addStyle(host: Tree, projectName: string, stylePath: string) {
const config = readConfig(host);
const appConfig = getAngularAppConfig(config);
if (appConfig) {
appConfig.architect.build.options.assets.push(asset);
writeConfig(host, config);
} else {
throw new SchematicsException(`Cannot find valid app`);
}
const appConfig = getAngularAppConfig(config, projectName);
appConfig.architect.build.options.styles.push({
input: stylePath
});
writeConfig(host, config);
}
export function addArchitectBuilder(host: Tree, builderName: string, builderOpts: any){
export function addAsset(host: Tree, projectName: string, asset: string | {glob: string; input: string; output: string}) {
const config = readConfig(host);
const appConfig = getAngularAppConfig(config);
const appConfig = getAngularAppConfig(config, projectName);
appConfig.architect.build.options.assets.push(asset);
writeConfig(host, config);
}
if (appConfig) {
appConfig.architect[builderName] = builderOpts
writeConfig(host, config);
} else {
throw new SchematicsException(`Cannot find valid app`);
}
export function addArchitectBuilder(host: Tree, projectName: string, builderName: string, builderOpts: any): void | never {
const config = readConfig(host);
const appConfig = getAngularAppConfig(config, projectName);
appConfig.architect[builderName] = builderOpts;
writeConfig(host, config);
}
export type WorkspaceSchema = experimental.workspace.WorkspaceSchema;
export type WorkspaceProject = experimental.workspace.WorkspaceProject;
export function getWorkspacePath(host: Tree): string {
const possibleFiles = ['/angular.json', '/.angular.json'];

View File

@@ -0,0 +1,31 @@
/**
* https://ionicframework.com/docs/api/router-outlet#life-cycle-hooks
*/
export interface ViewWillEnter {
/**
* Fired when the component routing to is about to animate into view.
*/
ionViewWillEnter(): void;
}
export interface ViewDidEnter {
/**
* Fired when the component routing to has finished animating.
*/
ionViewDidEnter(): void;
}
export interface ViewWillLeave {
/**
* Fired when the component routing from is about to animate.
*/
ionViewWillLeave(): void;
}
export interface ViewDidLeave {
/**
* Fired when the component routing to has finished animating.
*/
ionViewDidLeave(): void;
}

View File

@@ -13,11 +13,13 @@
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/browser",
"aot": true,
"outputPath": "dist/test-app/browser",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"buildOptimizer": true,
"assets": [
"src/favicon.ico",
{
@@ -57,6 +59,10 @@
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb"
}
]
}
@@ -116,20 +122,44 @@
"server": {
"builder": "@angular-devkit/build-angular:server",
"options": {
"outputPath": "dist/server",
"main": "src/main.server.ts",
"outputPath": "dist/test-app/server",
"main": "server.ts",
"tsConfig": "tsconfig.server.json"
},
"configurations": {
"production": {
"outputHashing": "media",
"fileReplacements": [
{
"src": "src/environments/environment.ts",
"replaceWith": "src/environments/environment.prod.ts"
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
]
],
"sourceMap": false,
"optimization": true
}
}
},
"serve-ssr": {
"builder": "@nguniversal/builders:ssr-dev-server",
"options": {
"browserTarget": "test-app:build",
"serverTarget": "test-app:server"
},
"configurations": {
"production": {
"browserTarget": "test-app:build:production",
"serverTarget": "test-app:server:production"
}
}
},
"prerender": {
"builder": "@nguniversal/builders:prerender",
"options": {
"browserTarget": "test-app:build:production",
"serverTarget": "test-app:server:production",
"routes": []
}
}
}
}

View File

@@ -23,7 +23,7 @@ exports.config = {
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 70000,
defaultTimeoutInterval: 100000,
print: function() {}
},
onPrepare() {

View File

@@ -1,5 +1,5 @@
import { browser, element, by } from 'protractor';
import { handleErrorMessages, setProperty, getText, waitTime } from './utils';
import { handleErrorMessages, getProperty, setProperty, getText, waitTime } from './utils';
describe('form', () => {
@@ -7,6 +7,20 @@ describe('form', () => {
return handleErrorMessages();
});
describe('status updates', () => {
beforeEach(async () => {
await browser.get('/form');
await waitTime(30);
});
it('should update Ionic form classes when calling form methods programatically', async () => {
await element(by.css('form #input-touched')).click();
await waitTime(100);
const classList = (await getProperty('#touched-input-test', 'classList')) as string[];
expect(classList.includes('ion-touched')).toEqual(true);
});
});
describe('change', () => {
beforeEach(async () => {
await browser.get('/form');

View File

@@ -1,5 +1,5 @@
import { browser, element, by, ElementFinder } from 'protractor';
import { waitTime, testStack, handleErrorMessages } from './utils';
import { browser, by, element, ElementFinder, ExpectedConditions } from 'protractor';
import { handleErrorMessages, testStack, waitTime } from './utils';
describe('tabs', () => {
afterEach(() => {
@@ -131,6 +131,94 @@ describe('tabs', () => {
await testTabTitle('Tab 3 - Page 1');
await testStack('ion-tabs ion-router-outlet', ['app-tabs-tab1', 'app-tabs-tab3']);
});
it('should preserve navigation extras when switching tabs', async () => {
const expectUrlToContain = 'search=hello#fragment';
let tab = await getSelectedTab() as ElementFinder;
await tab.$('#goto-nested-page1-with-query-params').click();
await testTabTitle('Tab 1 - Page 2 (1)');
await testUrlContains(expectUrlToContain);
await element(by.css('#tab-button-contact')).click();
await testTabTitle('Tab 2 - Page 1');
await element(by.css('#tab-button-account')).click();
tab = await testTabTitle('Tab 1 - Page 2 (1)');
await testUrlContains(expectUrlToContain);
});
it('should set root when clicking on an active tab to navigate to the root', async () => {
const expectNestedTabUrlToContain = 'search=hello#fragment';
let tab = await getSelectedTab() as ElementFinder;
const initialUrl = await browser.getCurrentUrl();
await tab.$('#goto-nested-page1-with-query-params').click();
await testTabTitle('Tab 1 - Page 2 (1)');
await testUrlContains(expectNestedTabUrlToContain);
await element(by.css('#tab-button-account')).click();
await testTabTitle('Tab 1 - Page 1');
await testUrlEquals(initialUrl);
});
});
describe('entry tab contains navigation extras', () => {
const expectNestedTabUrlToContain = 'search=hello#fragment';
const rootUrlParams = 'test=123#rootFragment';
const rootUrl = `/tabs/account?${rootUrlParams}`;
beforeEach(async () => {
await browser.get(rootUrl);
await waitTime(30);
});
it('should preserve root url navigation extras when clicking on an active tab to navigate to the root', async () => {
await browser.get(rootUrl);
let tab = await getSelectedTab() as ElementFinder;
await tab.$('#goto-nested-page1-with-query-params').click();
await testTabTitle('Tab 1 - Page 2 (1)');
await testUrlContains(expectNestedTabUrlToContain);
await element(by.css('#tab-button-account')).click();
await testTabTitle('Tab 1 - Page 1');
await testUrlContains(rootUrl);
});
it('should preserve root url navigation extras when changing tabs', async () => {
await browser.get(rootUrl);
let tab = await getSelectedTab() as ElementFinder;
await element(by.css('#tab-button-contact')).click();
tab = await testTabTitle('Tab 2 - Page 1');
await element(by.css('#tab-button-account')).click();
await testTabTitle('Tab 1 - Page 1');
await testUrlContains(rootUrl);
});
it('should navigate deep then go home and preserve navigation extras', async () => {
let tab = await getSelectedTab();
await tab.$('#goto-tab1-page2').click();
tab = await testTabTitle('Tab 1 - Page 2 (1)');
await tab.$('#goto-next').click();
tab = await testTabTitle('Tab 1 - Page 2 (2)');
await element(by.css('#tab-button-contact')).click();
tab = await testTabTitle('Tab 2 - Page 1');
await element(by.css('#tab-button-account')).click();
await testTabTitle('Tab 1 - Page 2 (2)');
await element(by.css('#tab-button-account')).click();
await testTabTitle('Tab 1 - Page 1');
await testUrlContains(rootUrl);
});
});
describe('entry url - /tabs/account/nested/1', () => {
@@ -159,7 +247,7 @@ describe('tabs', () => {
await tab.$('#goto-next').click();
tab = await testTabTitle('Tab 1 - Page 2 (3)');
await testStack('ion-tabs ion-router-outlet',[
await testStack('ion-tabs ion-router-outlet', [
'app-tabs-tab1-nested',
'app-tabs-tab1-nested',
'app-tabs-tab1-nested'
@@ -226,6 +314,18 @@ async function testTabTitle(title: string) {
return tab;
}
async function testUrlContains(urlFragment: string) {
await browser.wait(ExpectedConditions.urlContains(urlFragment),
5000,
`expected ${browser.getCurrentUrl()} to contain ${urlFragment}`);
}
async function testUrlEquals(url: string) {
await browser.wait(ExpectedConditions.urlIs(url),
5000,
`expected ${browser.getCurrentUrl()} to equal ${url}`);
}
async function getSelectedTab(): Promise<ElementFinder> {
const tabs = element.all(by.css('ion-tabs ion-router-outlet > *:not(.ion-page-hidden)'));
expect(await tabs.count()).toEqual(1);

View File

@@ -8,6 +8,8 @@ module.exports = function (config) {
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
@@ -24,6 +26,7 @@ module.exports = function (config) {
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
singleRun: false,
restartOnFileChange: true
});
};
};

View File

@@ -11,50 +11,53 @@
"test": "ng e2e --prod",
"test.dev": "npm run sync && ng e2e",
"lint": "ng lint",
"postinstall": "npm run sync",
"compile:server": "webpack --config webpack.server.config.js --progress --colors",
"serve:ssr": "node dist/server",
"build:ssr": "npm run build:client-and-server-bundles && npm run compile:server",
"build:client-and-server-bundles": "npm run build && ng run test-app:server:production --bundleDependencies all"
"postinstall": "npm run sync && ngcc",
"serve:ssr": "node dist/test-app/server/main.js",
"build:ssr": "ng build --prod && ng run test-app:server:production",
"dev:ssr": "ng run test-app:serve-ssr",
"prerender": "ng run test-app:prerender"
},
"dependencies": {
"@angular/animations": "^8.2.8",
"@angular/common": "^8.2.8",
"@angular/compiler": "^8.2.8",
"@angular/core": "^8.2.8",
"@angular/forms": "^8.2.8",
"@angular/platform-browser": "^8.2.8",
"@angular/platform-browser-dynamic": "^8.2.8",
"@angular/platform-server": "^8.2.8",
"@angular/router": "^8.2.8",
"@angular/animations": "^9.0.0-rc.2",
"@angular/common": "^9.0.0-rc.2",
"@angular/compiler": "^9.0.0-rc.2",
"@angular/core": "^9.0.0-rc.2",
"@angular/forms": "^9.0.0-rc.2",
"@angular/platform-browser": "^9.0.0-rc.2",
"@angular/platform-browser-dynamic": "^9.0.0-rc.2",
"@angular/platform-server": "^9.0.0-rc.2",
"@angular/router": "^9.0.0-rc.2",
"@ionic/angular": "^4.7.0",
"@ionic/angular-server": "^0.0.2",
"@nguniversal/express-engine": "~8.1.1",
"@nguniversal/module-map-ngfactory-loader": "~8.1.1",
"@nguniversal/express-engine": "9.0.0-next.9",
"core-js": "^2.6.2",
"express": "^4.15.2",
"rxjs": "^6.5.3",
"tslib": "^1.9.0",
"zone.js": "~0.9.1"
"tslib": "^1.10.0",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.803.6",
"@angular/cli": "^8.3.6",
"@angular/compiler-cli": "^8.2.8",
"@angular/language-service": "^8.2.8",
"@angular-devkit/build-angular": "~0.900.0-rc.2",
"@angular/cli": "^9.0.0-rc.2",
"@angular/compiler-cli": "^9.0.0-rc.2",
"@angular/language-service": "^9.0.0-rc.2",
"@nguniversal/builders": "9.0.0-next.9",
"@types/express": "^4.17.0",
"@types/jasmine": "3.4.1",
"@types/node": "12.7.8",
"@types/node": "^12.11.1",
"codelyzer": "^5.1.2",
"jasmine-core": "3.5.0",
"jasmine-spec-reporter": "4.2.1",
"karma": "4.3.0",
"karma-chrome-launcher": "3.1.0",
"karma-jasmine": "2.0.1",
"protractor": "5.4.2",
"jasmine-core": "~3.5.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~4.3.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~2.1.0",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.2",
"protractor": "~5.4.2",
"ts-loader": "^6.1.2",
"ts-node": "8.4.1",
"tslint": "~5.18.0",
"typescript": "~3.5.3",
"typescript": "~3.6.4",
"webpack-cli": "^3.3.9"
}
}

View File

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

View File

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

View File

@@ -1,5 +1,8 @@
<ion-header>
<ion-toolbar>
<ion-buttons>
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>
Alert test
</ion-title>

View File

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

View File

@@ -35,9 +35,11 @@
<ion-item>
<ion-label>Input (required)</ion-label>
<ion-input formControlName="input" class="required"></ion-input>
<ion-input formControlName="input" class="required" id="touched-input-test"></ion-input>
</ion-item>
<ion-button id="input-touched" (click)="setTouched()">Set Input Touched</ion-button>
<ion-item>
<ion-label>Input</ion-label>
<ion-input formControlName="input2"></ion-input>

View File

@@ -25,6 +25,11 @@ export class FormComponent {
});
}
setTouched() {
const formControl = this.profileForm.get('input');
formControl.markAsTouched();
}
onSubmit(_ev) {
this.submitted = 'true';
}

View File

@@ -7,7 +7,7 @@
</ion-header>
<ion-content>
<ion-list>
<ion-item routerLink="/alerts">
<ion-item routerLink="/alerts" [routerAnimation]="routerAnimation">
<ion-label>
Alerts test
</ion-label>

View File

@@ -1,9 +1,25 @@
import { Component } from '@angular/core';
import { AnimationBuilder, AnimationController } from '@ionic/angular';
@Component({
selector: 'app-home-page',
templateUrl: './home-page.component.html',
})
export class HomePageComponent {
routerAnimation: AnimationBuilder = (_, opts) => {
const { direction, enteringEl, leavingEl } = opts;
const animation = this.animationCtrl.create().duration(500).easing('ease-out');
const enteringAnimation = this.animationCtrl.create().addElement(enteringEl).beforeRemoveClass(['ion-page-invisible']);
const leavingAnimation = this.animationCtrl.create().addElement(leavingEl).beforeRemoveClass(['ion-page-invisible']);
if (direction === 'back') {
enteringAnimation.fromTo('transform', 'translateX(-100%)', 'translateX(0%)');
leavingAnimation.fromTo('transform', 'translateX(0%)', 'translateX(100%)');
} else {
enteringAnimation.fromTo('transform', 'translateX(100%)', 'translateX(0%)');
leavingAnimation.fromTo('transform', 'translateX(0%)', 'translateX(-100%)');
}
return animation.addAnimation([enteringAnimation, leavingAnimation]);
};
constructor(private animationCtrl: AnimationController) {}
}

View File

@@ -1,11 +1,11 @@
import { Component, Input, NgZone, OnInit, Optional } from '@angular/core';
import { ModalController, NavParams, IonNav } from '@ionic/angular';
import { ModalController, NavParams, IonNav, ViewWillLeave, ViewDidEnter, ViewDidLeave } from '@ionic/angular';
@Component({
selector: 'app-modal-example',
templateUrl: './modal-example.component.html',
})
export class ModalExampleComponent implements OnInit {
export class ModalExampleComponent implements OnInit, ViewWillLeave, ViewDidEnter, ViewWillLeave, ViewDidLeave {
@Input() value: string;

View File

@@ -1,11 +1,11 @@
import { Component, OnInit, NgZone } from '@angular/core';
import { IonRouterOutlet } from '@ionic/angular';
import { IonRouterOutlet, ViewDidEnter, ViewDidLeave, ViewWillLeave } from '@ionic/angular';
@Component({
selector: 'app-router-link-page',
templateUrl: './router-link-page.component.html',
})
export class RouterLinkPageComponent implements OnInit {
export class RouterLinkPageComponent implements OnInit, ViewWillLeave, ViewDidEnter, ViewWillLeave, ViewDidLeave {
onInit = 0;
willEnter = 0;

View File

@@ -1,12 +1,12 @@
import { Component, NgZone, OnInit } from '@angular/core';
import { NavController } from '@ionic/angular';
import { NavController, ViewDidEnter, ViewDidLeave, ViewWillEnter, ViewWillLeave } from '@ionic/angular';
import { Router } from '@angular/router';
@Component({
selector: 'app-router-link',
templateUrl: './router-link.component.html',
})
export class RouterLinkComponent implements OnInit {
export class RouterLinkComponent implements OnInit, ViewWillEnter, ViewDidEnter, ViewWillLeave, ViewDidLeave {
onInit = 0;
willEnter = 0;

View File

@@ -15,6 +15,8 @@
</p>
<p>
<ion-button routerLink="/tabs/account/nested/1" id="goto-tab1-page2">Go to Page 2</ion-button>
<ion-button routerLink="/tabs/account/nested/1" [queryParams]="{search:'hello'}" fragment="fragment"
id="goto-nested-page1-with-query-params">Go to Page 2 with Query Params</ion-button>
<ion-button routerLink="/tabs/lazy/nested" id="goto-tab3-page2">Go to Tab 3 - Page 2</ion-button>
<ion-button routerLink="/nested-outlet/page" id="goto-nested-page1">Go to nested</ion-button>
</p>

View File

@@ -1,11 +1,12 @@
import { Component, NgZone, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ViewDidEnter, ViewDidLeave, ViewWillEnter, ViewWillLeave } from '@ionic/angular';
@Component({
selector: 'app-virtual-scroll-detail',
templateUrl: './virtual-scroll-detail.component.html',
})
export class VirtualScrollDetailComponent implements OnInit {
export class VirtualScrollDetailComponent implements OnInit, ViewWillEnter, ViewDidEnter, ViewWillLeave, ViewDidLeave {
onInit = 0;
willEnter = 0;

View File

@@ -7,5 +7,4 @@ if (environment.production) {
}
export { AppServerModule } from './app/app.server.module';
export { ngExpressEngine } from '@nguniversal/express-engine';
export { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';
export { renderModule, renderModuleFactory } from '@angular/platform-server';

View File

@@ -10,6 +10,6 @@ if (environment.production) {
document.addEventListener('DOMContentLoaded', () => {
platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch(err => console.error(err));
.bootstrapModule(AppModule)
.catch(err => console.error(err));
});

View File

@@ -43,7 +43,7 @@
*
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
* (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
*
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch for IE/Edge
@@ -52,9 +52,12 @@
*
*/
import './zone-flags.ts';
/***************************************************************************************************
* Zone JS is required by default for Angular itself.
*/
import 'zone.js/dist/zone'; // Included with Angular CLI.

View File

@@ -0,0 +1,5 @@
/**
* Prevents Angular change detection from
* running with certain Web Component callbacks
*/
(window as any).__Zone_disable_customElements = true;

View File

@@ -3,6 +3,10 @@
"compilerOptions": {
"outDir": "./out-tsc/app"
},
"include": ["src/**/*.ts"],
"exclude": ["src/test.ts", "src/**/*.spec.ts"]
"files": [
"src/main.ts",
"src/polyfills.ts",
"src/zone-flags.ts"
],
"include": ["src/**/*.d.ts"]
}

View File

@@ -1,8 +1,16 @@
{
"extends": "./tsconfig.app.json",
"compilerOptions": {
"outDir": "../out-tsc/app-server"
"outDir": "./out-tsc/app-server",
"module": "commonjs",
"types": [
"node"
]
},
"files": [
"src/main.server.ts",
"server.ts"
],
"angularCompilerOptions": {
"entryModule": "./src/app/app.server.module#AppServerModule"
}

View File

@@ -1,53 +0,0 @@
// Work around for https://github.com/angular/angular-cli/issues/7200
const path = require('path');
const webpack = require('webpack');
module.exports = {
mode: 'none',
entry: {
// This is our Express server for Dynamic universal
server: './server.ts'
},
externals: {
'./dist/server/main': 'require("./server/main")'
},
target: 'node',
resolve: {
mainFields: ['module', 'main'],
extensions: ['.ts', '.js']
},
optimization: {
minimize: false
},
output: {
// Puts the output at the root of the dist folder
path: path.join(__dirname, 'dist'),
filename: '[name].js'
},
module: {
rules: [
{ test: /\.ts$/, loader: 'ts-loader' },
{
// Mark files inside `@angular/core` as using SystemJS style dynamic imports.
// Removing this will cause deprecation warnings to appear.
test: /(\\|\/)@angular(\\|\/)core(\\|\/).+\.js$/,
parser: { system: true },
},
]
},
plugins: [
new webpack.ContextReplacementPlugin(
// fixes WARNING Critical dependency: the request of a dependency is an expression
/(.+)?angular(\\|\/)core(.+)?/,
path.join(__dirname, 'src'), // location of your src
{} // a map of your routes
),
new webpack.ContextReplacementPlugin(
// fixes WARNING Critical dependency: the request of a dependency is an expression
/(.+)?express(\\|\/)(.+)?/,
path.join(__dirname, 'src'),
{}
)
]
};

View File

@@ -1,11 +1,13 @@
{
"angularCompilerOptions": {
"annotateForClosureCompiler": true,
"strictMetadataEmit" : true,
"strictMetadataEmit": true,
"flatModuleOutFile": "core.js",
"flatModuleId": "@ionic/angular",
"skipTemplateCodegen": true,
"fullTemplateTypeCheck": false
"fullTemplateTypeCheck": false,
"enableResourceInlining": true,
"enableIvy": false
},
"compilerOptions": {
"alwaysStrict": true,
@@ -32,12 +34,8 @@
"target": "es2015",
"baseUrl": ".",
"paths": {
"@ionic/core/hydrate": [
"../core/hydrate"
],
"@ionic/core": [
"../core"
]
"@ionic/core/hydrate": ["../core/hydrate"],
"@ionic/core": ["../core"]
}
},
"exclude": ["node_modules", "src/schematics"],

View File

@@ -51,7 +51,7 @@ npm start
You should be able to navigate to `http://localhost:3333` which will look like a file browser.
E2E tests are located inside the `src/component` folder, in the following way: `http://localhost:3333/src/components/{COMPONENT}/test/`
E2E tests are located inside the `src/components` folder, in the following way: `http://localhost:3333/src/components/{COMPONENT}/test/`
**Path examples:**

View File

@@ -23,9 +23,9 @@ The Ionic Core package contains the Web Components that make up the reusable UI
Easiest way to start using Ionic Core is by adding a script tag to the CDN:
```html
<script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core@4.6.2/dist/ionic/ionic.esm.js"></script>
<script nomodule src="https://cdn.jsdelivr.net/npm/@ionic/core@4.6.2/dist/ionic/ionic.js"></script>
<link href="https://cdn.jsdelivr.net/npm/@ionic/core@4.6.2/css/ionic.bundle.css" rel="stylesheet">
<script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.esm.js"></script>
<script nomodule src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.js"></script>
<link href="https://cdn.jsdelivr.net/npm/@ionic/core/css/ionic.bundle.css" rel="stylesheet">
```
Any Ionic component added to the webpage will automatically load. This includes writing the component tag directly in HTML, or using JavaScript such as `document.createElement('ion-toggle')`.

View File

@@ -12,8 +12,8 @@ ion-action-sheet,prop,mode,"ios" | "md",undefined,false,false
ion-action-sheet,prop,subHeader,string | undefined,undefined,false,false
ion-action-sheet,prop,translucent,boolean,false,false,false
ion-action-sheet,method,dismiss,dismiss(data?: any, role?: string | undefined) => Promise<boolean>
ion-action-sheet,method,onDidDismiss,onDidDismiss() => Promise<OverlayEventDetail<any>>
ion-action-sheet,method,onWillDismiss,onWillDismiss() => Promise<OverlayEventDetail<any>>
ion-action-sheet,method,onDidDismiss,onDidDismiss<T = any>() => Promise<OverlayEventDetail<T>>
ion-action-sheet,method,onWillDismiss,onWillDismiss<T = any>() => Promise<OverlayEventDetail<T>>
ion-action-sheet,method,present,present() => Promise<void>
ion-action-sheet,event,ionActionSheetDidDismiss,OverlayEventDetail<any>,true
ion-action-sheet,event,ionActionSheetDidPresent,void,true
@@ -21,8 +21,20 @@ ion-action-sheet,event,ionActionSheetWillDismiss,OverlayEventDetail<any>,true
ion-action-sheet,event,ionActionSheetWillPresent,void,true
ion-action-sheet,css-prop,--backdrop-opacity
ion-action-sheet,css-prop,--background
ion-action-sheet,css-prop,--background-activated
ion-action-sheet,css-prop,--background-selected
ion-action-sheet,css-prop,--button-background
ion-action-sheet,css-prop,--button-background-activated
ion-action-sheet,css-prop,--button-background-activated-opacity
ion-action-sheet,css-prop,--button-background-focused
ion-action-sheet,css-prop,--button-background-focused-opacity
ion-action-sheet,css-prop,--button-background-hover
ion-action-sheet,css-prop,--button-background-hover-opacity
ion-action-sheet,css-prop,--button-background-selected
ion-action-sheet,css-prop,--button-background-selected-opacity
ion-action-sheet,css-prop,--button-color
ion-action-sheet,css-prop,--button-color-activated
ion-action-sheet,css-prop,--button-color-focused
ion-action-sheet,css-prop,--button-color-hover
ion-action-sheet,css-prop,--button-color-selected
ion-action-sheet,css-prop,--color
ion-action-sheet,css-prop,--height
ion-action-sheet,css-prop,--max-height
@@ -31,11 +43,6 @@ ion-action-sheet,css-prop,--min-height
ion-action-sheet,css-prop,--min-width
ion-action-sheet,css-prop,--width
ion-action-sheet-controller,none
ion-action-sheet-controller,method,create,create(options: ActionSheetOptions) => Promise<HTMLIonActionSheetElement>
ion-action-sheet-controller,method,dismiss,dismiss(data?: any, role?: string | undefined, id?: string | undefined) => Promise<boolean>
ion-action-sheet-controller,method,getTop,getTop() => Promise<HTMLIonActionSheetElement | undefined>
ion-alert,scoped
ion-alert,prop,animated,boolean,true,false,false
ion-alert,prop,backdropDismiss,boolean,true,false,false
@@ -46,13 +53,13 @@ ion-alert,prop,header,string | undefined,undefined,false,false
ion-alert,prop,inputs,AlertInput[],[],false,false
ion-alert,prop,keyboardClose,boolean,true,false,false
ion-alert,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-alert,prop,message,string | undefined,undefined,false,false
ion-alert,prop,message,IonicSafeString | string | undefined,undefined,false,false
ion-alert,prop,mode,"ios" | "md",undefined,false,false
ion-alert,prop,subHeader,string | undefined,undefined,false,false
ion-alert,prop,translucent,boolean,false,false,false
ion-alert,method,dismiss,dismiss(data?: any, role?: string | undefined) => Promise<boolean>
ion-alert,method,onDidDismiss,onDidDismiss() => Promise<OverlayEventDetail<any>>
ion-alert,method,onWillDismiss,onWillDismiss() => Promise<OverlayEventDetail<any>>
ion-alert,method,onDidDismiss,onDidDismiss<T = any>() => Promise<OverlayEventDetail<T>>
ion-alert,method,onWillDismiss,onWillDismiss<T = any>() => Promise<OverlayEventDetail<T>>
ion-alert,method,present,present() => Promise<void>
ion-alert,event,ionAlertDidDismiss,OverlayEventDetail<any>,true
ion-alert,event,ionAlertDidPresent,void,true
@@ -67,27 +74,25 @@ ion-alert,css-prop,--min-height
ion-alert,css-prop,--min-width
ion-alert,css-prop,--width
ion-alert-controller,none
ion-alert-controller,method,create,create(options: AlertOptions) => Promise<HTMLIonAlertElement>
ion-alert-controller,method,dismiss,dismiss(data?: any, role?: string | undefined, id?: string | undefined) => Promise<boolean>
ion-alert-controller,method,getTop,getTop() => Promise<HTMLIonAlertElement | undefined>
ion-app,none
ion-avatar,shadow
ion-avatar,css-prop,--border-radius
ion-back-button,scoped
ion-back-button,shadow
ion-back-button,prop,color,string | undefined,undefined,false,false
ion-back-button,prop,defaultHref,string | undefined,undefined,false,false
ion-back-button,prop,disabled,boolean,false,false,true
ion-back-button,prop,icon,null | string | undefined,undefined,false,false
ion-back-button,prop,mode,"ios" | "md",undefined,false,false
ion-back-button,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-back-button,prop,text,null | string | undefined,undefined,false,false
ion-back-button,prop,type,"button" | "reset" | "submit",'button',false,false
ion-back-button,css-prop,--background
ion-back-button,css-prop,--background-focused
ion-back-button,css-prop,--background-focused-opacity
ion-back-button,css-prop,--background-hover
ion-back-button,css-prop,--background-hover-opacity
ion-back-button,css-prop,--border-radius
ion-back-button,css-prop,--color
ion-back-button,css-prop,--color-focused
@@ -115,6 +120,9 @@ ion-back-button,css-prop,--padding-start
ion-back-button,css-prop,--padding-top
ion-back-button,css-prop,--ripple-color
ion-back-button,css-prop,--transition
ion-back-button,part,icon
ion-back-button,part,native
ion-back-button,part,text
ion-backdrop,shadow
ion-backdrop,prop,stopPropagation,boolean,true,false,false
@@ -142,6 +150,7 @@ ion-button,prop,fill,"clear" | "default" | "outline" | "solid" | undefined,undef
ion-button,prop,href,string | undefined,undefined,false,false
ion-button,prop,mode,"ios" | "md",undefined,false,false
ion-button,prop,rel,string | undefined,undefined,false,false
ion-button,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-button,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
ion-button,prop,shape,"round" | undefined,undefined,false,true
ion-button,prop,size,"default" | "large" | "small" | undefined,undefined,false,true
@@ -152,8 +161,11 @@ ion-button,event,ionBlur,void,true
ion-button,event,ionFocus,void,true
ion-button,css-prop,--background
ion-button,css-prop,--background-activated
ion-button,css-prop,--background-activated-opacity
ion-button,css-prop,--background-focused
ion-button,css-prop,--background-focused-opacity
ion-button,css-prop,--background-hover
ion-button,css-prop,--background-hover-opacity
ion-button,css-prop,--border-color
ion-button,css-prop,--border-radius
ion-button,css-prop,--border-style
@@ -170,6 +182,7 @@ ion-button,css-prop,--padding-start
ion-button,css-prop,--padding-top
ion-button,css-prop,--ripple-color
ion-button,css-prop,--transition
ion-button,part,native
ion-buttons,scoped
ion-buttons,prop,collapse,boolean,false,false,false
@@ -182,11 +195,13 @@ ion-card,prop,download,string | undefined,undefined,false,false
ion-card,prop,href,string | undefined,undefined,false,false
ion-card,prop,mode,"ios" | "md",undefined,false,false
ion-card,prop,rel,string | undefined,undefined,false,false
ion-card,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-card,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
ion-card,prop,target,string | undefined,undefined,false,false
ion-card,prop,type,"button" | "reset" | "submit",'button',false,false
ion-card,css-prop,--background
ion-card,css-prop,--color
ion-card,part,native
ion-card-content,none
ion-card-content,prop,mode,"ios" | "md",undefined,false,false
@@ -225,8 +240,11 @@ ion-checkbox,css-prop,--border-radius
ion-checkbox,css-prop,--border-style
ion-checkbox,css-prop,--border-width
ion-checkbox,css-prop,--checkmark-color
ion-checkbox,css-prop,--checkmark-width
ion-checkbox,css-prop,--size
ion-checkbox,css-prop,--transition
ion-checkbox,part,container
ion-checkbox,part,mark
ion-chip,shadow
ion-chip,prop,color,string | undefined,undefined,false,false
@@ -278,7 +296,7 @@ ion-content,prop,scrollY,boolean,true,false,false
ion-content,method,getScrollElement,getScrollElement() => Promise<HTMLElement>
ion-content,method,scrollByPoint,scrollByPoint(x: number, y: number, duration: number) => Promise<void>
ion-content,method,scrollToBottom,scrollToBottom(duration?: number) => Promise<void>
ion-content,method,scrollToPoint,scrollToPoint(x: number | null | undefined, y: number | null | undefined, duration?: number) => Promise<void>
ion-content,method,scrollToPoint,scrollToPoint(x: number | undefined | null, y: number | undefined | null, duration?: number) => Promise<void>
ion-content,method,scrollToTop,scrollToTop(duration?: number) => Promise<void>
ion-content,event,ionScroll,ScrollDetail,true
ion-content,event,ionScrollEnd,ScrollBaseDetail,true
@@ -292,6 +310,8 @@ ion-content,css-prop,--padding-bottom
ion-content,css-prop,--padding-end
ion-content,css-prop,--padding-start
ion-content,css-prop,--padding-top
ion-content,part,background
ion-content,part,scroll
ion-datetime,shadow
ion-datetime,prop,cancelText,string,'Cancel',false,false
@@ -300,6 +320,7 @@ ion-datetime,prop,dayShortNames,string | string[] | undefined,undefined,false,fa
ion-datetime,prop,dayValues,number | number[] | string | undefined,undefined,false,false
ion-datetime,prop,disabled,boolean,false,false,false
ion-datetime,prop,displayFormat,string,'MMM D, YYYY',false,false
ion-datetime,prop,displayTimezone,string | undefined,undefined,false,false
ion-datetime,prop,doneText,string,'Done',false,false
ion-datetime,prop,hourValues,number | number[] | string | undefined,undefined,false,false
ion-datetime,prop,max,string | undefined,undefined,false,false
@@ -311,7 +332,7 @@ ion-datetime,prop,monthShortNames,string | string[] | undefined,undefined,false,
ion-datetime,prop,monthValues,number | number[] | string | undefined,undefined,false,false
ion-datetime,prop,name,string,this.inputId,false,false
ion-datetime,prop,pickerFormat,string | undefined,undefined,false,false
ion-datetime,prop,pickerOptions,undefined | { columns?: PickerColumn[] | undefined; buttons?: PickerButton[] | undefined; cssClass?: string | string[] | undefined; backdropDismiss?: boolean | undefined; animated?: boolean | undefined; mode?: "ios" | "md" | undefined; keyboardClose?: boolean | undefined; id?: string | undefined; enterAnimation?: AnimationBuilder | undefined; leaveAnimation?: AnimationBuilder | undefined; },undefined,false,false
ion-datetime,prop,pickerOptions,undefined | { columns?: PickerColumn[] | undefined; buttons?: PickerButton[] | undefined; cssClass?: string | string[] | undefined; showBackdrop?: boolean | undefined; backdropDismiss?: boolean | undefined; animated?: boolean | undefined; mode?: "ios" | "md" | undefined; keyboardClose?: boolean | undefined; id?: string | undefined; enterAnimation?: AnimationBuilder | undefined; leaveAnimation?: AnimationBuilder | undefined; },undefined,false,false
ion-datetime,prop,placeholder,null | string | undefined,undefined,false,false
ion-datetime,prop,readonly,boolean,false,false,false
ion-datetime,prop,value,null | string | undefined,undefined,false,false
@@ -326,6 +347,8 @@ ion-datetime,css-prop,--padding-end
ion-datetime,css-prop,--padding-start
ion-datetime,css-prop,--padding-top
ion-datetime,css-prop,--placeholder-color
ion-datetime,part,placeholder
ion-datetime,part,text
ion-fab,shadow
ion-fab,prop,activated,boolean,false,false,false
@@ -336,12 +359,14 @@ ion-fab,method,close,close() => Promise<void>
ion-fab-button,shadow
ion-fab-button,prop,activated,boolean,false,false,false
ion-fab-button,prop,closeIcon,string,'close',false,false
ion-fab-button,prop,color,string | undefined,undefined,false,false
ion-fab-button,prop,disabled,boolean,false,false,false
ion-fab-button,prop,download,string | undefined,undefined,false,false
ion-fab-button,prop,href,string | undefined,undefined,false,false
ion-fab-button,prop,mode,"ios" | "md",undefined,false,false
ion-fab-button,prop,rel,string | undefined,undefined,false,false
ion-fab-button,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-fab-button,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
ion-fab-button,prop,show,boolean,false,false,false
ion-fab-button,prop,size,"small" | undefined,undefined,false,false
@@ -352,13 +377,17 @@ ion-fab-button,event,ionBlur,void,true
ion-fab-button,event,ionFocus,void,true
ion-fab-button,css-prop,--background
ion-fab-button,css-prop,--background-activated
ion-fab-button,css-prop,--background-activated-opacity
ion-fab-button,css-prop,--background-focused
ion-fab-button,css-prop,--background-focused-opacity
ion-fab-button,css-prop,--background-hover
ion-fab-button,css-prop,--background-hover-opacity
ion-fab-button,css-prop,--border-color
ion-fab-button,css-prop,--border-radius
ion-fab-button,css-prop,--border-style
ion-fab-button,css-prop,--border-width
ion-fab-button,css-prop,--box-shadow
ion-fab-button,css-prop,--close-icon-font-size
ion-fab-button,css-prop,--color
ion-fab-button,css-prop,--color-activated
ion-fab-button,css-prop,--color-focused
@@ -369,6 +398,8 @@ ion-fab-button,css-prop,--padding-start
ion-fab-button,css-prop,--padding-top
ion-fab-button,css-prop,--ripple-color
ion-fab-button,css-prop,--transition
ion-fab-button,part,close-icon
ion-fab-button,part,native
ion-fab-list,shadow
ion-fab-list,prop,activated,boolean,false,false,false
@@ -404,6 +435,7 @@ ion-img,prop,src,string | undefined,undefined,false,false
ion-img,event,ionError,void,true
ion-img,event,ionImgDidLoad,void,true
ion-img,event,ionImgWillLoad,void,true
ion-img,part,image
ion-infinite-scroll,none
ion-infinite-scroll,prop,disabled,boolean,false,false,false
@@ -414,12 +446,12 @@ ion-infinite-scroll,event,ionInfinite,void,true
ion-infinite-scroll-content,none
ion-infinite-scroll-content,prop,loadingSpinner,"bubbles" | "circles" | "circular" | "crescent" | "dots" | "lines" | "lines-small" | null | undefined,undefined,false,false
ion-infinite-scroll-content,prop,loadingText,string | undefined,undefined,false,false
ion-infinite-scroll-content,prop,loadingText,IonicSafeString | string | undefined,undefined,false,false
ion-input,scoped
ion-input,prop,accept,string | undefined,undefined,false,false
ion-input,prop,autocapitalize,string,'off',false,false
ion-input,prop,autocomplete,"off" | "on",'off',false,false
ion-input,prop,autocomplete,"on" | "off" | "name" | "honorific-prefix" | "given-name" | "additional-name" | "family-name" | "honorific-suffix" | "nickname" | "email" | "username" | "new-password" | "current-password" | "one-time-code" | "organization-title" | "organization" | "street-address" | "address-line1" | "address-line2" | "address-line3" | "address-level4" | "address-level3" | "address-level2" | "address-level1" | "country" | "country-name" | "postal-code" | "cc-name" | "cc-given-name" | "cc-additional-name" | "cc-family-name" | "cc-number" | "cc-exp" | "cc-exp-month" | "cc-exp-year" | "cc-csc" | "cc-type" | "transaction-currency" | "transaction-amount" | "language" | "bday" | "bday-day" | "bday-month" | "bday-year" | "sex" | "tel" | "tel-country-code" | "tel-national" | "tel-area-code" | "tel-local" | "tel-extension" | "impp" | "url" | "photo",'off',false,false
ion-input,prop,autocorrect,"off" | "on",'off',false,false
ion-input,prop,autofocus,boolean,false,false,false
ion-input,prop,clearInput,boolean,false,false,false
@@ -427,6 +459,7 @@ ion-input,prop,clearOnEdit,boolean | undefined,undefined,false,false
ion-input,prop,color,string | undefined,undefined,false,false
ion-input,prop,debounce,number,0,false,false
ion-input,prop,disabled,boolean,false,false,false
ion-input,prop,enterkeyhint,"done" | "enter" | "go" | "next" | "previous" | "search" | "send" | undefined,undefined,false,false
ion-input,prop,inputmode,"decimal" | "email" | "none" | "numeric" | "search" | "tel" | "text" | "url" | undefined,undefined,false,false
ion-input,prop,max,string | undefined,undefined,false,false
ion-input,prop,maxlength,number | undefined,undefined,false,false
@@ -443,7 +476,7 @@ ion-input,prop,size,number | undefined,undefined,false,false
ion-input,prop,spellcheck,boolean,false,false,false
ion-input,prop,step,string | undefined,undefined,false,false
ion-input,prop,type,"date" | "email" | "number" | "password" | "search" | "tel" | "text" | "time" | "url",'text',false,false
ion-input,prop,value,null | string | undefined,'',false,false
ion-input,prop,value,null | number | string | undefined,'',false,false
ion-input,method,getInputElement,getInputElement() => Promise<HTMLInputElement>
ion-input,method,setFocus,setFocus() => Promise<void>
ion-input,event,ionBlur,void,true
@@ -465,25 +498,28 @@ ion-item,shadow
ion-item,prop,button,boolean,false,false,false
ion-item,prop,color,string | undefined,undefined,false,false
ion-item,prop,detail,boolean | undefined,undefined,false,false
ion-item,prop,detailIcon,string,'ios-arrow-forward',false,false
ion-item,prop,detailIcon,string,'chevron-forward',false,false
ion-item,prop,disabled,boolean,false,false,false
ion-item,prop,download,string | undefined,undefined,false,false
ion-item,prop,href,string | undefined,undefined,false,false
ion-item,prop,lines,"full" | "inset" | "none" | undefined,undefined,false,false
ion-item,prop,mode,"ios" | "md",undefined,false,false
ion-item,prop,rel,string | undefined,undefined,false,false
ion-item,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-item,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
ion-item,prop,target,string | undefined,undefined,false,false
ion-item,prop,type,"button" | "reset" | "submit",'button',false,false
ion-item,css-prop,--background
ion-item,css-prop,--background-activated
ion-item,css-prop,--background-activated-opacity
ion-item,css-prop,--background-focused
ion-item,css-prop,--background-focused-opacity
ion-item,css-prop,--background-hover
ion-item,css-prop,--background-hover-opacity
ion-item,css-prop,--border-color
ion-item,css-prop,--border-radius
ion-item,css-prop,--border-style
ion-item,css-prop,--border-width
ion-item,css-prop,--box-shadow
ion-item,css-prop,--color
ion-item,css-prop,--color-activated
ion-item,css-prop,--color-focused
@@ -508,6 +544,8 @@ ion-item,css-prop,--padding-start
ion-item,css-prop,--padding-top
ion-item,css-prop,--ripple-color
ion-item,css-prop,--transition
ion-item,part,detail-icon
ion-item,part,native
ion-item-divider,shadow
ion-item-divider,prop,color,string | undefined,undefined,false,false
@@ -538,6 +576,7 @@ ion-item-option,prop,target,string | undefined,undefined,false,false
ion-item-option,prop,type,"button" | "reset" | "submit",'button',false,false
ion-item-option,css-prop,--background
ion-item-option,css-prop,--color
ion-item-option,part,native
ion-item-options,none
ion-item-options,prop,side,"end" | "start",'end',false,false
@@ -549,7 +588,7 @@ ion-item-sliding,method,close,close() => Promise<void>
ion-item-sliding,method,closeOpened,closeOpened() => Promise<boolean>
ion-item-sliding,method,getOpenAmount,getOpenAmount() => Promise<number>
ion-item-sliding,method,getSlidingRatio,getSlidingRatio() => Promise<number>
ion-item-sliding,method,open,open(side: "start" | "end" | undefined) => Promise<void>
ion-item-sliding,method,open,open(side: Side | undefined) => Promise<void>
ion-item-sliding,event,ionDrag,any,true
ion-label,scoped
@@ -566,9 +605,14 @@ ion-list,method,closeSlidingItems,closeSlidingItems() => Promise<boolean>
ion-list-header,shadow
ion-list-header,prop,color,string | undefined,undefined,false,false
ion-list-header,prop,lines,"full" | "inset" | "none" | undefined,undefined,false,false
ion-list-header,prop,mode,"ios" | "md",undefined,false,false
ion-list-header,css-prop,--background
ion-list-header,css-prop,--border-color
ion-list-header,css-prop,--border-style
ion-list-header,css-prop,--border-width
ion-list-header,css-prop,--color
ion-list-header,css-prop,--inner-border-width
ion-loading,scoped
ion-loading,prop,animated,boolean,true,false,false
@@ -578,14 +622,14 @@ ion-loading,prop,duration,number,0,false,false
ion-loading,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-loading,prop,keyboardClose,boolean,true,false,false
ion-loading,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-loading,prop,message,string | undefined,undefined,false,false
ion-loading,prop,message,IonicSafeString | string | undefined,undefined,false,false
ion-loading,prop,mode,"ios" | "md",undefined,false,false
ion-loading,prop,showBackdrop,boolean,true,false,false
ion-loading,prop,spinner,"bubbles" | "circles" | "circular" | "crescent" | "dots" | "lines" | "lines-small" | null | undefined,undefined,false,false
ion-loading,prop,translucent,boolean,false,false,false
ion-loading,method,dismiss,dismiss(data?: any, role?: string | undefined) => Promise<boolean>
ion-loading,method,onDidDismiss,onDidDismiss() => Promise<OverlayEventDetail<any>>
ion-loading,method,onWillDismiss,onWillDismiss() => Promise<OverlayEventDetail<any>>
ion-loading,method,onDidDismiss,onDidDismiss<T = any>() => Promise<OverlayEventDetail<T>>
ion-loading,method,onWillDismiss,onWillDismiss<T = any>() => Promise<OverlayEventDetail<T>>
ion-loading,method,present,present() => Promise<void>
ion-loading,event,ionLoadingDidDismiss,OverlayEventDetail<any>,true
ion-loading,event,ionLoadingDidPresent,void,true
@@ -601,16 +645,11 @@ ion-loading,css-prop,--min-width
ion-loading,css-prop,--spinner-color
ion-loading,css-prop,--width
ion-loading-controller,none
ion-loading-controller,method,create,create(options?: LoadingOptions | undefined) => Promise<HTMLIonLoadingElement>
ion-loading-controller,method,dismiss,dismiss(data?: any, role?: string | undefined, id?: string | undefined) => Promise<boolean>
ion-loading-controller,method,getTop,getTop() => Promise<HTMLIonLoadingElement | undefined>
ion-menu,shadow
ion-menu,prop,contentId,string | undefined,undefined,false,false
ion-menu,prop,contentId,string | undefined,undefined,false,true
ion-menu,prop,disabled,boolean,false,false,false
ion-menu,prop,maxEdgeStart,number,50,false,false
ion-menu,prop,menuId,string | undefined,undefined,false,false
ion-menu,prop,menuId,string | undefined,undefined,false,true
ion-menu,prop,side,"end" | "start",'start',false,true
ion-menu,prop,swipeGesture,boolean,true,false,false
ion-menu,prop,type,string | undefined,undefined,false,false
@@ -631,16 +670,21 @@ ion-menu,css-prop,--max-width
ion-menu,css-prop,--min-height
ion-menu,css-prop,--min-width
ion-menu,css-prop,--width
ion-menu,part,backdrop
ion-menu,part,container
ion-menu-button,shadow
ion-menu-button,prop,autoHide,boolean,true,false,false
ion-menu-button,prop,color,string | undefined,undefined,false,false
ion-menu-button,prop,disabled,boolean,false,false,false
ion-menu-button,prop,menu,string | undefined,undefined,false,false
ion-menu-button,prop,mode,"ios" | "md",undefined,false,false
ion-menu-button,prop,type,"button" | "reset" | "submit",'button',false,false
ion-menu-button,css-prop,--background
ion-menu-button,css-prop,--background-focused
ion-menu-button,css-prop,--background-focused-opacity
ion-menu-button,css-prop,--background-hover
ion-menu-button,css-prop,--background-hover-opacity
ion-menu-button,css-prop,--border-radius
ion-menu-button,css-prop,--color
ion-menu-button,css-prop,--color-focused
@@ -649,20 +693,8 @@ ion-menu-button,css-prop,--padding-bottom
ion-menu-button,css-prop,--padding-end
ion-menu-button,css-prop,--padding-start
ion-menu-button,css-prop,--padding-top
ion-menu-controller,none
ion-menu-controller,method,close,close(menu?: string | null | undefined) => Promise<boolean>
ion-menu-controller,method,enable,enable(enable: boolean, menu?: string | null | undefined) => Promise<HTMLIonMenuElement | undefined>
ion-menu-controller,method,get,get(menu?: string | null | undefined) => Promise<HTMLIonMenuElement | undefined>
ion-menu-controller,method,getMenus,getMenus() => Promise<HTMLIonMenuElement[]>
ion-menu-controller,method,getOpen,getOpen() => Promise<HTMLIonMenuElement | undefined>
ion-menu-controller,method,isAnimating,isAnimating() => Promise<boolean>
ion-menu-controller,method,isEnabled,isEnabled(menu?: string | null | undefined) => Promise<boolean>
ion-menu-controller,method,isOpen,isOpen(menu?: string | null | undefined) => Promise<boolean>
ion-menu-controller,method,open,open(menu?: string | null | undefined) => Promise<boolean>
ion-menu-controller,method,registerAnimation,registerAnimation(name: string, animation: AnimationBuilder) => Promise<void>
ion-menu-controller,method,swipeGesture,swipeGesture(enable: boolean, menu?: string | null | undefined) => Promise<HTMLIonMenuElement | undefined>
ion-menu-controller,method,toggle,toggle(menu?: string | null | undefined) => Promise<boolean>
ion-menu-button,part,icon
ion-menu-button,part,native
ion-menu-toggle,shadow
ion-menu-toggle,prop,autoHide,boolean,true,false,false
@@ -678,10 +710,12 @@ ion-modal,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefin
ion-modal,prop,keyboardClose,boolean,true,false,false
ion-modal,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-modal,prop,mode,"ios" | "md",undefined,false,false
ion-modal,prop,presentingElement,HTMLElement | undefined,undefined,false,false
ion-modal,prop,showBackdrop,boolean,true,false,false
ion-modal,prop,swipeToClose,boolean,false,false,false
ion-modal,method,dismiss,dismiss(data?: any, role?: string | undefined) => Promise<boolean>
ion-modal,method,onDidDismiss,onDidDismiss() => Promise<OverlayEventDetail<any>>
ion-modal,method,onWillDismiss,onWillDismiss() => Promise<OverlayEventDetail<any>>
ion-modal,method,onDidDismiss,onDidDismiss<T = any>() => Promise<OverlayEventDetail<T>>
ion-modal,method,onWillDismiss,onWillDismiss<T = any>() => Promise<OverlayEventDetail<T>>
ion-modal,method,present,present() => Promise<void>
ion-modal,event,ionModalDidDismiss,OverlayEventDetail<any>,true
ion-modal,event,ionModalDidPresent,void,true
@@ -700,11 +734,6 @@ ion-modal,css-prop,--min-height
ion-modal,css-prop,--min-width
ion-modal,css-prop,--width
ion-modal-controller,none
ion-modal-controller,method,create,create<T extends ComponentRef>(options: ModalOptions<T>) => Promise<HTMLIonModalElement>
ion-modal-controller,method,dismiss,dismiss(data?: any, role?: string | undefined, id?: string | undefined) => Promise<boolean>
ion-modal-controller,method,getTop,getTop() => Promise<HTMLIonModalElement | undefined>
ion-nav,shadow
ion-nav,prop,animated,boolean,true,false,false
ion-nav,prop,animation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
@@ -730,6 +759,7 @@ ion-nav,event,ionNavWillChange,void,false
ion-nav-link,none
ion-nav-link,prop,component,Function | HTMLElement | ViewController | null | string | undefined,undefined,false,false
ion-nav-link,prop,componentProps,undefined | { [key: string]: any; },undefined,false,false
ion-nav-link,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-nav-link,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
ion-note,shadow
@@ -751,8 +781,8 @@ ion-picker,prop,mode,"ios" | "md",undefined,false,false
ion-picker,prop,showBackdrop,boolean,true,false,false
ion-picker,method,dismiss,dismiss(data?: any, role?: string | undefined) => Promise<boolean>
ion-picker,method,getColumn,getColumn(name: string) => Promise<PickerColumn | undefined>
ion-picker,method,onDidDismiss,onDidDismiss() => Promise<OverlayEventDetail<any>>
ion-picker,method,onWillDismiss,onWillDismiss() => Promise<OverlayEventDetail<any>>
ion-picker,method,onDidDismiss,onDidDismiss<T = any>() => Promise<OverlayEventDetail<T>>
ion-picker,method,onWillDismiss,onWillDismiss<T = any>() => Promise<OverlayEventDetail<T>>
ion-picker,method,present,present() => Promise<void>
ion-picker,event,ionPickerDidDismiss,OverlayEventDetail<any>,true
ion-picker,event,ionPickerDidPresent,void,true
@@ -772,11 +802,6 @@ ion-picker,css-prop,--min-height
ion-picker,css-prop,--min-width
ion-picker,css-prop,--width
ion-picker-controller,none
ion-picker-controller,method,create,create(options: PickerOptions) => Promise<HTMLIonPickerElement>
ion-picker-controller,method,dismiss,dismiss(data?: any, role?: string | undefined, id?: string | undefined) => Promise<boolean>
ion-picker-controller,method,getTop,getTop() => Promise<HTMLIonPickerElement | undefined>
ion-popover,scoped
ion-popover,prop,animated,boolean,true,false,false
ion-popover,prop,backdropDismiss,boolean,true,false,false
@@ -791,8 +816,8 @@ ion-popover,prop,mode,"ios" | "md",undefined,false,false
ion-popover,prop,showBackdrop,boolean,true,false,false
ion-popover,prop,translucent,boolean,false,false,false
ion-popover,method,dismiss,dismiss(data?: any, role?: string | undefined) => Promise<boolean>
ion-popover,method,onDidDismiss,onDidDismiss() => Promise<OverlayEventDetail<any>>
ion-popover,method,onWillDismiss,onWillDismiss() => Promise<OverlayEventDetail<any>>
ion-popover,method,onDidDismiss,onDidDismiss<T = any>() => Promise<OverlayEventDetail<T>>
ion-popover,method,onWillDismiss,onWillDismiss<T = any>() => Promise<OverlayEventDetail<T>>
ion-popover,method,present,present() => Promise<void>
ion-popover,event,ionPopoverDidDismiss,OverlayEventDetail<any>,true
ion-popover,event,ionPopoverDidPresent,void,true
@@ -808,11 +833,6 @@ ion-popover,css-prop,--min-height
ion-popover,css-prop,--min-width
ion-popover,css-prop,--width
ion-popover-controller,none
ion-popover-controller,method,create,create<T extends ComponentRef>(options: PopoverOptions<T>) => Promise<HTMLIonPopoverElement>
ion-popover-controller,method,dismiss,dismiss(data?: any, role?: string | undefined, id?: string | undefined) => Promise<boolean>
ion-popover-controller,method,getTop,getTop() => Promise<HTMLIonPopoverElement | undefined>
ion-progress-bar,shadow
ion-progress-bar,prop,buffer,number,1,false,false
ion-progress-bar,prop,color,string | undefined,undefined,false,false
@@ -825,7 +845,6 @@ ion-progress-bar,css-prop,--buffer-background
ion-progress-bar,css-prop,--progress-background
ion-radio,shadow
ion-radio,prop,checked,boolean,false,false,false
ion-radio,prop,color,string | undefined,undefined,false,false
ion-radio,prop,disabled,boolean,false,false,false
ion-radio,prop,mode,"ios" | "md",undefined,false,false
@@ -833,9 +852,12 @@ ion-radio,prop,name,string,this.inputId,false,false
ion-radio,prop,value,any,undefined,false,false
ion-radio,event,ionBlur,void,true
ion-radio,event,ionFocus,void,true
ion-radio,event,ionSelect,RadioChangeEventDetail,true
ion-radio,css-prop,--border-radius
ion-radio,css-prop,--color
ion-radio,css-prop,--color-checked
ion-radio,css-prop,--inner-border-radius
ion-radio,part,container
ion-radio,part,mark
ion-radio-group,none
ion-radio-group,prop,allowEmptySelection,boolean,false,false,false
@@ -871,6 +893,12 @@ ion-range,css-prop,--knob-box-shadow
ion-range,css-prop,--knob-size
ion-range,css-prop,--pin-background
ion-range,css-prop,--pin-color
ion-range,part,bar
ion-range,part,bar-active
ion-range,part,knob
ion-range,part,pin
ion-range,part,tick
ion-range,part,tick-active
ion-refresher,none
ion-refresher,prop,closeDuration,string,'280ms',false,false
@@ -888,11 +916,12 @@ ion-refresher,event,ionStart,void,true
ion-refresher-content,none
ion-refresher-content,prop,pullingIcon,null | string | undefined,undefined,false,false
ion-refresher-content,prop,pullingText,string | undefined,undefined,false,false
ion-refresher-content,prop,pullingText,IonicSafeString | string | undefined,undefined,false,false
ion-refresher-content,prop,refreshingSpinner,"bubbles" | "circles" | "circular" | "crescent" | "dots" | "lines" | "lines-small" | null | undefined,undefined,false,false
ion-refresher-content,prop,refreshingText,string | undefined,undefined,false,false
ion-refresher-content,prop,refreshingText,IonicSafeString | string | undefined,undefined,false,false
ion-reorder,shadow
ion-reorder,part,icon
ion-reorder-group,none
ion-reorder-group,prop,disabled,boolean,true,false,false
@@ -918,7 +947,7 @@ ion-router,none
ion-router,prop,root,string,'/',false,false
ion-router,prop,useHash,boolean,true,false,false
ion-router,method,back,back() => Promise<void>
ion-router,method,push,push(url: string, direction?: RouterDirection) => Promise<boolean>
ion-router,method,push,push(url: string, direction?: RouterDirection, animation?: AnimationBuilder | undefined) => Promise<boolean>
ion-router,event,ionRouteDidChange,RouterEventDetail,true
ion-router,event,ionRouteWillChange,RouterEventDetail,true
@@ -926,6 +955,7 @@ ion-router-link,shadow
ion-router-link,prop,color,string | undefined,undefined,false,false
ion-router-link,prop,href,string | undefined,undefined,false,false
ion-router-link,prop,rel,string | undefined,undefined,false,false
ion-router-link,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-router-link,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
ion-router-link,prop,target,string | undefined,undefined,false,false
ion-router-link,css-prop,--background
@@ -940,18 +970,19 @@ ion-row,shadow
ion-searchbar,scoped
ion-searchbar,prop,animated,boolean,false,false,false
ion-searchbar,prop,autocomplete,"off" | "on",'off',false,false
ion-searchbar,prop,autocomplete,"on" | "off" | "name" | "honorific-prefix" | "given-name" | "additional-name" | "family-name" | "honorific-suffix" | "nickname" | "email" | "username" | "new-password" | "current-password" | "one-time-code" | "organization-title" | "organization" | "street-address" | "address-line1" | "address-line2" | "address-line3" | "address-level4" | "address-level3" | "address-level2" | "address-level1" | "country" | "country-name" | "postal-code" | "cc-name" | "cc-given-name" | "cc-additional-name" | "cc-family-name" | "cc-number" | "cc-exp" | "cc-exp-month" | "cc-exp-year" | "cc-csc" | "cc-type" | "transaction-currency" | "transaction-amount" | "language" | "bday" | "bday-day" | "bday-month" | "bday-year" | "sex" | "tel" | "tel-country-code" | "tel-national" | "tel-area-code" | "tel-local" | "tel-extension" | "impp" | "url" | "photo",'off',false,false
ion-searchbar,prop,autocorrect,"off" | "on",'off',false,false
ion-searchbar,prop,cancelButtonIcon,string,config.get('backButtonIcon', 'md-arrow-back') as string,false,false
ion-searchbar,prop,cancelButtonIcon,string,config.get('backButtonIcon', 'arrow-back-sharp') as string,false,false
ion-searchbar,prop,cancelButtonText,string,'Cancel',false,false
ion-searchbar,prop,clearIcon,string | undefined,undefined,false,false
ion-searchbar,prop,color,string | undefined,undefined,false,false
ion-searchbar,prop,debounce,number,250,false,false
ion-searchbar,prop,disabled,boolean,false,false,false
ion-searchbar,prop,inputmode,"decimal" | "email" | "none" | "numeric" | "search" | "tel" | "text" | "url",'search',false,false
ion-searchbar,prop,enterkeyhint,"done" | "enter" | "go" | "next" | "previous" | "search" | "send" | undefined,undefined,false,false
ion-searchbar,prop,inputmode,"decimal" | "email" | "none" | "numeric" | "search" | "tel" | "text" | "url" | undefined,undefined,false,false
ion-searchbar,prop,mode,"ios" | "md",undefined,false,false
ion-searchbar,prop,placeholder,string,'Search',false,false
ion-searchbar,prop,searchIcon,string,'search',false,false
ion-searchbar,prop,searchIcon,string | undefined,undefined,false,false
ion-searchbar,prop,showCancelButton,"always" | "focus" | "never",'never',false,false
ion-searchbar,prop,spellcheck,boolean,false,false,false
ion-searchbar,prop,type,"email" | "number" | "password" | "search" | "tel" | "text" | "url",'search',false,false
@@ -965,6 +996,7 @@ ion-searchbar,event,ionClear,void,true
ion-searchbar,event,ionFocus,void,true
ion-searchbar,event,ionInput,KeyboardEvent,true
ion-searchbar,css-prop,--background
ion-searchbar,css-prop,--border-radius
ion-searchbar,css-prop,--box-shadow
ion-searchbar,css-prop,--cancel-button-color
ion-searchbar,css-prop,--clear-button-color
@@ -975,37 +1007,40 @@ ion-searchbar,css-prop,--placeholder-font-style
ion-searchbar,css-prop,--placeholder-font-weight
ion-searchbar,css-prop,--placeholder-opacity
ion-segment,scoped
ion-segment,shadow
ion-segment,prop,color,string | undefined,undefined,false,false
ion-segment,prop,disabled,boolean,false,false,false
ion-segment,prop,mode,"ios" | "md",undefined,false,false
ion-segment,prop,scrollable,boolean,false,false,false
ion-segment,prop,value,null | string | undefined,undefined,false,false
ion-segment,event,ionChange,SegmentChangeEventDetail,true
ion-segment,css-prop,--background
ion-segment-button,shadow
ion-segment-button,prop,checked,boolean,false,false,false
ion-segment-button,prop,disabled,boolean,false,false,false
ion-segment-button,prop,layout,"icon-bottom" | "icon-end" | "icon-hide" | "icon-start" | "icon-top" | "label-hide" | undefined,'icon-top',false,false
ion-segment-button,prop,mode,"ios" | "md",undefined,false,false
ion-segment-button,prop,type,"button" | "reset" | "submit",'button',false,false
ion-segment-button,prop,value,string,'ion-sb-' + (ids++),false,false
ion-segment-button,event,ionSelect,void,true
ion-segment-button,css-prop,--background
ion-segment-button,css-prop,--background-activated
ion-segment-button,css-prop,--background-checked
ion-segment-button,css-prop,--background-focused
ion-segment-button,css-prop,--background-focused-opacity
ion-segment-button,css-prop,--background-hover
ion-segment-button,css-prop,--background-hover-opacity
ion-segment-button,css-prop,--border-color
ion-segment-button,css-prop,--border-radius
ion-segment-button,css-prop,--border-style
ion-segment-button,css-prop,--border-width
ion-segment-button,css-prop,--color
ion-segment-button,css-prop,--color-activated
ion-segment-button,css-prop,--color-checked
ion-segment-button,css-prop,--color-checked-disabled
ion-segment-button,css-prop,--color-disabled
ion-segment-button,css-prop,--color-focused
ion-segment-button,css-prop,--color-hover
ion-segment-button,css-prop,--indicator-box-shadow
ion-segment-button,css-prop,--indicator-color
ion-segment-button,css-prop,--indicator-color-checked
ion-segment-button,css-prop,--indicator-height
ion-segment-button,css-prop,--indicator-transform
ion-segment-button,css-prop,--indicator-transition
ion-segment-button,css-prop,--margin-bottom
ion-segment-button,css-prop,--margin-end
ion-segment-button,css-prop,--margin-start
@@ -1015,6 +1050,8 @@ ion-segment-button,css-prop,--padding-end
ion-segment-button,css-prop,--padding-start
ion-segment-button,css-prop,--padding-top
ion-segment-button,css-prop,--transition
ion-segment-button,part,indicator
ion-segment-button,part,native
ion-select,shadow
ion-select,prop,cancelText,string,'Cancel',false,false
@@ -1040,10 +1077,12 @@ ion-select,css-prop,--padding-start
ion-select,css-prop,--padding-top
ion-select,css-prop,--placeholder-color
ion-select,css-prop,--placeholder-opacity
ion-select,part,icon
ion-select,part,placeholder
ion-select,part,text
ion-select-option,shadow
ion-select-option,prop,disabled,boolean,false,false,false
ion-select-option,prop,selected,boolean,false,false,false
ion-select-option,prop,value,any,undefined,false,false
ion-skeleton-text,shadow
@@ -1106,7 +1145,7 @@ ion-spinner,prop,paused,boolean,false,false,false
ion-spinner,css-prop,--color
ion-split-pane,shadow
ion-split-pane,prop,contentId,string | undefined,undefined,false,false
ion-split-pane,prop,contentId,string | undefined,undefined,false,true
ion-split-pane,prop,disabled,boolean,false,false,false
ion-split-pane,prop,when,boolean | string,QUERY['lg'],false,false
ion-split-pane,event,ionSplitPaneVisible,{ visible: boolean; },true
@@ -1141,13 +1180,16 @@ ion-tab-button,prop,tab,string | undefined,undefined,false,false
ion-tab-button,prop,target,string | undefined,undefined,false,false
ion-tab-button,css-prop,--background
ion-tab-button,css-prop,--background-focused
ion-tab-button,css-prop,--background-focused-opacity
ion-tab-button,css-prop,--color
ion-tab-button,css-prop,--color-focused
ion-tab-button,css-prop,--color-selected
ion-tab-button,css-prop,--padding-bottom
ion-tab-button,css-prop,--padding-end
ion-tab-button,css-prop,--padding-start
ion-tab-button,css-prop,--padding-top
ion-tab-button,css-prop,--ripple-color
ion-tab-button,part,native
ion-tabs,shadow
ion-tabs,method,getSelected,getSelected() => Promise<string | undefined>
@@ -1169,6 +1211,8 @@ ion-textarea,prop,color,string | undefined,undefined,false,false
ion-textarea,prop,cols,number | undefined,undefined,false,false
ion-textarea,prop,debounce,number,0,false,false
ion-textarea,prop,disabled,boolean,false,false,false
ion-textarea,prop,enterkeyhint,"done" | "enter" | "go" | "next" | "previous" | "search" | "send" | undefined,undefined,false,false
ion-textarea,prop,inputmode,"decimal" | "email" | "none" | "numeric" | "search" | "tel" | "text" | "url" | undefined,undefined,false,false
ion-textarea,prop,maxlength,number | undefined,undefined,false,false
ion-textarea,prop,minlength,number | undefined,undefined,false,false
ion-textarea,prop,mode,"ios" | "md",undefined,false,false
@@ -1217,13 +1261,13 @@ ion-toast,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefin
ion-toast,prop,header,string | undefined,undefined,false,false
ion-toast,prop,keyboardClose,boolean,false,false,false
ion-toast,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-toast,prop,message,string | undefined,undefined,false,false
ion-toast,prop,message,IonicSafeString | string | undefined,undefined,false,false
ion-toast,prop,mode,"ios" | "md",undefined,false,false
ion-toast,prop,position,"bottom" | "middle" | "top",'bottom',false,false
ion-toast,prop,translucent,boolean,false,false,false
ion-toast,method,dismiss,dismiss(data?: any, role?: string | undefined) => Promise<boolean>
ion-toast,method,onDidDismiss,onDidDismiss() => Promise<OverlayEventDetail<any>>
ion-toast,method,onWillDismiss,onWillDismiss() => Promise<OverlayEventDetail<any>>
ion-toast,method,onDidDismiss,onDidDismiss<T = any>() => Promise<OverlayEventDetail<T>>
ion-toast,method,onWillDismiss,onWillDismiss<T = any>() => Promise<OverlayEventDetail<T>>
ion-toast,method,present,present() => Promise<void>
ion-toast,event,ionToastDidDismiss,OverlayEventDetail<any>,true
ion-toast,event,ionToastDidPresent,void,true
@@ -1244,13 +1288,9 @@ ion-toast,css-prop,--max-width
ion-toast,css-prop,--min-height
ion-toast,css-prop,--min-width
ion-toast,css-prop,--start
ion-toast,css-prop,--white-space
ion-toast,css-prop,--width
ion-toast-controller,none
ion-toast-controller,method,create,create(options?: ToastOptions | undefined) => Promise<HTMLIonToastElement>
ion-toast-controller,method,dismiss,dismiss(data?: any, role?: string | undefined, id?: string | undefined) => Promise<boolean>
ion-toast-controller,method,getTop,getTop() => Promise<HTMLIonToastElement | undefined>
ion-toggle,shadow
ion-toggle,prop,checked,boolean,false,false,false
ion-toggle,prop,color,string | undefined,undefined,false,false
@@ -1263,8 +1303,18 @@ ion-toggle,event,ionChange,ToggleChangeEventDetail,true
ion-toggle,event,ionFocus,void,true
ion-toggle,css-prop,--background
ion-toggle,css-prop,--background-checked
ion-toggle,css-prop,--border-radius
ion-toggle,css-prop,--handle-background
ion-toggle,css-prop,--handle-background-checked
ion-toggle,css-prop,--handle-border-radius
ion-toggle,css-prop,--handle-box-shadow
ion-toggle,css-prop,--handle-height
ion-toggle,css-prop,--handle-max-height
ion-toggle,css-prop,--handle-spacing
ion-toggle,css-prop,--handle-transition
ion-toggle,css-prop,--handle-width
ion-toggle,part,handle
ion-toggle,part,track
ion-toolbar,shadow
ion-toolbar,prop,color,string | undefined,undefined,false,false

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/core",
"version": "5.0.0-beta.0",
"version": "5.2.0",
"description": "Base components for Ionic",
"keywords": [
"ionic",
@@ -30,16 +30,16 @@
"loader/"
],
"dependencies": {
"ionicons": "^4.6.3",
"ionicons": "^5.0.1",
"tslib": "^1.10.0"
},
"devDependencies": {
"@stencil/core": "1.7.5",
"@stencil/sass": "1.0.1",
"@types/jest": "24.0.21",
"@stencil/core": "1.14.0",
"@stencil/sass": "1.3.1",
"@types/jest": "24.9.1",
"@types/node": "12.12.3",
"@types/puppeteer": "1.19.1",
"@types/swiper": "4.4.4",
"@types/swiper": "5.3.1",
"aws-sdk": "^2.497.0",
"clean-css-cli": "^4.1.11",
"domino": "^2.1.3",
@@ -49,13 +49,13 @@
"np": "^5.0.3",
"pixelmatch": "4.0.2",
"puppeteer": "1.20.0",
"rollup": "1.19.4",
"rollup": "1.32.0",
"rollup-plugin-node-resolve": "5.2.0",
"rollup-plugin-virtual": "^1.0.1",
"sass": "^1.22.9",
"stylelint": "10.1.0",
"stylelint-order": "3.0.1",
"swiper": "4.5.1",
"swiper": "5.4.1",
"tslint": "^5.10.0",
"tslint-ionic-rules": "0.0.21",
"tslint-react": "^3.6.0"
@@ -65,6 +65,7 @@
"build.vendor": "rollup --config ./scripts/swiper.rollup.config.js",
"build.css": "npm run css.sass && npm run css.minify",
"build.debug": "npm run clean && stencil build --debug",
"build.docs": "stencil build --docs",
"build.docs.json": "stencil build --docs-json dist/docs.json",
"clean": "node scripts/clean.js",
"cdnloader": "node scripts/copy-cdn-loader.js",

View File

@@ -35,6 +35,9 @@ function generateComponent(component, content) {
component.styles.forEach(prop => {
content.push(`${component.tag},css-prop,${prop.name}`);
});
component.parts.forEach(part => {
content.push(`${component.tag},part,${part.name}`);
});
}
exports.apiSpecGenerator = apiSpecGenerator;

12432
core/src/components.d.ts vendored
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,54 +0,0 @@
import { Build, Component, ComponentInterface, Method } from '@stencil/core';
import { ActionSheetOptions, OverlayController } from '../../interface';
import { createOverlay, dismissOverlay, getOverlay } from '../../utils/overlays';
/**
* @deprecated Use the `actionSheetController` exported from core.
*/
@Component({
tag: 'ion-action-sheet-controller'
})
export class ActionSheetController implements ComponentInterface, OverlayController {
constructor() {
if (Build.isDev) {
console.warn(`[DEPRECATED][ion-action-sheet-controller] Use the actionSheetController export from @ionic/core:
import { actionSheetController } from '@ionic/core';
const actionSheet = await actionSheetController.create({...});`);
}
}
/**
* Create an action sheet overlay with action sheet options.
*
* @param options The options to use to create the action sheet.
*/
@Method()
create(options: ActionSheetOptions): Promise<HTMLIonActionSheetElement> {
return createOverlay('ion-action-sheet', options);
}
/**
* Dismiss the open action sheet overlay.
*
* @param data Any data to emit in the dismiss events.
* @param role The role of the element that is dismissing the action sheet.
* This can be useful in a button handler for determining which button was
* clicked to dismiss the action sheet.
* Some examples include: ``"cancel"`, `"destructive"`, "selected"`, and `"backdrop"`.
* @param id The id of the action sheet to dismiss. If an id is not provided, it will dismiss the most recently opened action sheet.
*/
@Method()
dismiss(data?: any, role?: string, id?: string) {
return dismissOverlay(document, data, role, 'ion-action-sheet', id);
}
/**
* Get the most recently opened action sheet overlay.
*/
@Method()
async getTop(): Promise<HTMLIonActionSheetElement | undefined> {
return getOverlay(document, 'ion-action-sheet') as HTMLIonActionSheetElement;
}
}

View File

@@ -1,45 +0,0 @@
# ion-action-sheet-controller
Action Sheet controllers programmatically control the action sheet component. Action Sheets can be created and dismissed from the action sheet controller. View the [Action Sheet](../action-sheet) documentation for a full list of options to pass upon creation.
<!-- Auto Generated Below -->
> **[DEPRECATED]** Use the `actionSheetController` exported from core.
## Methods
### `create(options: ActionSheetOptions) => Promise<HTMLIonActionSheetElement>`
Create an action sheet overlay with action sheet options.
#### Returns
Type: `Promise<HTMLIonActionSheetElement>`
### `dismiss(data?: any, role?: string | undefined, id?: string | undefined) => Promise<boolean>`
Dismiss the open action sheet overlay.
#### Returns
Type: `Promise<boolean>`
### `getTop() => Promise<HTMLIonActionSheetElement | undefined>`
Get the most recently opened action sheet overlay.
#### Returns
Type: `Promise<HTMLIonActionSheetElement | undefined>`
----------------------------------------------
*Built with [StencilJS](https://stenciljs.com/)*

View File

@@ -21,5 +21,5 @@ export interface ActionSheetButton {
role?: 'cancel' | 'destructive' | 'selected' | string;
icon?: string;
cssClass?: string | string[];
handler?: () => boolean | void | Promise<boolean>;
handler?: () => boolean | void | Promise<boolean | void>;
}

View File

@@ -6,9 +6,18 @@
:host {
--background: #{$action-sheet-ios-background-color};
--background-selected: #{$action-sheet-ios-button-background-selected};
--background-activated: #{$action-sheet-ios-button-background-activated};
--backdrop-opacity: var(--ion-backdrop-opacity, 0.4);
--button-background: #{$action-sheet-ios-button-background};
--button-background-activated: #{$action-sheet-ios-button-background-activated};
--button-background-activated-opacity: .08;
--button-background-hover: currentColor;
--button-background-hover-opacity: .04;
--button-background-focused: currentColor;
--button-background-focused-opacity: .12;
--button-background-selected: #{$action-sheet-ios-button-background-selected};
--button-background-selected-opacity: 1;
--button-color: #{$action-sheet-ios-button-text-color};
--color: #{$action-sheet-ios-title-color};
text-align: $action-sheet-ios-text-align;
}
@@ -32,8 +41,6 @@
.action-sheet-group {
@include border-radius($action-sheet-ios-border-radius);
@include margin(null, null, $action-sheet-ios-group-margin-bottom - 2, null);
overflow: hidden;
}
.action-sheet-group:first-child {
@@ -69,13 +76,13 @@
backdrop-filter: $action-sheet-ios-button-translucent-filter;
}
:host(.action-sheet-translucent) .action-sheet-button.activated {
:host(.action-sheet-translucent) .action-sheet-button.ion-activated {
background-color: $action-sheet-ios-translucent-background-color-activated;
background-image: none;
}
:host(.action-sheet-translucent) .action-sheet-cancel {
background: var(--background-selected);
background: var(--button-background-selected);
}
}
@@ -84,16 +91,8 @@
// Border is made with a linear gradient in order
// to get the proper color and iOS blur effect
.action-sheet-title,
.action-sheet-button {
background-color: transparent;
background-image: linear-gradient(0deg, $action-sheet-ios-button-border-color, $action-sheet-ios-button-border-color 50%, transparent 50%);
background-repeat: no-repeat;
/* stylelint-disable-next-line all */
background-position: bottom;
background-size: 100% 1px;
.action-sheet-title {
background: $action-sheet-ios-button-background;
}
@@ -126,8 +125,6 @@
height: $action-sheet-ios-button-height;
color: var(--color, $action-sheet-ios-button-text-color);
font-size: $action-sheet-ios-button-font-size;
contain: strict;
@@ -137,6 +134,8 @@
@include margin-horizontal(null, $action-sheet-ios-button-icon-padding-right);
font-size: $action-sheet-ios-button-icon-font-size;
pointer-events: none;
}
.action-sheet-button:last-child {
@@ -144,17 +143,30 @@
}
.action-sheet-selected {
background: var(--background-selected);
font-weight: bold;
}
.action-sheet-destructive {
.action-sheet-cancel {
font-weight: $action-sheet-ios-button-cancel-font-weight;
&::after {
background: var(--button-background-selected);
opacity: var(--button-background-selected-opacity);
}
}
// iOS Action Sheet Button: Destructive
// ---------------------------------------------------
.action-sheet-destructive,
.action-sheet-destructive.ion-activated,
.action-sheet-destructive.ion-focused {
color: $action-sheet-ios-button-destructive-text-color;
}
.action-sheet-cancel {
background: var(--background-selected);
font-weight: $action-sheet-ios-button-cancel-font-weight;
@media (any-hover: hover) {
.action-sheet-destructive:hover {
color: $action-sheet-ios-button-destructive-text-color;
}
}

View File

@@ -105,21 +105,9 @@ $action-sheet-ios-button-icon-font-size: 28px !default;
/// @prop - Padding right of the action sheet button icon
$action-sheet-ios-button-icon-padding-right: .1em !default;
/// @prop - Height of the action sheet button icon
$action-sheet-ios-button-icon-height: .7em !default;
/// @prop - Margin top of the action sheet button icon
$action-sheet-ios-button-icon-margin-top: -10px !default;
/// @prop - Font size of the action sheet button
$action-sheet-ios-button-font-size: 20px !default;
/// @prop - Border width of the action sheet button
$action-sheet-ios-button-border-width: $hairlines-width !default;
/// @prop - Border style of the action sheet button
$action-sheet-ios-button-border-style: solid !default;
/// @prop - Border color alpha of the action sheet button
$action-sheet-ios-button-border-color-alpha: .08 !default;
@@ -127,16 +115,13 @@ $action-sheet-ios-button-border-color-alpha: .08 !default;
$action-sheet-ios-button-border-color: rgba($text-color-rgb, $action-sheet-ios-button-border-color-alpha) !default;
/// @prop - Background color of the action sheet button
$action-sheet-ios-button-background: transparent !default;
/// @prop - Background color alpha of the activated action sheet button
$action-sheet-ios-button-background-alpha-activated: .08 !default;
$action-sheet-ios-button-background: linear-gradient(0deg, $action-sheet-ios-button-border-color, $action-sheet-ios-button-border-color 50%, transparent 50%) bottom / 100% 1px no-repeat transparent !default;
/// @prop - Background color of the activated action sheet button
$action-sheet-ios-button-background-activated: rgba($text-color-rgb, $action-sheet-ios-button-background-alpha-activated) !default;
$action-sheet-ios-button-background-activated: $text-color !default;
/// @prop - Background color of the selected action sheet button
$action-sheet-ios-button-background-selected: $background-color !default;
$action-sheet-ios-button-background-selected: var(--ion-color-step-150, $background-color) !default;
/// @prop - Destructive text color of the action sheet button
$action-sheet-ios-button-destructive-text-color: ion-color(danger, base) !default;

View File

@@ -6,9 +6,18 @@
:host {
--background: #{$action-sheet-md-background-color};
--background-selected: #{var(--background, $action-sheet-md-button-background-selected)};
--background-activated: var(--background);
--backdrop-opacity: var(--ion-backdrop-opacity, 0.32);
--button-background: transparent;
--button-background-selected: currentColor;
--button-background-selected-opacity: 0;
--button-background-activated: transparent;
--button-background-activated-opacity: 0;
--button-background-hover: currentColor;
--button-background-hover-opacity: .04;
--button-background-focused: currentColor;
--button-background-focused-opacity: .12;
--button-color: #{$action-sheet-md-button-text-color};
--color: #{$action-sheet-md-title-color};
}
.action-sheet-title {
@@ -52,9 +61,6 @@
height: $action-sheet-md-button-height;
background: transparent;
color: var(--color, $action-sheet-md-button-text-color);
font-size: $action-sheet-md-button-font-size;
text-align: $action-sheet-md-text-align;
@@ -67,7 +73,7 @@
@include padding(null, null, 4px, null);
@include margin($action-sheet-md-icon-margin-top, $action-sheet-md-icon-margin-end, $action-sheet-md-icon-margin-bottom, $action-sheet-md-icon-margin-start);
color: var(--color, $action-sheet-md-icon-color);
color: var(--color);
font-size: $action-sheet-md-icon-font-size;
}

View File

@@ -87,13 +87,6 @@ $action-sheet-md-button-padding-start: $action-sheet-md-button-
/// @prop - Background color of the action sheet button
$action-sheet-md-button-background: transparent !default;
/// @prop - Background color of the action sheet activated button
$action-sheet-md-button-background-activated: $background-color-step-50 !default;
/// @prop - Background color of the selected action sheet button
$action-sheet-md-button-background-selected: null !default;
// Action Sheet Icon
// --------------------------------------------------

View File

@@ -6,9 +6,6 @@
:host {
/**
* @prop --background: Background of the action sheet group
* @prop --background-activated: Background of the action sheet button when pressed
* @prop --background-selected: Background of the selected action sheet button
*
* @prop --color: Color of the action sheet text
*
* @prop --min-width: Minimum width of the action sheet
@@ -20,14 +17,34 @@
* @prop --max-height: Maximum height of the action sheet
*
* @prop --backdrop-opacity: Opacity of the backdrop
*
* @prop --button-background: Background of the action sheet button
* @prop --button-background-activated: Background of the action sheet button when pressed. Note: setting this will interfere with the Material Design ripple.
* @prop --button-background-activated-opacity: Opacity of the action sheet button background when pressed
* @prop --button-background-hover: Background of the action sheet button on hover
* @prop --button-background-hover-opacity: Opacity of the action sheet button background on hover
* @prop --button-background-focused: Background of the action sheet button when tabbed to
* @prop --button-background-focused-opacity: Opacity of the action sheet button background when tabbed to
* @prop --button-background-selected: Background of the selected action sheet button
* @prop --button-background-selected-opacity: Opacity of the selected action sheet button background
*
* @prop --button-color: Color of the action sheet button
* @prop --button-color-activated: Color of the action sheet button when pressed
* @prop --button-color-hover: Color of the action sheet button on hover
* @prop --button-color-focused: Color of the action sheet button when tabbed to
* @prop --button-color-selected: Color of the selected action sheet button
*/
--color: initial;
--button-color-activated: var(--button-color);
--button-color-focused: var(--button-color);
--button-color-hover: var(--button-color);
--button-color-selected: var(--button-color);
--min-width: auto;
--width: #{$action-sheet-width};
--max-width: #{$action-sheet-max-width};
--min-height: auto;
--height: 100%;
--max-height: 100%;
--max-height: calc(100% - (var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));
@include font-smoothing();
@include position(0, 0, 0, 0);
@@ -35,6 +52,8 @@
display: block;
position: fixed;
outline: none;
font-family: $font-family-base;
touch-action: none;
@@ -68,6 +87,7 @@
.action-sheet-button {
display: block;
position: relative;
width: 100%;
@@ -75,23 +95,29 @@
outline: none;
font-family: inherit;
}
background: var(--button-background);
color: var(--button-color);
.action-sheet-button.activated {
background: var(--background-activated);
font-family: inherit;
overflow: hidden;
}
.action-sheet-button-inner {
display: flex;
position: relative;
flex-flow: row nowrap;
flex-shrink: 0;
align-items: center;
justify-content: center;
pointer-events: none;
width: 100%;
height: 100%;
z-index: 1;
}
.action-sheet-container {
@@ -124,6 +150,67 @@
overflow: hidden;
}
// Action Sheet: States
// --------------------------------------------------
.action-sheet-button::after {
@include button-state();
}
// Action Sheet: Selected
// --------------------------------------------------
.action-sheet-selected {
background: var(--background-selected);
}
color: var(--button-color-selected);
&::after {
background: var(--button-background-selected);
opacity: var(--button-background-selected-opacity);
}
}
// Action Sheet: Activated
// --------------------------------------------------
.action-sheet-button.ion-activated {
color: var(--button-color-activated);
&::after {
background: var(--button-background-activated);
opacity: var(--button-background-activated-opacity);
}
}
// Action Sheet: Focused
// --------------------------------------------------
.action-sheet-button.ion-focused {
color: var(--button-color-focused);
&::after {
background: var(--button-background-focused);
opacity: var(--button-background-focused-opacity);
}
}
// Action Sheet: Hover
// --------------------------------------------------
@media (any-hover: hover) {
.action-sheet-button:hover {
color: var(--button-color-hover);
&::after {
background: var(--button-background-hover);
opacity: var(--button-background-hover-opacity);
}
}
}

View File

@@ -1,7 +1,9 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Method, Prop, h } from '@stencil/core';
import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Method, Prop, h, readTask } from '@stencil/core';
import { getIonMode } from '../../global/ionic-global';
import { ActionSheetButton, AnimationBuilder, CssClassMap, OverlayEventDetail, OverlayInterface } from '../../interface';
import { Gesture } from '../../utils/gesture';
import { createButtonActiveGesture } from '../../utils/gesture/button-active';
import { BACKDROP, dismiss, eventMethod, isCancel, prepareOverlay, present, safeCall } from '../../utils/overlays';
import { getClassMap } from '../../utils/theme';
@@ -25,7 +27,9 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
presented = false;
animation?: any;
mode = getIonMode(this);
private wrapperEl?: HTMLElement;
private groupEl?: HTMLElement;
private gesture?: Gesture;
@Element() el!: HTMLIonActionSheetElement;
@@ -135,7 +139,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
* Returns a promise that resolves when the action sheet did dismiss.
*/
@Method()
onDidDismiss(): Promise<OverlayEventDetail> {
onDidDismiss<T = any>(): Promise<OverlayEventDetail<T>> {
return eventMethod(this.el, 'ionActionSheetDidDismiss');
}
@@ -144,7 +148,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
*
*/
@Method()
onWillDismiss(): Promise<OverlayEventDetail> {
onWillDismiss<T = any>(): Promise<OverlayEventDetail<T>> {
return eventMethod(this.el, 'ionActionSheetWillDismiss');
}
@@ -193,6 +197,35 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
}
}
componentDidUnload() {
if (this.gesture) {
this.gesture.destroy();
this.gesture = undefined;
}
}
componentDidLoad() {
/**
* Do not create gesture if:
* 1. A gesture already exists
* 2. App is running in MD mode
* 3. A wrapper ref does not exist
*/
const { groupEl, wrapperEl } = this;
if (this.gesture || getIonMode(this) === 'md' || !wrapperEl || !groupEl) { return; }
readTask(() => {
const isScrollable = groupEl.scrollHeight > groupEl.clientHeight;
if (!isScrollable) {
this.gesture = createButtonActiveGesture(
wrapperEl,
(refEl: HTMLElement) => refEl.classList.contains('action-sheet-button')
);
this.gesture.enable(true);
}
});
}
render() {
const mode = getIonMode(this);
const allButtons = this.getButtons();
@@ -203,6 +236,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
<Host
role="dialog"
aria-modal="true"
tabindex="-1"
style={{
zIndex: `${20000 + this.overlayIndex}`,
}}
@@ -216,9 +250,9 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
onIonBackdropTap={this.onBackdropTap}
>
<ion-backdrop tappable={this.backdropDismiss}/>
<div class="action-sheet-wrapper" role="dialog">
<div class="action-sheet-wrapper" role="dialog" ref={el => this.wrapperEl = el}>
<div class="action-sheet-container">
<div class="action-sheet-group">
<div class="action-sheet-group" ref={el => this.groupEl = el}>
{this.header !== undefined &&
<div class="action-sheet-title">
{this.header}
@@ -226,7 +260,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
</div>
}
{buttons.map(b =>
<button type="button" ion-activatable class={buttonClass(b)} onClick={() => this.buttonClick(b)}>
<button type="button" class={buttonClass(b)} onClick={() => this.buttonClick(b)}>
<span class="action-sheet-button-inner">
{b.icon && <ion-icon icon={b.icon} lazy={false} class="action-sheet-icon" />}
{b.text}
@@ -252,6 +286,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
/>}
{cancelButton.text}
</span>
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
</button>
</div>
}
@@ -266,6 +301,7 @@ const buttonClass = (button: ActionSheetButton): CssClassMap => {
return {
'action-sheet-button': true,
'ion-activatable': true,
'ion-focusable': true,
[`action-sheet-${button.role}`]: button.role !== undefined,
...getClassMap(button.cssClass),
};

View File

@@ -11,7 +11,11 @@ export const iosEnterAnimation = (baseEl: HTMLElement): Animation => {
backdropAnimation
.addElement(baseEl.querySelector('ion-backdrop')!)
.fromTo('opacity', 0.01, 'var(--backdrop-opacity)');
.fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
.beforeStyles({
'pointer-events': 'none'
})
.afterClearStyles(['pointer-events']);
wrapperAnimation
.addElement(baseEl.querySelector('.action-sheet-wrapper')!)

View File

@@ -11,7 +11,11 @@ export const mdEnterAnimation = (baseEl: HTMLElement): Animation => {
backdropAnimation
.addElement(baseEl.querySelector('ion-backdrop')!)
.fromTo('opacity', 0.01, 'var(--backdrop-opacity)');
.fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
.beforeStyles({
'pointer-events': 'none'
})
.afterClearStyles(['pointer-events']);
wrapperAnimation
.addElement(baseEl.querySelector('.action-sheet-wrapper')!)

View File

@@ -2,14 +2,38 @@
An Action Sheet is a dialog that displays a set of options. It appears on top of the app's content, and must be manually dismissed by the user before they can resume interaction with the app. Destructive options are made obvious in `ios` mode. There are multiple ways to dismiss the action sheet, including tapping the backdrop or hitting the escape key on desktop.
### Creating
An action sheet can be created by the [Action Sheet Controller](../action-sheet-controller) from an array of `buttons`, with each button including properties for its `text`, and optionally a `handler` and `role`. If a handler returns `false` then the action sheet will not be dismissed. An action sheet can also optionally have a `header` and a `subHeader`.
### Buttons
## Buttons
A button's `role` property can either be `destructive` or `cancel`. Buttons without a role property will have the default look for the platform. Buttons with the `cancel` role will always load as the bottom button, no matter where they are in the array. All other buttons will be displayed in the order they have been added to the `buttons` array. Note: We recommend that `destructive` buttons are always the first button in the array, making them the top button. Additionally, if the action sheet is dismissed by tapping the backdrop, then it will fire the handler from the button with the cancel role.
## Customization
Action Sheet uses scoped encapsulation, which means it will automatically scope its CSS by appending each of the styles with an additional class at runtime. Overriding scoped selectors in CSS requires a [higher specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity) selector.
We recommend passing a custom class to `cssClass` in the `create` method and using that to add custom styles to the host and inner elements. This property can also accept multiple classes separated by spaces. View the [Usage](#usage) section for an example of how to pass a class using `cssClass`.
```css
/* DOES NOT WORK - not specific enough */
.action-sheet-group {
background: #e5e5e5;
}
/* Works - pass "my-custom-class" in cssClass to increase specificity */
.my-custom-class .action-sheet-group {
background: #e5e5e5;
}
```
Any of the defined [CSS Custom Properties](#css-custom-properties) can be used to style the Action Sheet without needing to target individual elements:
```css
.my-custom-class {
--background: #e5e5e5;
}
```
> If you are building an Ionic Angular app, the styles need to be added to a global stylesheet file. Read [Style Placement](#style-placement) in the Angular section below for more information.
<!-- Auto Generated Below -->
@@ -34,6 +58,7 @@ export class ActionSheetExample {
async presentActionSheet() {
const actionSheet = await this.actionSheetController.create({
header: 'Albums',
cssClass: 'my-custom-class',
buttons: [{
text: 'Delete',
role: 'destructive',
@@ -49,7 +74,7 @@ export class ActionSheetExample {
}
}, {
text: 'Play (open modal)',
icon: 'arrow-dropright-circle',
icon: 'caret-forward-circle',
handler: () => {
console.log('Play clicked');
}
@@ -75,14 +100,19 @@ export class ActionSheetExample {
```
### Style Placement
In Angular, the CSS of a specific page is scoped only to elements of that page. Even though the Action Sheet can be presented from within a page, the `ion-action-sheet` element is appended outside of the current page. This means that any custom styles need to go in a global stylesheet file. In an Ionic Angular starter this can be the `src/global.scss` file or you can register a new global style file by [adding to the `styles` build option in `angular.json`](https://angular.io/guide/workspace-config#style-script-config).
### Javascript
```javascript
async function presentActionSheet() {
const actionSheet = document.createElement('ion-action-sheet');
actionSheet.header = "Albums";
actionSheet.header = 'Albums';
actionSheet.cssClass = 'my-custom-class';
actionSheet.buttons = [{
text: 'Delete',
role: 'destructive',
@@ -98,7 +128,7 @@ async function presentActionSheet() {
}
}, {
text: 'Play (open modal)',
icon: 'arrow-dropright-circle',
icon: 'caret-forward-circle',
handler: () => {
console.log('Play clicked');
}
@@ -124,48 +154,51 @@ async function presentActionSheet() {
### React
```typescript
import React, { useState } from 'react'
```tsx
import React, { useState } from 'react';
import { IonActionSheet, IonContent, IonButton } from '@ionic/react';
import { trash, share, caretForwardCircle, heart, close } from 'ionicons/icons';
export const ActionSheetExample: React.FC = () => {
const [showActionSheet, setShowActionSheet] = useState(false);
return (
<IonContent>
<IonButton onClick={() => setShowActionSheet(true)} expand="block">Show Action Sheet</IonButton>
<IonButton onClick={() => setShowActionSheet(true)} expand="block">
Show Action Sheet
</IonButton>
<IonActionSheet
isOpen={showActionSheet}
onDidDismiss={() => setShowActionSheet(false)}
cssClass='my-custom-class'
buttons={[{
text: 'Delete',
role: 'destructive',
icon: 'trash',
icon: trash,
handler: () => {
console.log('Delete clicked');
}
}, {
text: 'Share',
icon: 'share',
icon: share,
handler: () => {
console.log('Share clicked');
}
}, {
text: 'Play (open modal)',
icon: 'arrow-dropright-circle',
icon: caretForwardCircle,
handler: () => {
console.log('Play clicked');
}
}, {
text: 'Favorite',
icon: 'heart',
icon: heart,
handler: () => {
console.log('Favorite clicked');
}
}, {
text: 'Cancel',
icon: 'close',
icon: close,
role: 'cancel',
handler: () => {
console.log('Cancel clicked');
@@ -174,11 +207,72 @@ export const ActionSheetExample: React.FC = () => {
>
</IonActionSheet>
</IonContent>
);
}
```
### Stencil
```tsx
import { Component, h } from '@stencil/core';
import { actionSheetController } from '@ionic/core';
@Component({
tag: 'action-sheet-example',
styleUrl: 'action-sheet-example.css'
})
export class ActionSheetExample {
async presentActionSheet() {
const actionSheet = await actionSheetController.create({
header: 'Albums',
cssClass: 'my-custom-class',
buttons: [{
text: 'Delete',
role: 'destructive',
icon: 'trash',
handler: () => {
console.log('Delete clicked');
}
}, {
text: 'Share',
icon: 'share',
handler: () => {
console.log('Share clicked');
}
}, {
text: 'Play (open modal)',
icon: 'caret-forward-circle',
handler: () => {
console.log('Play clicked');
}
}, {
text: 'Favorite',
icon: 'heart',
handler: () => {
console.log('Favorite clicked');
}
}, {
text: 'Cancel',
icon: 'close',
role: 'cancel',
handler: () => {
console.log('Cancel clicked');
}
}]
});
await actionSheet.present();
}
render() {
return [
<ion-content>
<ion-button onClick={() => this.presentActionSheet()}>Present Action Sheet</ion-button>
</ion-content>
];
}
}
```
@@ -198,6 +292,7 @@ export default {
return this.$ionic.actionSheetController
.create({
header: 'Albums',
cssClass: 'my-custom-class',
buttons: [
{
text: 'Delete',
@@ -216,7 +311,7 @@ export default {
},
{
text: 'Play (open modal)',
icon: 'arrow-dropright-circle',
icon: 'caret-forward-circle',
handler: () => {
console.log('Play clicked')
},
@@ -286,23 +381,23 @@ Type: `Promise<boolean>`
### `onDidDismiss() => Promise<OverlayEventDetail<any>>`
### `onDidDismiss<T = any>() => Promise<OverlayEventDetail<T>>`
Returns a promise that resolves when the action sheet did dismiss.
#### Returns
Type: `Promise<OverlayEventDetail<any>>`
Type: `Promise<OverlayEventDetail<T>>`
### `onWillDismiss() => Promise<OverlayEventDetail<any>>`
### `onWillDismiss<T = any>() => Promise<OverlayEventDetail<T>>`
Returns a promise that resolves when the action sheet will dismiss.
#### Returns
Type: `Promise<OverlayEventDetail<any>>`
Type: `Promise<OverlayEventDetail<T>>`
@@ -319,19 +414,31 @@ Type: `Promise<void>`
## CSS Custom Properties
| Name | Description |
| ------------------------ | -------------------------------------------------- |
| `--backdrop-opacity` | Opacity of the backdrop |
| `--background` | Background of the action sheet group |
| `--background-activated` | Background of the action sheet button when pressed |
| `--background-selected` | Background of the selected action sheet button |
| `--color` | Color of the action sheet text |
| `--height` | height of the action sheet |
| `--max-height` | Maximum height of the action sheet |
| `--max-width` | Maximum width of the action sheet |
| `--min-height` | Minimum height of the action sheet |
| `--min-width` | Minimum width of the action sheet |
| `--width` | Width of the action sheet |
| Name | Description |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `--backdrop-opacity` | Opacity of the backdrop |
| `--background` | Background of the action sheet group |
| `--button-background` | Background of the action sheet button |
| `--button-background-activated` | Background of the action sheet button when pressed. Note: setting this will interfere with the Material Design ripple. |
| `--button-background-activated-opacity` | Opacity of the action sheet button background when pressed |
| `--button-background-focused` | Background of the action sheet button when tabbed to |
| `--button-background-focused-opacity` | Opacity of the action sheet button background when tabbed to |
| `--button-background-hover` | Background of the action sheet button on hover |
| `--button-background-hover-opacity` | Opacity of the action sheet button background on hover |
| `--button-background-selected` | Background of the selected action sheet button |
| `--button-background-selected-opacity` | Opacity of the selected action sheet button background |
| `--button-color` | Color of the action sheet button |
| `--button-color-activated` | Color of the action sheet button when pressed |
| `--button-color-focused` | Color of the action sheet button when tabbed to |
| `--button-color-hover` | Color of the action sheet button on hover |
| `--button-color-selected` | Color of the selected action sheet button |
| `--color` | Color of the action sheet text |
| `--height` | height of the action sheet |
| `--max-height` | Maximum height of the action sheet |
| `--max-width` | Maximum width of the action sheet |
| `--min-height` | Minimum height of the action sheet |
| `--min-width` | Minimum width of the action sheet |
| `--width` | Width of the action sheet |
## Dependencies

View File

@@ -10,6 +10,10 @@
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script></head>
<script type="module">
import { actionSheetController } from '../../../../dist/ionic/index.esm.js';
window.actionSheetController = actionSheetController;
</script>
<body>
<ion-app>
@@ -36,10 +40,10 @@
<style>
.my-color-class {
--background: #292929;
--background-selected: #222222;
--button-background-selected: #222222;
--color: #dfdfdf;
;
--button-color: #dfdfdf;
}
.my-custom-class {
@@ -57,11 +61,14 @@
</style>
<script>
window.addEventListener('ionActionSheetDidDismiss', function (e) { console.log('didDismiss', e) })
async function openActionSheet(opts) {
const actionSheet = await actionSheetController.create(opts);
await actionSheet.present();
}
async function presentBasic() {
const mode = Ionic.mode;
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
await openActionSheet({
header: "Albums",
buttons: [{
text: 'Delete',
@@ -73,13 +80,13 @@
}, {
text: 'Share',
icon: 'share',
cssClass: 'activated',
cssClass: 'ion-activated',
handler: () => {
console.log('Share clicked');
}
}, {
text: 'Play (open modal)',
icon: 'arrow-dropright-circle',
icon: 'chevron-forward-circle',
handler: () => {
console.log('Play clicked');
}
@@ -98,12 +105,10 @@
}
}]
});
document.body.append(actionSheetElement);
await actionSheetElement.present();
}
async function presentAlert() {
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
await openActionSheet({
buttons: [{
text: 'Open Alert',
handler: async () => {
@@ -114,7 +119,7 @@
buttons: [{
text: 'Okay',
handler: async () => {
await actionSheetElement.dismiss();
await actionSheetController.dismiss();
return false;
}
}]
@@ -131,12 +136,10 @@
}
}]
});
document.body.append(actionSheetElement);
await actionSheetElement.present();
}
async function presentCancelOnly() {
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
await openActionSheet({
buttons: [
{
text: 'Cancel',
@@ -147,21 +150,17 @@
}
]
});
document.body.append(actionSheetElement);
await actionSheetElement.present();
}
async function presentWithCssClass(classList) {
const addClass = classList ? classList : "my-color-class my-custom-class";
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
await openActionSheet({
header: "Custom Css Class",
cssClass: addClass,
cssClass: classList ? classList : "my-color-class my-custom-class",
buttons: [
{
text: 'Add to Favorites',
icon: 'star',
cssClass: 'my-custom-button customClass activated',
cssClass: 'my-custom-button customClass ion-activated',
handler: () => {
console.log('Add to Favorites clicked');
}
@@ -197,14 +196,10 @@
}
]
});
document.body.append(actionSheetElement);
await actionSheetElement.present();
}
async function presentIcons() {
const mode = Ionic.mode;
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
await openActionSheet({
header: "Albums",
buttons: [{
text: 'Delete',
@@ -221,7 +216,7 @@
}
}, {
text: 'Play (open modal)',
icon: 'arrow-dropright-circle',
icon: 'chevron-forward-circle',
handler: () => {
console.log('Play clicked');
}
@@ -241,12 +236,10 @@
}
}]
});
document.body.append(actionSheetElement);
await actionSheetElement.present();
}
async function presentNoBackdropDismiss() {
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
await openActionSheet({
backdropDismiss: false,
buttons: [{
text: 'Archive',
@@ -267,12 +260,10 @@
}
}]
});
document.body.append(actionSheetElement);
await actionSheetElement.present();
}
async function presentScroll() {
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
await openActionSheet({
buttons: [
{
text: 'Add Reaction',
@@ -281,7 +272,7 @@
}
}, {
text: 'Copy Text',
cssClass: 'activated',
cssClass: 'ion-activated',
handler: () => {
console.log('Copy Text clicked');
}
@@ -360,12 +351,10 @@
}
]
});
document.body.append(actionSheetElement);
await actionSheetElement.present();
}
async function presentScrollNoCancel() {
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
await openActionSheet({
buttons: [
{
text: 'Add Reaction',
@@ -431,8 +420,6 @@
}
]
});
document.body.append(actionSheetElement);
await actionSheetElement.present();
}
</script>
</body>

View File

@@ -10,7 +10,10 @@
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script></head>
<script type="module">
import { actionSheetController } from '../../../../dist/ionic/index.esm.js';
window.actionSheetController = actionSheetController;
</script>
<body>
<ion-app>
@@ -31,8 +34,7 @@
async function presentSpec() {
const mode = Ionic.mode;
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
const actionSheet = await actionSheetController.create({
header: "Open in",
buttons: [{
text: 'Item 1',
@@ -66,8 +68,7 @@
}
}]
});
document.body.appendChild(actionSheetElement);
await actionSheetElement.present();
await actionSheet.present();
}
</script>
</body>

View File

@@ -10,7 +10,10 @@
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script></head>
<script type="module">
import { actionSheetController } from '../../../../dist/ionic/index.esm.js';
window.actionSheetController = actionSheetController;
</script>
<body>
<button id="basic" onclick="presentBasic()">Basic</button>
<button id="noBackdropDismiss" onclick="presentNoBackdropDismiss()">No Backdrop Dismiss</button>
@@ -37,8 +40,13 @@
<script>
window.addEventListener('ionActionSheetDidDismiss', function(e){console.log('didDismiss', e)})
async function openActionSheet(opts) {
const actionSheet = await actionSheetController.create(opts);
await actionSheet.present();
}
function presentBasic() {
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
openActionSheet({
header: "Albums",
buttons: [{
text: 'Delete',
@@ -55,7 +63,7 @@
}
}, {
text: 'Play (open modal)',
icon: 'arrow-dropright-circle',
icon: 'chevron-forward-circle',
handler: () => {
console.log('Play clicked');
}
@@ -74,14 +82,10 @@
}
}]
});
document.body.appendChild(actionSheetElement);
return actionSheetElement.present();
}
function presentIcons() {
const mode = Ionic.mode;
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
openActionSheet({
header: "Albums",
buttons: [{
text: 'Delete',
@@ -98,7 +102,7 @@
}
}, {
text: 'Play (open modal)',
icon: 'arrow-dropright-circle',
icon: 'chevron-forward-circle',
handler: () => {
console.log('Play clicked');
}
@@ -117,12 +121,10 @@
}
}]
});
document.body.appendChild(actionSheetElement);
return actionSheetElement.present();
}
function presentNoBackdropDismiss() {
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
openActionSheet({
buttons: [{
text: 'Archive',
handler: () => {
@@ -142,12 +144,10 @@
}
}]
});
document.body.appendChild(actionSheetElement);
return actionSheetElement.present();
}
function presentAlert() {
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
openActionSheet({
buttons: [{
text: 'Open Alert',
handler: () => {
@@ -161,12 +161,10 @@
}
}]
});
document.body.appendChild(actionSheetElement);
return actionSheetElement.present();
}
function presentScroll() {
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
openActionSheet({
buttons: [
{
text: 'Add Reaction',
@@ -238,12 +236,10 @@
}
]
});
document.body.appendChild(actionSheetElement);
return actionSheetElement.present();
}
function presentScrollNoCancel() {
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
openActionSheet({
buttons: [
{
text: 'Add Reaction',
@@ -309,12 +305,10 @@
}
]
});
document.body.appendChild(actionSheetElement);
return actionSheetElement.present();
}
function presentCancelOnly() {
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
openActionSheet({
buttons: [
{
text: 'Cancel',
@@ -325,12 +319,10 @@
}
]
});
document.body.append(actionSheetElement);
return actionSheetElement.present();
}
function presentWithCssClass() {
const actionSheetElement = Object.assign(document.createElement('ion-action-sheet'), {
openActionSheet({
header: "Custom Css Class",
cssClass: "my-class my-custom-class",
buttons: [
@@ -344,8 +336,6 @@
}
]
});
document.body.appendChild(actionSheetElement);
return actionSheetElement.present();
}
</script>

View File

@@ -10,7 +10,10 @@
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script></head>
<script type="module">
import { actionSheetController } from '../../../../dist/ionic/index.esm.js';
window.actionSheetController = actionSheetController;
</script>
<body>
<ion-app>
@@ -46,12 +49,15 @@
</ion-app>
<script>
async function openActionSheet(opts) {
const actionSheet = await actionSheetController.create(opts);
await actionSheet.present();
}
async function presentBasic() {
var mode = Ionic.mode;
const actionSheetController = document.querySelector('ion-action-sheet-controller');
const actionSheetElement = await actionSheetController.create({
await openActionSheet({
header: "Albums",
buttons: [{
text: 'Delete',
@@ -68,7 +74,7 @@
}
}, {
text: 'Play (open modal)',
icon: 'arrow-dropright-circle',
icon: 'chevron-forward-circle',
handler: () => {
console.log('Play clicked');
}
@@ -87,13 +93,11 @@
}
}],
translucent: true
})
await actionSheetElement.present();
});
}
async function presentNoBackdropDismiss() {
const actionSheetController = document.querySelector('ion-action-sheet-controller');
const actionSheetElement = await actionSheetController.create({
await openActionSheet({
backdropDismiss: false,
buttons: [{
text: 'Archive',
@@ -115,12 +119,10 @@
}],
translucent: true
});
return await actionSheetElement.present();
}
async function presentAlert() {
const actionSheetController = document.querySelector('ion-action-sheet-controller');
const actionSheetElement = await actionSheetController.create({
await openActionSheet({
buttons: [{
text: 'Open Alert',
handler: () => {
@@ -135,12 +137,10 @@
}],
translucent: true
});
return await actionSheetElement.present();
}
async function presentScroll() {
const actionSheetController = document.querySelector('ion-action-sheet-controller');
const actionSheetElement = await actionSheetController.create({
await openActionSheet({
buttons: [
{
text: 'Add Reaction',
@@ -149,7 +149,7 @@
}
}, {
text: 'Copy Text',
cssClass: 'activated',
cssClass: 'ion-activated',
handler: () => {
console.log('Copy Text clicked');
}
@@ -185,7 +185,7 @@
}
}, {
text: 'Edit Title',
cssClass: 'activated',
cssClass: 'ion-activated',
handler: () => {
console.log('Edit Title clicked');
}
@@ -215,12 +215,10 @@
],
translucent: true
});
return await actionSheetElement.present();
}
async function presentScrollNoCancel() {
const actionSheetController = document.querySelector('ion-action-sheet-controller');
const actionSheetElement = await actionSheetController.create({
await openActionSheet({
buttons: [
{
text: 'Add Reaction',
@@ -287,12 +285,10 @@
],
translucent: true
});
return await actionSheetElement.present();
}
async function presentCancelOnly() {
const actionSheetController = document.querySelector('ion-action-sheet-controller');
const actionSheetElement = await actionSheetController.create({
await openActionSheet({
buttons: [
{
text: 'Cancel',
@@ -304,7 +300,6 @@
],
translucent: true
});
return await actionSheetElement.present();
}
</script>

View File

@@ -14,6 +14,7 @@ export class ActionSheetExample {
async presentActionSheet() {
const actionSheet = await this.actionSheetController.create({
header: 'Albums',
cssClass: 'my-custom-class',
buttons: [{
text: 'Delete',
role: 'destructive',
@@ -29,7 +30,7 @@ export class ActionSheetExample {
}
}, {
text: 'Play (open modal)',
icon: 'arrow-dropright-circle',
icon: 'caret-forward-circle',
handler: () => {
console.log('Play clicked');
}
@@ -53,3 +54,8 @@ export class ActionSheetExample {
}
```
### Style Placement
In Angular, the CSS of a specific page is scoped only to elements of that page. Even though the Action Sheet can be presented from within a page, the `ion-action-sheet` element is appended outside of the current page. This means that any custom styles need to go in a global stylesheet file. In an Ionic Angular starter this can be the `src/global.scss` file or you can register a new global style file by [adding to the `styles` build option in `angular.json`](https://angular.io/guide/workspace-config#style-script-config).

View File

@@ -1,9 +1,9 @@
```javascript
async function presentActionSheet() {
const actionSheet = document.createElement('ion-action-sheet');
actionSheet.header = "Albums";
actionSheet.header = 'Albums';
actionSheet.cssClass = 'my-custom-class';
actionSheet.buttons = [{
text: 'Delete',
role: 'destructive',
@@ -19,7 +19,7 @@ async function presentActionSheet() {
}
}, {
text: 'Play (open modal)',
icon: 'arrow-dropright-circle',
icon: 'caret-forward-circle',
handler: () => {
console.log('Play clicked');
}

View File

@@ -1,45 +1,48 @@
```typescript
import React, { useState } from 'react'
```tsx
import React, { useState } from 'react';
import { IonActionSheet, IonContent, IonButton } from '@ionic/react';
import { trash, share, caretForwardCircle, heart, close } from 'ionicons/icons';
export const ActionSheetExample: React.FC = () => {
const [showActionSheet, setShowActionSheet] = useState(false);
return (
<IonContent>
<IonButton onClick={() => setShowActionSheet(true)} expand="block">Show Action Sheet</IonButton>
<IonButton onClick={() => setShowActionSheet(true)} expand="block">
Show Action Sheet
</IonButton>
<IonActionSheet
isOpen={showActionSheet}
onDidDismiss={() => setShowActionSheet(false)}
cssClass='my-custom-class'
buttons={[{
text: 'Delete',
role: 'destructive',
icon: 'trash',
icon: trash,
handler: () => {
console.log('Delete clicked');
}
}, {
text: 'Share',
icon: 'share',
icon: share,
handler: () => {
console.log('Share clicked');
}
}, {
text: 'Play (open modal)',
icon: 'arrow-dropright-circle',
icon: caretForwardCircle,
handler: () => {
console.log('Play clicked');
}
}, {
text: 'Favorite',
icon: 'heart',
icon: heart,
handler: () => {
console.log('Favorite clicked');
}
}, {
text: 'Cancel',
icon: 'close',
icon: close,
role: 'cancel',
handler: () => {
console.log('Cancel clicked');
@@ -48,9 +51,6 @@ export const ActionSheetExample: React.FC = () => {
>
</IonActionSheet>
</IonContent>
);
}
```

View File

@@ -0,0 +1,60 @@
```tsx
import { Component, h } from '@stencil/core';
import { actionSheetController } from '@ionic/core';
@Component({
tag: 'action-sheet-example',
styleUrl: 'action-sheet-example.css'
})
export class ActionSheetExample {
async presentActionSheet() {
const actionSheet = await actionSheetController.create({
header: 'Albums',
cssClass: 'my-custom-class',
buttons: [{
text: 'Delete',
role: 'destructive',
icon: 'trash',
handler: () => {
console.log('Delete clicked');
}
}, {
text: 'Share',
icon: 'share',
handler: () => {
console.log('Share clicked');
}
}, {
text: 'Play (open modal)',
icon: 'caret-forward-circle',
handler: () => {
console.log('Play clicked');
}
}, {
text: 'Favorite',
icon: 'heart',
handler: () => {
console.log('Favorite clicked');
}
}, {
text: 'Cancel',
icon: 'close',
role: 'cancel',
handler: () => {
console.log('Cancel clicked');
}
}]
});
await actionSheet.present();
}
render() {
return [
<ion-content>
<ion-button onClick={() => this.presentActionSheet()}>Present Action Sheet</ion-button>
</ion-content>
];
}
}
```

View File

@@ -12,6 +12,7 @@ export default {
return this.$ionic.actionSheetController
.create({
header: 'Albums',
cssClass: 'my-custom-class',
buttons: [
{
text: 'Delete',
@@ -30,7 +31,7 @@ export default {
},
{
text: 'Play (open modal)',
icon: 'arrow-dropright-circle',
icon: 'caret-forward-circle',
handler: () => {
console.log('Play clicked')
},

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