@rdlabo/ionic-theme-ios27 1.2.0-1 → 1.2.0-3

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.
Files changed (75) hide show
  1. package/README.md +9 -0
  2. package/dist/css/components/ion-tabs.css +1 -1
  3. package/dist/css/ionic-theme-ios27.css +1 -1
  4. package/dist/css/vertical-bars.css +1 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +31 -12
  7. package/dist/native/components/index.d.ts.map +1 -1
  8. package/dist/native/components/index.js +4 -1
  9. package/dist/native/components/ion-button.d.ts.map +1 -1
  10. package/dist/native/components/ion-button.js +3 -3
  11. package/dist/native/components/ion-buttons.d.ts.map +1 -1
  12. package/dist/native/components/ion-buttons.js +3 -2
  13. package/dist/native/components/searchable-tabs.d.ts.map +1 -1
  14. package/dist/native/components/searchable-tabs.js +6 -7
  15. package/dist/native/definitions.d.ts +8 -15
  16. package/dist/native/definitions.d.ts.map +1 -1
  17. package/dist/native/definitions.js +1 -6
  18. package/dist/native/index.d.ts +1 -2
  19. package/dist/native/index.d.ts.map +1 -1
  20. package/dist/native/index.js +64 -28
  21. package/dist/native/prehide.d.ts.map +1 -1
  22. package/dist/native/prehide.js +6 -4
  23. package/dist/native/runtime.d.ts.map +1 -1
  24. package/dist/native/runtime.js +40 -19
  25. package/dist/native/shared/candidate.d.ts.map +1 -1
  26. package/dist/native/shared/candidate.js +8 -0
  27. package/dist/native/shared/dom.d.ts.map +1 -1
  28. package/dist/native/shared/dom.js +11 -10
  29. package/dist/native/shared/modal.d.ts +8 -0
  30. package/dist/native/shared/modal.d.ts.map +1 -0
  31. package/dist/native/shared/modal.js +143 -0
  32. package/dist/native/vertical-bars-web.d.ts.map +1 -1
  33. package/dist/native/vertical-bars-web.js +11 -3
  34. package/dist/sheets-of-glass/animations.d.ts +13 -4
  35. package/dist/sheets-of-glass/animations.d.ts.map +1 -1
  36. package/dist/sheets-of-glass/animations.js +56 -40
  37. package/dist/sheets-of-glass/index.d.ts +1 -1
  38. package/dist/sheets-of-glass/index.d.ts.map +1 -1
  39. package/dist/sheets-of-glass/index.js +64 -20
  40. package/dist/tab-bar-searchable/index.d.ts.map +1 -1
  41. package/dist/tab-bar-searchable/index.js +39 -11
  42. package/dist/vertical-bars.d.ts +1 -2
  43. package/dist/vertical-bars.d.ts.map +1 -1
  44. package/dist/vertical-bars.js +0 -1
  45. package/docs/iphone-duo-with-original-theme.md +37 -15
  46. package/docs/iphone-duo.md +90 -47
  47. package/docs/migration.md +3 -3
  48. package/docs/native-ui-shell.md +12 -8
  49. package/docs/special-markup.md +0 -13
  50. package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellSearchController.swift +1 -1
  51. package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellVerticalBars.swift +50 -6
  52. package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellVerticalSearch.swift +118 -0
  53. package/ios/Sources/IonicNativeUIShellPlugin/IonicNativeUIShellPlugin.swift +32 -179
  54. package/ios/Sources/IonicNativeUIShellPlugin/Shared/ShellSnapshot.swift +5 -0
  55. package/ios/Tests/IonicNativeUIShellPluginTests/ShellSnapshotTests.swift +67 -0
  56. package/package.json +1 -1
  57. package/src/index.ts +40 -9
  58. package/src/native/components/index.ts +6 -1
  59. package/src/native/components/ion-button.ts +4 -3
  60. package/src/native/components/ion-buttons.ts +4 -2
  61. package/src/native/components/searchable-tabs.ts +8 -11
  62. package/src/native/definitions.ts +11 -19
  63. package/src/native/index.ts +67 -30
  64. package/src/native/prehide.ts +7 -4
  65. package/src/native/runtime.ts +40 -18
  66. package/src/native/shared/candidate.ts +10 -0
  67. package/src/native/shared/dom.ts +11 -10
  68. package/src/native/shared/modal.ts +157 -0
  69. package/src/native/vertical-bars-web.ts +12 -3
  70. package/src/sheets-of-glass/animations.ts +66 -41
  71. package/src/sheets-of-glass/index.ts +82 -16
  72. package/src/styles/components/ion-tabs.scss +7 -4
  73. package/src/styles/vertical-bars.scss +110 -35
  74. package/src/tab-bar-searchable/index.ts +40 -9
  75. package/src/vertical-bars.ts +1 -2
