@ionic/core 8.8.16-dev.11784841344.1aa1a41c → 8.8.16-dev.11784914346.10d0804c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/ion-accordion.js +1 -1
- package/components/ion-action-sheet.js +1 -1
- package/components/ion-alert.js +1 -1
- package/components/ion-avatar.js +1 -1
- package/components/ion-back-button.js +1 -1
- package/components/ion-badge.js +1 -1
- package/components/ion-breadcrumb.js +1 -1
- package/components/ion-button.js +1 -1
- package/components/ion-buttons.js +1 -1
- package/components/ion-content.js +1 -1
- package/components/ion-datetime.js +1 -1
- package/components/ion-fab-button.js +1 -1
- package/components/ion-footer.js +1 -1
- package/components/ion-header.js +1 -1
- package/components/ion-icon.js +1 -1
- package/components/ion-input-password-toggle.js +1 -1
- package/components/ion-input.js +1 -1
- package/components/ion-item-option.js +1 -1
- package/components/ion-item.js +1 -1
- package/components/ion-menu-button.js +1 -1
- package/components/ion-refresher-content.js +1 -1
- package/components/ion-reorder.js +1 -1
- package/components/ion-searchbar.js +1 -1
- package/components/ion-segment-button.js +1 -1
- package/components/ion-select-modal.js +1 -1
- package/components/ion-select-popover.js +1 -1
- package/components/ion-select.js +1 -1
- package/components/ion-tab-bar.js +1 -1
- package/components/ion-tab-button.js +1 -1
- package/components/ion-title.js +1 -1
- package/components/ion-toast.js +1 -1
- package/components/ion-toggle.js +1 -1
- package/components/{p-DiKh2eQw.js → p-4u9RNymb.js} +1 -1
- package/components/{p-B8KYxaMx.js → p-B8xhFBOE.js} +1 -1
- package/components/p-BAnNwWMA.js +4 -0
- package/components/p-BYZR_5L4.js +4 -0
- package/components/p-B_zaqq5F.js +4 -0
- package/components/p-CO9VfZyc.js +4 -0
- package/components/p-Cjx0xPoU.js +4 -0
- package/components/p-CyWeCU8e.js +4 -0
- package/components/p-DRnK3A-V.js +4 -0
- package/components/p-DcVqGRkT.js +4 -0
- package/components/p-Dght1fh7.js +4 -0
- package/components/p-GpxJMpJu.js +4 -0
- package/dist/cjs/{index-Cu9JNpPi.js → index-CgAbCW6L.js} +1 -1
- package/dist/cjs/ion-accordion_2.cjs.entry.js +1 -1
- package/dist/cjs/ion-action-sheet.cjs.entry.js +3 -3
- package/dist/cjs/ion-alert.cjs.entry.js +3 -3
- package/dist/cjs/ion-app_8.cjs.entry.js +194 -65
- package/dist/cjs/ion-avatar_3.cjs.entry.js +4 -4
- package/dist/cjs/ion-back-button.cjs.entry.js +1 -1
- package/dist/cjs/ion-breadcrumb_2.cjs.entry.js +1 -1
- package/dist/cjs/ion-button_2.cjs.entry.js +3 -3
- package/dist/cjs/ion-datetime_3.cjs.entry.js +1 -1
- package/dist/cjs/ion-fab_3.cjs.entry.js +1 -1
- package/dist/cjs/ion-input-password-toggle.cjs.entry.js +1 -1
- package/dist/cjs/ion-input.cjs.entry.js +4 -4
- package/dist/cjs/ion-item-option_3.cjs.entry.js +1 -1
- package/dist/cjs/ion-item_8.cjs.entry.js +1 -1
- package/dist/cjs/ion-menu_3.cjs.entry.js +1 -1
- package/dist/cjs/ion-refresher_2.cjs.entry.js +1 -1
- package/dist/cjs/ion-reorder_2.cjs.entry.js +1 -1
- package/dist/cjs/ion-searchbar.cjs.entry.js +2 -2
- package/dist/cjs/ion-segment_2.cjs.entry.js +1 -1
- package/dist/cjs/ion-select-modal.cjs.entry.js +4 -4
- package/dist/cjs/ion-select_3.cjs.entry.js +5 -5
- package/dist/cjs/ion-tab-bar_2.cjs.entry.js +78 -80
- package/dist/cjs/ion-toggle.cjs.entry.js +1 -1
- package/dist/cjs/ionic.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/scroll-hide-controller-G9HOmmhN.js +345 -0
- package/dist/collection/components/action-sheet/action-sheet.ionic.css +2 -5
- package/dist/collection/components/action-sheet/action-sheet.ios.css +2 -1
- package/dist/collection/components/action-sheet/action-sheet.md.css +2 -1
- package/dist/collection/components/alert/alert.ionic.css +2 -5
- package/dist/collection/components/alert/alert.ios.css +2 -1
- package/dist/collection/components/alert/alert.md.css +2 -1
- package/dist/collection/components/avatar/avatar.ionic.css +12 -6
- package/dist/collection/components/badge/badge.ionic.css +6 -3
- package/dist/collection/components/badge/badge.ios.css +4 -2
- package/dist/collection/components/badge/badge.md.css +2 -1
- package/dist/collection/components/button/button.ionic.css +4 -2
- package/dist/collection/components/buttons/buttons.ionic.css +1 -1
- package/dist/collection/components/content/content.css +39 -0
- package/dist/collection/components/footer/footer-interface.js +1 -0
- package/dist/collection/components/footer/footer.ios.css +19 -4
- package/dist/collection/components/footer/footer.js +102 -15
- package/dist/collection/components/footer/footer.md.css +28 -0
- package/dist/collection/components/header/header-interface.js +1 -0
- package/dist/collection/components/header/header.ionic.css +153 -0
- package/dist/collection/components/header/header.ios.css +153 -123
- package/dist/collection/components/header/header.js +139 -28
- package/dist/collection/components/header/header.md.css +176 -1
- package/dist/collection/components/header/header.utils.js +6 -13
- package/dist/collection/components/input/input.ionic.css +2 -1
- package/dist/collection/components/input/input.ios.css +2 -1
- package/dist/collection/components/input/input.md.css +2 -1
- package/dist/collection/components/item-option/item-option.ionic.css +2 -1
- package/dist/collection/components/searchbar/searchbar.ionic.css +6 -2
- package/dist/collection/components/segment-button/segment-button.ionic.css +2 -1
- package/dist/collection/components/select/select.ionic.css +2 -1
- package/dist/collection/components/select-modal/select-modal.ionic.css +2 -5
- package/dist/collection/components/select-modal/select-modal.ios.css +2 -1
- package/dist/collection/components/select-modal/select-modal.md.css +2 -1
- package/dist/collection/components/select-popover/select-popover.ionic.css +2 -5
- package/dist/collection/components/select-popover/select-popover.ios.css +2 -1
- package/dist/collection/components/select-popover/select-popover.md.css +2 -1
- package/dist/collection/components/tab-bar/tab-bar.ionic.css +25 -3
- package/dist/collection/components/tab-bar/tab-bar.ios.css +15 -0
- package/dist/collection/components/tab-bar/tab-bar.js +94 -88
- package/dist/collection/components/tab-bar/tab-bar.md.css +15 -0
- package/dist/collection/components/tab-button/tab-button.ionic.css +2 -1
- package/dist/collection/components/title/title.md.css +7 -0
- package/dist/collection/utils/scroll-hide-controller.js +178 -0
- package/dist/docs.json +144 -32
- package/dist/esm/{index-1y3VhUSy.js → index-D2tu5BUg.js} +1 -1
- package/dist/esm/ion-accordion_2.entry.js +1 -1
- package/dist/esm/ion-action-sheet.entry.js +3 -3
- package/dist/esm/ion-alert.entry.js +3 -3
- package/dist/esm/ion-app_8.entry.js +194 -65
- package/dist/esm/ion-avatar_3.entry.js +4 -4
- package/dist/esm/ion-back-button.entry.js +1 -1
- package/dist/esm/ion-breadcrumb_2.entry.js +1 -1
- package/dist/esm/ion-button_2.entry.js +3 -3
- package/dist/esm/ion-datetime_3.entry.js +1 -1
- package/dist/esm/ion-fab_3.entry.js +1 -1
- package/dist/esm/ion-input-password-toggle.entry.js +1 -1
- package/dist/esm/ion-input.entry.js +4 -4
- package/dist/esm/ion-item-option_3.entry.js +1 -1
- package/dist/esm/ion-item_8.entry.js +1 -1
- package/dist/esm/ion-menu_3.entry.js +1 -1
- package/dist/esm/ion-refresher_2.entry.js +1 -1
- package/dist/esm/ion-reorder_2.entry.js +1 -1
- package/dist/esm/ion-searchbar.entry.js +2 -2
- package/dist/esm/ion-segment_2.entry.js +1 -1
- package/dist/esm/ion-select-modal.entry.js +4 -4
- package/dist/esm/ion-select_3.entry.js +5 -5
- package/dist/esm/ion-tab-bar_2.entry.js +79 -81
- package/dist/esm/ion-toggle.entry.js +1 -1
- package/dist/esm/ionic.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/scroll-hide-controller-CUNW7EpD.js +342 -0
- package/dist/html.html-data.json +36 -4
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-07bd8446.entry.js +4 -0
- package/dist/ionic/p-103e1d9f.entry.js +4 -0
- package/dist/ionic/{p-eeb7b373.entry.js → p-18bc4f2d.entry.js} +1 -1
- package/dist/ionic/p-248265c2.entry.js +4 -0
- package/dist/ionic/{p-fb457fdd.entry.js → p-3bc5b5e9.entry.js} +1 -1
- package/dist/ionic/{p-42a882b7.entry.js → p-43b00c5b.entry.js} +1 -1
- package/dist/ionic/{p-d0f253fc.entry.js → p-56224b93.entry.js} +1 -1
- package/dist/ionic/p-5732396e.entry.js +4 -0
- package/dist/ionic/{p-b3d04a86.entry.js → p-58d8877d.entry.js} +1 -1
- package/dist/ionic/{p-9e9be378.entry.js → p-5d079dc1.entry.js} +1 -1
- package/dist/ionic/{p-d0dfc9a3.entry.js → p-5e9665dd.entry.js} +1 -1
- package/dist/ionic/{p-7b2fe639.entry.js → p-5fee5cc1.entry.js} +1 -1
- package/dist/ionic/p-64734604.entry.js +4 -0
- package/dist/ionic/p-69feeff9.entry.js +4 -0
- package/dist/ionic/p-83acfa2d.entry.js +4 -0
- package/dist/ionic/{p-f692219d.entry.js → p-849b1759.entry.js} +1 -1
- package/dist/ionic/{p-a09c7a4c.entry.js → p-86f040e0.entry.js} +1 -1
- package/dist/ionic/p-8cb23f27.entry.js +4 -0
- package/dist/ionic/p-C1I_d964.js +4 -0
- package/dist/ionic/p-b97778f5.entry.js +4 -0
- package/dist/ionic/p-be9db7e8.entry.js +4 -0
- package/dist/ionic/{p-2fba8f15.entry.js → p-c04429f2.entry.js} +1 -1
- package/dist/ionic/p-c25a2a9b.entry.js +4 -0
- package/dist/ionic/{p-a797625e.entry.js → p-d272ff4f.entry.js} +1 -1
- package/dist/types/components/footer/footer-interface.d.ts +1 -0
- package/dist/types/components/footer/footer.d.ts +16 -0
- package/dist/types/components/header/header-interface.d.ts +1 -0
- package/dist/types/components/header/header.d.ts +17 -0
- package/dist/types/components/header/header.utils.d.ts +4 -5
- package/dist/types/components/tab-bar/tab-bar-interface.d.ts +1 -0
- package/dist/types/components/tab-bar/tab-bar.d.ts +17 -14
- package/dist/types/components.d.ts +37 -13
- package/dist/types/utils/scroll-hide-controller.d.ts +56 -0
- package/hydrate/index.js +477 -175
- package/hydrate/index.mjs +477 -175
- package/package.json +2 -2
- package/components/p-BZwQa9ey.js +0 -4
- package/components/p-CJCMdFb9.js +0 -4
- package/components/p-Ck_9SoHZ.js +0 -4
- package/components/p-CmnPD02Z.js +0 -4
- package/components/p-D-Xa9lMG.js +0 -4
- package/components/p-DFSqPtzD.js +0 -4
- package/components/p-NPsFR8Ng.js +0 -4
- package/components/p-U2gyA6Z0.js +0 -4
- package/components/p-q8wGOPJB.js +0 -4
- package/dist/cjs/keyboard-controller-CefyW9lm.js +0 -169
- package/dist/esm/keyboard-controller-BFwRdk2T.js +0 -167
- package/dist/ionic/p-0c4d9d7c.entry.js +0 -4
- package/dist/ionic/p-40dc9dbd.entry.js +0 -4
- package/dist/ionic/p-54419365.entry.js +0 -4
- package/dist/ionic/p-6293e9f1.entry.js +0 -4
- package/dist/ionic/p-7de397c7.entry.js +0 -4
- package/dist/ionic/p-8cf82b85.entry.js +0 -4
- package/dist/ionic/p-MqqcZQSB.js +0 -4
- package/dist/ionic/p-a6e04ca3.entry.js +0 -4
- package/dist/ionic/p-a6fe63f0.entry.js +0 -4
- package/dist/ionic/p-b275f17e.entry.js +0 -4
- package/dist/ionic/p-c5635175.entry.js +0 -4
- package/dist/ionic/p-dc8e0b91.entry.js +0 -4
- /package/components/{p-J03hHbbL.js → p-BaPtaYEC.js} +0 -0
- /package/dist/ionic/{p-1y3VhUSy.js → p-D2tu5BUg.js} +0 -0
|
@@ -9,6 +9,159 @@ ion-header ion-toolbar:first-of-type {
|
|
|
9
9
|
padding-top: var(--ion-safe-area-top, 0);
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
.header-collapse-fade ion-toolbar {
|
|
13
|
+
--opacity-scale: inherit;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Override styles applied during the page transition to prevent
|
|
18
|
+
* header flickering.
|
|
19
|
+
*/
|
|
20
|
+
.header-collapse-fade.header-transitioning ion-toolbar {
|
|
21
|
+
--background: transparent;
|
|
22
|
+
--border-style: none;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.header-collapse-condense {
|
|
26
|
+
z-index: 9;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.header-collapse-condense ion-toolbar {
|
|
30
|
+
position: sticky;
|
|
31
|
+
top: 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.header-collapse-condense ion-toolbar:first-of-type {
|
|
35
|
+
/**
|
|
36
|
+
* The toolbar that contains the collapsible
|
|
37
|
+
* large title should not have safe area padding applied.
|
|
38
|
+
*/
|
|
39
|
+
padding-top: 0px;
|
|
40
|
+
z-index: 1;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Large title toolbar should just use the content background
|
|
45
|
+
* since it needs to blend in with the header above it.
|
|
46
|
+
*/
|
|
47
|
+
.header-collapse-condense ion-toolbar {
|
|
48
|
+
z-index: 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.header-collapse-condense ion-toolbar:last-of-type {
|
|
52
|
+
--border-width: 0px;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.header-collapse-condense ion-toolbar ion-searchbar {
|
|
56
|
+
padding-top: 0px;
|
|
57
|
+
padding-bottom: 13px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.header-collapse-main {
|
|
61
|
+
--opacity-scale: 1;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.header-collapse-main ion-toolbar {
|
|
65
|
+
--opacity-scale: inherit;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.header-collapse-main ion-toolbar.in-toolbar ion-title,
|
|
69
|
+
.header-collapse-main ion-toolbar.in-toolbar ion-buttons {
|
|
70
|
+
transition: all 0.2s ease-in-out;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Large title toolbar should just use the content background
|
|
75
|
+
* since it needs to blend in with the header above it.
|
|
76
|
+
*/
|
|
77
|
+
.header-collapse-condense ion-toolbar,
|
|
78
|
+
.header-collapse-condense-inactive.header-transitioning:not(.header-collapse-condense) ion-toolbar {
|
|
79
|
+
--background: var(--ion-background-color, #fff);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Override styles applied during the page transition to prevent
|
|
84
|
+
* header flickering.
|
|
85
|
+
*/
|
|
86
|
+
.header-collapse-condense-inactive.header-transitioning:not(.header-collapse-condense) ion-toolbar {
|
|
87
|
+
--border-style: none;
|
|
88
|
+
--opacity-scale: 1;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.header-collapse-condense-inactive:not(.header-collapse-condense) ion-toolbar.in-toolbar ion-title,
|
|
92
|
+
.header-collapse-condense-inactive:not(.header-collapse-condense) ion-toolbar.in-toolbar ion-buttons.buttons-collapse {
|
|
93
|
+
opacity: 0;
|
|
94
|
+
pointer-events: none;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* There is a bug in Safari where changing
|
|
99
|
+
* the opacity of an element in a scrollable container
|
|
100
|
+
* while rubber-banding causes the scroll position
|
|
101
|
+
* to jump to the top
|
|
102
|
+
*/
|
|
103
|
+
.header-collapse-condense-inactive.header-collapse-condense ion-toolbar.in-toolbar ion-title,
|
|
104
|
+
.header-collapse-condense-inactive.header-collapse-condense ion-toolbar.in-toolbar ion-buttons.buttons-collapse {
|
|
105
|
+
visibility: hidden;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* The main header is only hidden once the collapsible large
|
|
110
|
+
* title is configured. As a result, if the main header loads
|
|
111
|
+
* before the collapsible large title is configured then the
|
|
112
|
+
* main header will be visible briefly before being hidden
|
|
113
|
+
* by the collapsible large title.
|
|
114
|
+
*
|
|
115
|
+
* The following selector ensures that any main header
|
|
116
|
+
* on a page with a collapsible large title is hidden
|
|
117
|
+
* before the collapsible large title is configured.
|
|
118
|
+
* Once the collapsible large title is configured the main
|
|
119
|
+
* header will have the ".header-collapse-main" class, and
|
|
120
|
+
* this selector will no longer apply.
|
|
121
|
+
*
|
|
122
|
+
* The :has(...) part of the selector ensures a couple things:
|
|
123
|
+
* 1. This will only apply within a page view since the content
|
|
124
|
+
* must be a subsequent-sibling of the header (~ ion-content).
|
|
125
|
+
* 2. This will only apply when that content has an active condense
|
|
126
|
+
* header (the .header-collapse-condense class).
|
|
127
|
+
*
|
|
128
|
+
* We use opacity: 0 to avoid a layout shift.
|
|
129
|
+
* We use the class (not the attribute) because the class is only
|
|
130
|
+
* added when the condense effect is valid (large title present).
|
|
131
|
+
* The attribute alone is not sufficient since it would match even
|
|
132
|
+
* when the effect is guarded (e.g. no large title).
|
|
133
|
+
*/
|
|
134
|
+
ion-header:not(.header-collapse-main):has(~ ion-content ion-header.header-collapse-condense) {
|
|
135
|
+
opacity: 0;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* The deprecated collapse="condense" prop is iOS-only.
|
|
140
|
+
* On non-iOS themes, the condense header should be hidden since
|
|
141
|
+
* the JS won't activate it. Uses a class instead of an attribute
|
|
142
|
+
* selector because collapse is not a reflected prop, and framework
|
|
143
|
+
* proxies (Angular/Vue) bind it as a property.
|
|
144
|
+
*/
|
|
145
|
+
.header-collapse-condense-hidden {
|
|
146
|
+
display: none;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
ion-header.header-scroll-effect-hide {
|
|
150
|
+
transition: transform 300ms cubic-bezier(0, 0, 0.2, 1), opacity 300ms cubic-bezier(0, 0, 0.2, 1);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
ion-header.header-scroll-effect-hide.header-scroll-hidden {
|
|
154
|
+
transform: translateY(-100%);
|
|
155
|
+
transition: transform 200ms cubic-bezier(0.4, 0, 1, 1), opacity 300ms cubic-bezier(0.4, 0, 1, 1);
|
|
156
|
+
opacity: 0;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@media (prefers-reduced-motion: reduce) {
|
|
160
|
+
ion-header.header-scroll-effect-hide,
|
|
161
|
+
ion-header.header-scroll-effect-hide.header-scroll-hidden {
|
|
162
|
+
transition: none;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
12
165
|
/**
|
|
13
166
|
* Convert a pixels given value into rem
|
|
14
167
|
*
|
|
@@ -163,129 +316,6 @@ ion-header {
|
|
|
163
316
|
--border-width: 0;
|
|
164
317
|
}
|
|
165
318
|
|
|
166
|
-
.header-collapse-fade ion-toolbar {
|
|
167
|
-
--opacity-scale: inherit;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Override styles applied during the page transition to prevent
|
|
172
|
-
* header flickering.
|
|
173
|
-
*/
|
|
174
|
-
.header-collapse-fade.header-transitioning ion-toolbar {
|
|
175
|
-
--background: transparent;
|
|
176
|
-
--border-style: none;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
.header-collapse-condense {
|
|
180
|
-
z-index: 9;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
.header-collapse-condense ion-toolbar {
|
|
184
|
-
position: sticky;
|
|
185
|
-
top: 0;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
.header-collapse-condense ion-toolbar:first-of-type {
|
|
189
|
-
/**
|
|
190
|
-
* The toolbar that contains the collapsible
|
|
191
|
-
* large title should not have safe area padding applied.
|
|
192
|
-
*/
|
|
193
|
-
padding-top: 0px;
|
|
194
|
-
z-index: 1;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Large title toolbar should just use the content background
|
|
199
|
-
* since it needs to blend in with the header above it.
|
|
200
|
-
*/
|
|
201
|
-
.header-collapse-condense ion-toolbar {
|
|
202
|
-
z-index: 0;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
319
|
.header-collapse-condense ion-toolbar:last-of-type {
|
|
206
320
|
--border-width: 0px;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
.header-collapse-condense ion-toolbar ion-searchbar {
|
|
210
|
-
padding-top: 0px;
|
|
211
|
-
padding-bottom: 13px;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
.header-collapse-main {
|
|
215
|
-
--opacity-scale: 1;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
.header-collapse-main ion-toolbar {
|
|
219
|
-
--opacity-scale: inherit;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
.header-collapse-main ion-toolbar.in-toolbar ion-title,
|
|
223
|
-
.header-collapse-main ion-toolbar.in-toolbar ion-buttons {
|
|
224
|
-
transition: all 0.2s ease-in-out;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Large title toolbar should just use the content background
|
|
229
|
-
* since it needs to blend in with the header above it.
|
|
230
|
-
*/
|
|
231
|
-
.header-collapse-condense ion-toolbar,
|
|
232
|
-
.header-collapse-condense-inactive.header-transitioning:not(.header-collapse-condense) ion-toolbar {
|
|
233
|
-
--background: var(--ion-background-color, #fff);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Override styles applied during the page transition to prevent
|
|
238
|
-
* header flickering.
|
|
239
|
-
*/
|
|
240
|
-
.header-collapse-condense-inactive.header-transitioning:not(.header-collapse-condense) ion-toolbar {
|
|
241
|
-
--border-style: none;
|
|
242
|
-
--opacity-scale: 1;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
.header-collapse-condense-inactive:not(.header-collapse-condense) ion-toolbar.in-toolbar ion-title,
|
|
246
|
-
.header-collapse-condense-inactive:not(.header-collapse-condense) ion-toolbar.in-toolbar ion-buttons.buttons-collapse {
|
|
247
|
-
opacity: 0;
|
|
248
|
-
pointer-events: none;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* There is a bug in Safari where changing
|
|
253
|
-
* the opacity of an element in a scrollable container
|
|
254
|
-
* while rubber-banding causes the scroll position
|
|
255
|
-
* to jump to the top
|
|
256
|
-
*/
|
|
257
|
-
.header-collapse-condense-inactive.header-collapse-condense ion-toolbar.in-toolbar ion-title,
|
|
258
|
-
.header-collapse-condense-inactive.header-collapse-condense ion-toolbar.in-toolbar ion-buttons.buttons-collapse {
|
|
259
|
-
visibility: hidden;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* The main header is only hidden once the collapsible large
|
|
264
|
-
* title is configured. As a result, if the main header loads
|
|
265
|
-
* before the collapsible large title is configured then the
|
|
266
|
-
* main header will be visible briefly before being hidden
|
|
267
|
-
* by the collapsible large title.
|
|
268
|
-
*
|
|
269
|
-
* The following selector ensures that any main header
|
|
270
|
-
* on a page with a collapsible large title is hidden
|
|
271
|
-
* before the collapsible large title is configured.
|
|
272
|
-
* Once the collapsible large title is configured the main
|
|
273
|
-
* header will have the ".header-collapse-main" class, and
|
|
274
|
-
* this selector will no longer apply.
|
|
275
|
-
*
|
|
276
|
-
* The :has(...) part of the selector ensures a couple things:
|
|
277
|
-
* 1. This will only apply within a page view since the content
|
|
278
|
-
* must be a subsequent-sibling of the header (~ ion-content).
|
|
279
|
-
* 2. This will only apply when that content has a collapse header (ion-header[collapse="condense"])
|
|
280
|
-
*
|
|
281
|
-
* We use opacity: 0 to avoid a layout shift.
|
|
282
|
-
* We target both the attribute and the class in the event that the attribute
|
|
283
|
-
* is not reflected on the host in some frameworks.
|
|
284
|
-
*
|
|
285
|
-
* Both headers should be scoped to iOS mode otherwise an MD app that uses an
|
|
286
|
-
* iOS header may cause other MD headers to be unexpectedly hidden.
|
|
287
|
-
*/
|
|
288
|
-
ion-header.header-ios:not(.header-collapse-main):has(~ ion-content ion-header.header-ios[collapse=condense],
|
|
289
|
-
~ ion-content ion-header.header-ios.header-collapse-condense) {
|
|
290
|
-
opacity: 0;
|
|
291
321
|
}
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
import { Host, h, writeTask } from "@stencil/core";
|
|
5
5
|
import { findIonContent, getScrollElement, printIonContentErrorMsg } from "../../utils/content/index";
|
|
6
6
|
import { inheritAriaAttributes } from "../../utils/helpers";
|
|
7
|
+
import { printIonWarning } from "../../utils/logging/index";
|
|
8
|
+
import { createScrollHideController } from "../../utils/scroll-hide-controller";
|
|
7
9
|
import { hostContext } from "../../utils/theme";
|
|
8
10
|
import { config } from "../../global/config";
|
|
9
11
|
import { getIonTheme } from "../../global/ionic-global";
|
|
@@ -15,6 +17,9 @@ import { cloneElement, createHeaderIndex, handleContentScroll, handleHeaderFade,
|
|
|
15
17
|
export class Header {
|
|
16
18
|
constructor() {
|
|
17
19
|
this.inheritedAttributes = {};
|
|
20
|
+
this.scrollHideCtrlPromise = null;
|
|
21
|
+
this.hasWarnedCollapse = false;
|
|
22
|
+
this.fadeCondenseSetupId = 0;
|
|
18
23
|
/**
|
|
19
24
|
* If `true`, the header will have a line at the bottom.
|
|
20
25
|
* TODO(ROU-10855): add support for this prop on ios/md themes
|
|
@@ -29,8 +34,29 @@ export class Header {
|
|
|
29
34
|
* attribute needs to be set on the content.
|
|
30
35
|
*/
|
|
31
36
|
this.translucent = false;
|
|
37
|
+
this.setupScrollEffectHide = async (contentEl) => {
|
|
38
|
+
const setupPromise = createScrollHideController(contentEl, {
|
|
39
|
+
el: this.el,
|
|
40
|
+
cssVar: '--internal-header-hide-height',
|
|
41
|
+
hiddenClass: 'header-scroll-hidden',
|
|
42
|
+
contentPartnerClass: 'content-header-hide-scroll-partner',
|
|
43
|
+
contentHiddenClass: 'content-header-hide-scroll-hidden',
|
|
44
|
+
});
|
|
45
|
+
this.scrollHideCtrlPromise = setupPromise;
|
|
46
|
+
const controller = await setupPromise;
|
|
47
|
+
if (this.scrollHideCtrlPromise === setupPromise) {
|
|
48
|
+
this.scrollHideCtrlPromise = null;
|
|
49
|
+
controller.init();
|
|
50
|
+
this.scrollHideCtrl = controller;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
32
53
|
this.setupFadeHeader = async (contentEl, condenseHeader) => {
|
|
33
|
-
const
|
|
54
|
+
const setupId = ++this.fadeCondenseSetupId;
|
|
55
|
+
const scrollEl = await getScrollElement(contentEl);
|
|
56
|
+
if (this.fadeCondenseSetupId !== setupId) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
this.scrollEl = scrollEl;
|
|
34
60
|
/**
|
|
35
61
|
* Handle fading of toolbars on scroll
|
|
36
62
|
*/
|
|
@@ -54,38 +80,63 @@ export class Header {
|
|
|
54
80
|
this.destroyCollapsibleHeader();
|
|
55
81
|
}
|
|
56
82
|
async checkCollapsibleHeader() {
|
|
57
|
-
const
|
|
58
|
-
if (
|
|
83
|
+
const { scrollEffect, collapse } = this;
|
|
84
|
+
if (collapse !== undefined && scrollEffect === undefined && !this.hasWarnedCollapse) {
|
|
85
|
+
this.hasWarnedCollapse = true;
|
|
86
|
+
printIonWarning(`[ion-header] - The \`collapse\` property is deprecated. Use \`scrollEffect\` instead.\nExample: <ion-header scroll-effect="${collapse}">`, this.el);
|
|
87
|
+
}
|
|
88
|
+
const effect = scrollEffect !== null && scrollEffect !== void 0 ? scrollEffect : collapse;
|
|
89
|
+
// Skip teardown/rebuild if the effect hasn't changed.
|
|
90
|
+
// This prevents re-renders from destroying the scroll controller
|
|
91
|
+
// and resetting isHidden.
|
|
92
|
+
if (effect === this.activeEffect) {
|
|
59
93
|
return;
|
|
60
94
|
}
|
|
61
|
-
const
|
|
62
|
-
const hasCondense =
|
|
63
|
-
const hasFade =
|
|
95
|
+
const hasHide = effect === 'hide';
|
|
96
|
+
const hasCondense = effect === 'condense';
|
|
97
|
+
const hasFade = effect === 'fade';
|
|
64
98
|
this.destroyCollapsibleHeader();
|
|
65
99
|
const appRootSelector = config.get('appRootSelector', 'ion-app');
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
100
|
+
const pageEl = this.el.closest(`${appRootSelector}, ion-page, .ion-page, page-inner`);
|
|
101
|
+
const contentEl = pageEl ? findIonContent(pageEl) : null;
|
|
102
|
+
if (hasHide && contentEl) {
|
|
103
|
+
this.activeEffect = effect;
|
|
104
|
+
await this.setupScrollEffectHide(contentEl);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
// condense/fade via the deprecated `collapse` prop are iOS-only.
|
|
108
|
+
// condense/fade via the new `scrollEffect` prop work in all themes.
|
|
109
|
+
const isModeRestricted = scrollEffect === undefined && getIonTheme(this) !== 'ios';
|
|
110
|
+
if (hasCondense && !isModeRestricted) {
|
|
69
111
|
// Cloned elements are always needed in iOS transition
|
|
70
112
|
writeTask(() => {
|
|
71
113
|
const title = cloneElement('ion-title');
|
|
72
114
|
title.size = 'large';
|
|
73
115
|
cloneElement('ion-back-button');
|
|
74
116
|
});
|
|
75
|
-
await this.setupCondenseHeader(contentEl, pageEl);
|
|
117
|
+
const didSetup = await this.setupCondenseHeader(contentEl, pageEl);
|
|
118
|
+
if (didSetup) {
|
|
119
|
+
this.activeEffect = effect;
|
|
120
|
+
}
|
|
76
121
|
}
|
|
77
|
-
else if (hasFade) {
|
|
78
|
-
const pageEl = this.el.closest(`${appRootSelector},ion-page,.ion-page,page-inner`);
|
|
79
|
-
const contentEl = pageEl ? findIonContent(pageEl) : null;
|
|
122
|
+
else if (hasFade && !isModeRestricted) {
|
|
80
123
|
if (!contentEl) {
|
|
81
124
|
printIonContentErrorMsg(this.el);
|
|
82
125
|
return;
|
|
83
126
|
}
|
|
84
|
-
const condenseHeader = contentEl.querySelector('ion-header[collapse="condense"]');
|
|
127
|
+
const condenseHeader = contentEl.querySelector('ion-header[collapse="condense"],ion-header[scroll-effect="condense"]');
|
|
128
|
+
this.activeEffect = effect;
|
|
85
129
|
await this.setupFadeHeader(contentEl, condenseHeader);
|
|
86
130
|
}
|
|
87
131
|
}
|
|
88
132
|
destroyCollapsibleHeader() {
|
|
133
|
+
this.activeEffect = undefined;
|
|
134
|
+
this.fadeCondenseSetupId++;
|
|
135
|
+
this.scrollHideCtrlPromise = null;
|
|
136
|
+
if (this.scrollHideCtrl) {
|
|
137
|
+
this.scrollHideCtrl.destroy();
|
|
138
|
+
this.scrollHideCtrl = undefined;
|
|
139
|
+
}
|
|
89
140
|
if (this.intersectionObserver) {
|
|
90
141
|
this.intersectionObserver.disconnect();
|
|
91
142
|
this.intersectionObserver = undefined;
|
|
@@ -102,21 +153,40 @@ export class Header {
|
|
|
102
153
|
async setupCondenseHeader(contentEl, pageEl) {
|
|
103
154
|
if (!contentEl || !pageEl) {
|
|
104
155
|
printIonContentErrorMsg(this.el);
|
|
105
|
-
return;
|
|
156
|
+
return false;
|
|
106
157
|
}
|
|
107
158
|
if (typeof IntersectionObserver === 'undefined') {
|
|
108
|
-
return;
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
const setupId = ++this.fadeCondenseSetupId;
|
|
162
|
+
const scrollEl = await getScrollElement(contentEl);
|
|
163
|
+
if (this.fadeCondenseSetupId !== setupId) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
this.scrollEl = scrollEl;
|
|
167
|
+
/**
|
|
168
|
+
* The condense effect requires an ion-title with size="large"
|
|
169
|
+
* in the condense header. Without it, there is nothing to
|
|
170
|
+
* collapse into the main header toolbar.
|
|
171
|
+
*/
|
|
172
|
+
const hasLargeTitle = this.el.querySelector('ion-title[size="large"]') !== null;
|
|
173
|
+
if (!hasLargeTitle) {
|
|
174
|
+
printIonWarning('[ion-header] - The condense scroll effect requires an <ion-title size="large"> in the condense header.', this.el);
|
|
175
|
+
return false;
|
|
109
176
|
}
|
|
110
|
-
this.scrollEl = await getScrollElement(contentEl);
|
|
111
177
|
const headers = pageEl.querySelectorAll('ion-header');
|
|
112
|
-
this.collapsibleMainHeader = Array.from(headers).find((header) =>
|
|
178
|
+
this.collapsibleMainHeader = Array.from(headers).find((header) => {
|
|
179
|
+
var _a;
|
|
180
|
+
const effect = (_a = header.scrollEffect) !== null && _a !== void 0 ? _a : header.collapse;
|
|
181
|
+
return effect !== 'condense';
|
|
182
|
+
});
|
|
113
183
|
if (!this.collapsibleMainHeader) {
|
|
114
|
-
return;
|
|
184
|
+
return false;
|
|
115
185
|
}
|
|
116
186
|
const mainHeaderIndex = createHeaderIndex(this.collapsibleMainHeader);
|
|
117
187
|
const scrollHeaderIndex = createHeaderIndex(this.el);
|
|
118
188
|
if (!mainHeaderIndex || !scrollHeaderIndex) {
|
|
119
|
-
return;
|
|
189
|
+
return false;
|
|
120
190
|
}
|
|
121
191
|
setHeaderActive(mainHeaderIndex, false);
|
|
122
192
|
setToolbarBackgroundOpacity(mainHeaderIndex.el, 0);
|
|
@@ -148,23 +218,35 @@ export class Header {
|
|
|
148
218
|
this.collapsibleMainHeader.classList.add('header-collapse-main');
|
|
149
219
|
}
|
|
150
220
|
});
|
|
221
|
+
return true;
|
|
151
222
|
}
|
|
152
223
|
render() {
|
|
153
|
-
const { translucent, inheritedAttributes, divider } = this;
|
|
224
|
+
const { translucent, inheritedAttributes, divider, scrollEffect, collapse } = this;
|
|
154
225
|
const theme = getIonTheme(this);
|
|
155
|
-
const
|
|
156
|
-
|
|
226
|
+
const effect = scrollEffect !== null && scrollEffect !== void 0 ? scrollEffect : collapse;
|
|
227
|
+
// condense/fade via the deprecated `collapse` prop are iOS-only.
|
|
228
|
+
const isModeRestricted = scrollEffect === undefined && theme !== 'ios';
|
|
229
|
+
const hasHide = effect === 'hide';
|
|
230
|
+
const hasCondense = effect === 'condense' && !isModeRestricted && this.el.querySelector('ion-title[size="large"]') !== null;
|
|
231
|
+
const hasFade = effect === 'fade' && !isModeRestricted;
|
|
232
|
+
// The condense header should be hidden when
|
|
233
|
+
// - deprecated collapse prop is used on non-iOS (mode restricted), or
|
|
234
|
+
// - scrollEffect="condense" is set but no ion-title[size="large"] is present
|
|
235
|
+
const isHiddenCondense = effect === 'condense' && !hasCondense;
|
|
157
236
|
// banner role must be at top level, so remove role if inside a menu
|
|
158
|
-
const roleType = getRoleType(hostContext('ion-menu', this.el)
|
|
159
|
-
return (h(Host, Object.assign({ key: '
|
|
237
|
+
const roleType = isHiddenCondense ? 'none' : getRoleType(hostContext('ion-menu', this.el));
|
|
238
|
+
return (h(Host, Object.assign({ key: '09f60ca014bb7b3a85d3c0a94e7989d5dbc43f46', role: roleType, class: {
|
|
160
239
|
[theme]: true,
|
|
161
240
|
// Used internally for styling
|
|
162
241
|
[`header-${theme}`]: true,
|
|
163
242
|
[`header-translucent`]: this.translucent,
|
|
164
|
-
[
|
|
243
|
+
['header-collapse-condense']: hasCondense,
|
|
244
|
+
['header-collapse-condense-hidden']: isHiddenCondense,
|
|
245
|
+
['header-collapse-fade']: hasFade,
|
|
165
246
|
[`header-translucent-${theme}`]: this.translucent,
|
|
166
247
|
['header-divider']: divider,
|
|
167
|
-
|
|
248
|
+
'header-scroll-effect-hide': hasHide,
|
|
249
|
+
} }, inheritedAttributes), theme !== 'md' && translucent && h("div", { key: 'fd5ff245ae0166e5e1d50936cacc98c90625db48', class: "header-background" }), h("slot", { key: '1baa31af87b9eb6406a21073ec65afa191dfbb3d' })));
|
|
168
250
|
}
|
|
169
251
|
static get is() { return "ion-header"; }
|
|
170
252
|
static get originalStyleUrls() {
|
|
@@ -183,6 +265,32 @@ export class Header {
|
|
|
183
265
|
}
|
|
184
266
|
static get properties() {
|
|
185
267
|
return {
|
|
268
|
+
"scrollEffect": {
|
|
269
|
+
"type": "string",
|
|
270
|
+
"mutable": false,
|
|
271
|
+
"complexType": {
|
|
272
|
+
"original": "HeaderScrollEffect",
|
|
273
|
+
"resolved": "\"condense\" | \"fade\" | \"hide\" | undefined",
|
|
274
|
+
"references": {
|
|
275
|
+
"HeaderScrollEffect": {
|
|
276
|
+
"location": "import",
|
|
277
|
+
"path": "./header-interface",
|
|
278
|
+
"id": "src/components/header/header-interface.ts::HeaderScrollEffect",
|
|
279
|
+
"referenceLocation": "HeaderScrollEffect"
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
"required": false,
|
|
284
|
+
"optional": true,
|
|
285
|
+
"docs": {
|
|
286
|
+
"tags": [],
|
|
287
|
+
"text": "Describes the scroll effect that will be applied to the header.\n`\"hide\"` slides the header out of view when scrolling down and back in\nwhen scrolling up.\n`\"condense\"` collapses the large title into the main toolbar on scroll.\n`\"fade\"` fades the toolbar background on scroll."
|
|
288
|
+
},
|
|
289
|
+
"getter": false,
|
|
290
|
+
"setter": false,
|
|
291
|
+
"reflect": true,
|
|
292
|
+
"attribute": "scroll-effect"
|
|
293
|
+
},
|
|
186
294
|
"collapse": {
|
|
187
295
|
"type": "string",
|
|
188
296
|
"mutable": false,
|
|
@@ -194,7 +302,10 @@ export class Header {
|
|
|
194
302
|
"required": false,
|
|
195
303
|
"optional": true,
|
|
196
304
|
"docs": {
|
|
197
|
-
"tags": [
|
|
305
|
+
"tags": [{
|
|
306
|
+
"name": "deprecated",
|
|
307
|
+
"text": "Use `scrollEffect` instead."
|
|
308
|
+
}],
|
|
198
309
|
"text": "Describes the scroll effect that will be applied to the header.\nOnly applies when the theme is `\"ios\"`.\n\nTypically used for [Collapsible Large Titles](https://ionicframework.com/docs/api/title#collapsible-large-titles)"
|
|
199
310
|
},
|
|
200
311
|
"getter": false,
|