@@ -31,8 +31,21 @@ ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left {
31
31
  --ios-theme-vertical-bars-safe-area-right-resolved: var(--ios-theme-vertical-bars-safe-area-right, 0px);
32
32
  }
33
33
 
34
+ // Centered dialogs do not inherit the page's rail reservation.
35
+ ion-app.ios-theme-vertical-bars ion-modal:not(.ios-theme-vertical-bars-modal) {
36
+ --ios-theme-vertical-bars-safe-area-left-resolved: 0px;
37
+ --ios-theme-vertical-bars-safe-area-right-resolved: 0px;
38
+ }
39
+
40
+ ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal {
41
+ --ios-theme-vertical-bars-modal-toolbar-top: max(
42
+ 24px,
43
+ calc(var(--ios-theme-vertical-bars-toolbar-top, 220px) - var(--ios-theme-vertical-bars-modal-offset-top, 0px))
44
+ );
45
+ }
46
+
34
47
  // Supply material defaults only to Web projections, never to ordinary controls.
35
- ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready
48
+ :is(ion-app.ios-theme-vertical-bars, ion-modal.ios-theme-vertical-bars-modal).ios-theme-vertical-bars-toolbar-ready
36
49
  > :is(ion-menu-button, ion-button).ios-theme-vertical-bars-toolbar-projection {
37
50
  --ios26-glass-background-rgb: var(--ion-background-color-rgb, 255, 255, 255);
38
51
  --ios26-glass-border-color-rgb: var(--ion-background-color-rgb, 255, 255, 255);
@@ -44,9 +57,19 @@ ion-app.ios-theme-vertical-bars .ios-transition-shade {
44
57
  clip-path: inset(0 var(--ios-theme-vertical-bars-safe-area-right-resolved) 0 var(--ios-theme-vertical-bars-safe-area-left-resolved));
45
58
  }
46
59
 
60
+ // A vertical system rail can leave no top inset for the page header.
61
+ ion-app.ios-theme-vertical-bars
62
+ ion-header.ios:not(.header-collapse-condense, .ios-theme-disabled, .ios26-disabled):not(
63
+ :where(ion-menu *, ion-modal:not(.ios-theme-vertical-bars-modal) *, ion-popover *)
64
+ ) {
65
+ --ion-safe-area-top: max(24px, env(safe-area-inset-top, 0px));
66
+ }
67
+
47
68
  // Keep page backgrounds and the router full width; move only their foregrounds.
48
69
  ion-app.ios-theme-vertical-bars
49
- ion-content:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(:where(ion-menu *, ion-modal *, ion-popover *)) {
70
+ ion-content:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(
71
+ :where(ion-menu *, ion-modal:not(.ios-theme-vertical-bars-modal) *, ion-popover *)
72
+ ) {
50
73
  --ion-safe-area-left: 0px;
51
74
  --ion-safe-area-right: 0px;
52
75
 
@@ -62,7 +85,9 @@ ion-app.ios-theme-vertical-bars
62
85
  }
63
86
 
64
87
  ion-app.ios-theme-vertical-bars
65
- ion-toolbar:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(:where(ion-menu *, ion-modal *, ion-popover *)) {
88
+ ion-toolbar:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(
89
+ :where(ion-menu *, ion-modal:not(.ios-theme-vertical-bars-modal) *, ion-popover *)
90
+ ) {
66
91
  --ion-safe-area-left: 0px;
67
92
  --ion-safe-area-right: 0px;
68
93
 
@@ -131,37 +156,44 @@ ion-app.ios-theme-vertical-bars {
131
156
  ion-app.ios-theme-vertical-bars
132
157
  ion-tabs:not(:where(ion-menu *, ion-modal *, ion-popover *))
133
158
  > ion-tab-bar:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled) {
134
- --ios-theme-side-tab-bar-width: 50px;
135
- --ios-theme-side-tab-bar-gap: 8px;
136
- --ios-theme-side-safe-area: var(--ios-theme-vertical-bars-safe-area-right-resolved);
159
+ // iOS 27.1 Duo: 48pt platter, 44 × 58pt items with 8pt overlap, 24pt edge gaps.
160
+ --ios-theme-side-tab-bar-width: 48px;
161
+ --ios-theme-side-tab-content-width: 44px;
162
+ --ios-theme-side-tab-bar-gap: 24px;
137
163
  contain: layout style;
138
164
  position: absolute;
139
165
  z-index: 2;
140
166
  display: flex;
141
167
  flex-direction: column;
142
- width: 46px;
143
- min-width: 46px;
144
- max-width: 46px;
168
+ width: 44px;
169
+ min-width: 44px;
170
+ max-width: 44px;
145
171
  height: fit-content;
146
172
  min-height: 0;
147
173
  padding: 2px;
148
- border-radius: 25px;
174
+ border-radius: 24px;
149
175
  left: auto;
150
- right: max(4px, calc((var(--ios-theme-side-safe-area) - var(--ios-theme-side-tab-bar-width)) / 2));
176
+ right: calc(24px + (48px - var(--ios-theme-side-tab-bar-width)) / 2);
151
177
  margin: 0;
152
178
  top: auto;
153
- bottom: calc(var(--ion-safe-area-bottom, 0px) + var(--ios-theme-side-tab-bar-gap));
179
+ bottom: var(--ios-theme-side-tab-bar-gap);
180
+
181
+ &.ios27-enable-gesture {
182
+ touch-action: pan-x pinch-zoom;
183
+ }
154
184
 
155
185
  > ion-tab-button:not(.ion-cloned-element) {
156
186
  display: block;
157
187
  flex: none;
158
- width: 46px;
159
- min-width: 46px;
160
- height: 52px;
161
- min-height: 52px;
162
- border-radius: 23px;
188
+ width: 44px;
189
+ min-width: 44px;
190
+ height: 58px;
191
+ min-height: 58px;
192
+ border-radius: 22px;
163
193
  &::part(native) {
164
194
  justify-content: center;
195
+ min-height: 58px;
196
+ padding: 0;
165
197
  }
166
198
  ion-label {
167
199
  position: absolute;
@@ -179,32 +211,54 @@ ion-app.ios-theme-vertical-bars
179
211
  font-size: 28px;
180
212
  }
181
213
  }
214
+ > ion-tab-button.ion-activated {
215
+ transform: scale(1.16);
216
+ }
182
217
  > ion-tab-button:not(.ion-cloned-element) ~ ion-tab-button:not(.ion-cloned-element) {
183
- margin-block-start: 0;
218
+ margin-block-start: -8px;
184
219
  margin-inline-start: 0;
185
220
  }
186
- &:has(> ion-tab-button:is(.ion-activated, :active)) > ion-tab-button:not(.ion-cloned-element) {
221
+ // Duo's expanded platter keeps its center and reveals labels without shrinking icons.
222
+ &:is(.ios27-animated, :has(> ion-tab-button:is(.ion-activated, :active))) {
223
+ --ios-theme-side-tab-bar-width: 72px;
224
+ --ios-theme-side-tab-content-width: 64px;
225
+ --ios-theme-side-tab-bar-gap: 20px;
226
+ width: 64px;
227
+ min-width: 64px;
228
+ max-width: 64px;
229
+ padding: 4px;
230
+ border-radius: 36px;
231
+ transform: none;
232
+ -webkit-transform: none;
233
+ }
234
+ &:is(.ios27-animated, :has(> ion-tab-button:is(.ion-activated, :active))) > ion-tab-button:not(.ion-cloned-element) {
235
+ width: 64px;
236
+ min-width: 64px;
237
+ height: 64px;
238
+ min-height: 64px;
239
+ border-radius: 32px;
187
240
  &::part(native) {
188
241
  flex-direction: column;
189
- padding-block: 4px;
242
+ min-height: 64px;
243
+ padding-block: 11px;
190
244
  }
191
245
  ion-label {
192
246
  position: static;
193
247
  width: auto;
194
248
  height: auto;
195
- max-width: 44px;
249
+ max-width: 64px;
196
250
  padding: 0;
197
251
  margin: 1px 0 0;
198
252
  overflow: hidden;
199
253
  clip: auto;
200
- font-size: 0.5rem;
201
- line-height: 1;
254
+ font-size: 10px;
255
+ line-height: 12px;
202
256
  text-overflow: ellipsis;
203
257
  white-space: nowrap;
204
258
  }
205
259
  ion-icon {
206
260
  margin: 0;
207
- font-size: 22px;
261
+ font-size: 28px;
208
262
  }
209
263
  }
210
264
  }
@@ -212,9 +266,8 @@ ion-app.ios-theme-vertical-bars
212
266
  ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left
213
267
  ion-tabs:not(:where(ion-menu *, ion-modal *, ion-popover *))
214
268
  > ion-tab-bar:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled) {
215
- --ios-theme-side-safe-area: var(--ios-theme-vertical-bars-safe-area-left-resolved);
216
269
  right: auto;
217
- left: max(4px, calc((var(--ios-theme-side-safe-area) - var(--ios-theme-side-tab-bar-width)) / 2));
270
+ left: calc(24px + (48px - var(--ios-theme-side-tab-bar-width)) / 2);
218
271
  }
219
272
 
220
273
  .ios-theme-native-ui-shell-prehidden {
@@ -251,8 +304,11 @@ html.ios-theme-native-ui-shell-prehide
251
304
  visibility: hidden !important;
252
305
  }
253
306
 
254
- ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready {
255
- ion-toolbar:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(:where(ion-menu *, ion-modal *, ion-popover *))
307
+ ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready,
308
+ ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready {
309
+ ion-toolbar:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(
310
+ :where(ion-menu *, ion-modal:not(.ios-theme-vertical-bars-modal) *, ion-popover *)
311
+ )
256
312
  ion-back-button:is(.ios, .md)[data-native-ui-shell]:not(
257
313
  .ios-theme-disabled,
258
314
  .ios26-disabled,
@@ -260,7 +316,9 @@ ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready {
260
316
  ) {
261
317
  display: none;
262
318
  }
263
- ion-toolbar:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(:where(ion-menu *, ion-modal *, ion-popover *))
319
+ ion-toolbar:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(
320
+ :where(ion-menu *, ion-modal:not(.ios-theme-vertical-bars-modal) *, ion-popover *)
321
+ )
264
322
  ion-buttons:is(.ios, .md)
265
323
  > :is(ion-button, ion-menu-button):is(.ios, .md)[data-native-ui-shell]:not(
266
324
  .ios-theme-disabled,
@@ -269,7 +327,9 @@ ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready {
269
327
  ) {
270
328
  display: none;
271
329
  }
272
- ion-toolbar:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(:where(ion-menu *, ion-modal *, ion-popover *))
330
+ ion-toolbar:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(
331
+ :where(ion-menu *, ion-modal:not(.ios-theme-vertical-bars-modal) *, ion-popover *)
332
+ )
273
333
  ion-buttons:is(.ios, .md):has(> :is(ion-back-button, ion-button, ion-menu-button)[data-native-ui-shell]):not(
274
334
  :has(> :is(ion-back-button, ion-button, ion-menu-button):not([data-native-ui-shell]))
275
335
  ) {
@@ -278,7 +338,7 @@ ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready {
278
338
  > ion-back-button.ios-theme-vertical-bars-back-button-projection {
279
339
  position: fixed;
280
340
  z-index: 1001;
281
- top: var(--ios-theme-vertical-bars-toolbar-top, 220px);
341
+ top: var(--ios-theme-vertical-bars-modal-toolbar-top, var(--ios-theme-vertical-bars-toolbar-top, 220px));
282
342
  right: max(4px, calc((var(--ios-theme-vertical-bars-safe-area-right-resolved) - 46px) / 2));
283
343
  display: block;
284
344
  width: 46px;
@@ -288,7 +348,10 @@ ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready {
288
348
  > :is(.ios, .md).ios-theme-vertical-bars-toolbar-projection {
289
349
  position: fixed;
290
350
  z-index: 1001;
291
- top: calc(var(--ios-theme-vertical-bars-toolbar-top, 220px) + var(--ios-theme-vertical-bars-toolbar-offset, 0px));
351
+ top: calc(
352
+ var(--ios-theme-vertical-bars-modal-toolbar-top, var(--ios-theme-vertical-bars-toolbar-top, 220px)) +
353
+ var(--ios-theme-vertical-bars-toolbar-offset, 0px)
354
+ );
292
355
  right: max(4px, calc((var(--ios-theme-vertical-bars-safe-area-right-resolved) - 46px) / 2));
293
356
  width: 46px;
294
357
  min-width: 46px;
@@ -307,10 +370,12 @@ ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready {
307
370
  border-radius: 50%;
308
371
  }
309
372
  > ion-button:is(.ios, .md).ios-theme-vertical-bars-toolbar-projection {
310
- --background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0.72);
373
+ &:not(.button-solid):not(.button-outline) {
374
+ --background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0.72);
375
+ }
311
376
  --border-radius: 50%;
312
377
  @include glass.light-shadow('--box-shadow');
313
- &::part(native) {
378
+ &:not(.button-outline)::part(native) {
314
379
  @include api.glass-control-background($include-background: false, $shadow: var(--box-shadow));
315
380
  }
316
381
  }
@@ -333,10 +398,20 @@ ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready {
333
398
  }
334
399
  }
335
400
 
336
- ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left {
401
+ ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left,
402
+ ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left ion-modal.ios-theme-vertical-bars-modal {
337
403
  > ion-back-button.ios-theme-vertical-bars-back-button-projection,
338
404
  > :is(.ios, .md).ios-theme-vertical-bars-toolbar-projection {
339
405
  right: auto;
340
406
  left: max(4px, calc((var(--ios-theme-vertical-bars-safe-area-left-resolved) - 46px) / 2));
341
407
  }
342
408
  }
409
+
410
+ // The lens is attached to body, outside the rail selectors.
411
+ ion-tab-button.ios.ion-cloned-element.ios27-vertical-tab-effect {
412
+ border-radius: 32px;
413
+ &::part(native) {
414
+ min-height: 0;
415
+ height: 100%;
416
+ }
417
+ }
@@ -64,6 +64,8 @@ export const attachTabBarSearchable = (
64
64
  // Initialize
65
65
  ionFooter.style.pointerEvents = 'none';
66
66
  ionFooter.style.opacity = '0';
67
+ // Search dismissal belongs beside the Web search field, never in the vertical rail.
68
+ ionFooter.querySelector('ion-buttons[slot=start]')?.classList.add('ios-theme-horizontal-only');
67
69
  const nativeSearch = registerNativeSearch(ionTabBar, ionFabButton, ionFooter);
68
70
 
69
71
  // Saved Params
@@ -72,6 +74,8 @@ export const attachTabBarSearchable = (
72
74
  // Leave is valid both while native Enter awaits its ack and after it completes.
73
75
  let nativeEntry = false;
74
76
  let nativeRequest = 0;
77
+ let verticalSearch = false;
78
+ let tabVisibilityObserver: MutationObserver | undefined;
75
79
 
76
80
  return async (event: Event, type: TabBarSearchableType) => {
77
81
  const selector = type === TabBarSearchableType.Enter ? 'ion-fab-button' : 'ion-buttons[slot=start] ion-button';
@@ -93,19 +97,38 @@ export const attachTabBarSearchable = (
93
97
  return;
94
98
  }
95
99
  if (type === TabBarSearchableType.Enter) {
96
- resumeNative ??= await suspendNativeUIShell([ionTabBar, ionFooter, ionFabButton.closest('ion-fab') ?? ionFabButton]);
100
+ verticalSearch = !!ionTabBar.closest('ion-app.ios-theme-vertical-bars');
101
+ if (verticalSearch) {
102
+ // Ionic hides horizontal tabs when the keyboard opens; keep this rail available.
103
+ const keepTabsVisible = () => {
104
+ if (ionTabBar.classList.contains('tab-bar-hidden') && ionTabBar.closest('ion-app.ios-theme-vertical-bars')) {
105
+ ionTabBar.classList.remove('tab-bar-hidden');
106
+ }
107
+ };
108
+ tabVisibilityObserver?.disconnect();
109
+ tabVisibilityObserver = new MutationObserver(keepTabsVisible);
110
+ tabVisibilityObserver.observe(ionTabBar, { attributes: true, attributeFilter: ['class'] });
111
+ keepTabsVisible();
112
+ }
113
+ resumeNative ??= await suspendNativeUIShell([
114
+ ...(verticalSearch ? [] : [ionTabBar]),
115
+ ionFooter,
116
+ ionFabButton.closest('ion-fab') ?? ionFabButton,
117
+ ]);
97
118
  try {
98
- searchableEventCache = await enterEvent(event, ionTabBar, ionFabButton, ionFooter);
119
+ searchableEventCache = await enterEvent(event, ionTabBar, ionFabButton, ionFooter, verticalSearch);
99
120
  } catch (error) {
121
+ tabVisibilityObserver?.disconnect();
100
122
  resumeNative();
101
123
  resumeNative = undefined;
102
124
  throw error;
103
125
  }
104
126
  } else if (searchableEventCache !== undefined) {
105
127
  try {
106
- await leaveEvent(event, searchableEventCache, ionTabBar, ionFabButton, ionFooter);
128
+ await leaveEvent(event, searchableEventCache, ionTabBar, ionFabButton, ionFooter, verticalSearch);
107
129
  searchableEventCache = undefined;
108
130
  } finally {
131
+ tabVisibilityObserver?.disconnect();
109
132
  resumeNative?.();
110
133
  resumeNative = undefined;
111
134
  }
@@ -120,6 +143,7 @@ const enterEvent = async (
120
143
  ionTabBar: HTMLElement,
121
144
  ionFabButton: HTMLElement,
122
145
  ionFooter: HTMLElement,
146
+ verticalSearch: boolean,
123
147
  ): Promise<SearchableEventCache> => {
124
148
  if (!(event.target as HTMLElement)?.closest('ion-fab-button')) {
125
149
  throw throwErrorByFailedClickElement('ion-fab-button');
@@ -131,10 +155,12 @@ const enterEvent = async (
131
155
  ? getComputedStyle(references.selectedTabButton).getPropertyValue('--color-selected').trim()
132
156
  : '';
133
157
 
134
- const effectAnimation = createEffectAnimation(references, sizes);
158
+ if (verticalSearch) references.closeButtonIcon.setAttribute('name', 'close');
159
+ const tabAnimations = verticalSearch
160
+ ? []
161
+ : [createTabBarAnimation(ionTabBar, references, sizes), createEffectAnimation(references, sizes)];
135
162
  const searchContainerAnimation = createSearchContainerAnimation(references, sizes);
136
163
  const closeButtonsAnimation = createCloseButtonsAnimation(references);
137
- const tabBarAnimation = createTabBarAnimation(ionTabBar, references, sizes);
138
164
  const fabButtonAnimation = createFabButtonAnimation(ionFabButton);
139
165
 
140
166
  await createAnimation()
@@ -144,7 +170,7 @@ const enterEvent = async (
144
170
  .addElement(ionFooter)
145
171
  .afterAddWrite(() => (ionFooter.style.pointerEvents = 'auto'))
146
172
  .fromTo('opacity', '0.8', '1')
147
- .addAnimation([tabBarAnimation, fabButtonAnimation, searchContainerAnimation, effectAnimation, closeButtonsAnimation])
173
+ .addAnimation([...tabAnimations, fabButtonAnimation, searchContainerAnimation, closeButtonsAnimation])
148
174
  .play();
149
175
 
150
176
  return {
@@ -159,6 +185,7 @@ const leaveEvent = async (
159
185
  ionTabBar: HTMLElement,
160
186
  ionFabButton: HTMLElement,
161
187
  ionFooter: HTMLElement,
188
+ verticalSearch: boolean,
162
189
  ): Promise<void> => {
163
190
  if (!(event.target as HTMLElement)?.closest('ion-buttons[slot=start] ion-button')) {
164
191
  throw throwErrorByFailedClickElement('ion-buttons[slot=start] ion-button');
@@ -166,10 +193,14 @@ const leaveEvent = async (
166
193
 
167
194
  const references = getElementReferences(ionTabBar, ionFooter);
168
195
 
169
- const effectAnimation = createReverseEffectAnimation(references, searchableEventCache.elementSizes, searchableEventCache.colorSelected);
196
+ const tabAnimations = verticalSearch
197
+ ? []
198
+ : [
199
+ createReverseTabBarAnimation(ionTabBar, references, searchableEventCache.elementSizes),
200
+ createReverseEffectAnimation(references, searchableEventCache.elementSizes, searchableEventCache.colorSelected),
201
+ ];
170
202
  const searchContainerAnimation = createReverseSearchContainerAnimation(references, searchableEventCache.elementSizes);
171
203
  const closeButtonsAnimation = createReverseCloseButtonsAnimation(references);
172
- const tabBarAnimation = createReverseTabBarAnimation(ionTabBar, references, searchableEventCache.elementSizes);
173
204
  const fabButtonAnimation = createReverseFabButtonAnimation(ionFabButton, searchableEventCache.elementSizes);
174
205
 
175
206
  await createAnimation()
@@ -179,6 +210,6 @@ const leaveEvent = async (
179
210
  .addElement(ionFooter)
180
211
  .afterAddWrite(() => (ionFooter.style.pointerEvents = 'none'))
181
212
  .fromTo('opacity', '1', '0')
182
- .addAnimation([tabBarAnimation, fabButtonAnimation, searchContainerAnimation, effectAnimation, closeButtonsAnimation])
213
+ .addAnimation([...tabAnimations, fabButtonAnimation, searchContainerAnimation, closeButtonsAnimation])
183
214
  .play();
184
215
  };
@@ -1,4 +1,3 @@
1
1
  export { enableVerticalControlArea, setVerticalControlAreaPlacement, IonicNativeUIShell } from './native';
2
- export { HingeStatus } from './native';
3
2
  export { withNativeUIShellTransition } from './native-integration/transition';
4
- export type { DeviceLayout, NativeUIShellStatus, NativeUIShellSuspension, VerticalBarEdge, VerticalControlAreaHandle } from './native';
3
+ export type { NativeUIShellStatus, NativeUIShellSuspension, VerticalBarEdge, VerticalControlAreaHandle } from './native';