@rdlabo/ionic-theme-ios27 1.2.0-0 → 1.2.0-2
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/README.md +12 -2
- package/dist/css/components/ion-tabs.css +1 -1
- package/dist/css/ionic-theme-ios27.css +1 -1
- package/dist/css/vertical-bars.css +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -12
- package/dist/native/components/index.d.ts.map +1 -1
- package/dist/native/components/index.js +4 -1
- package/dist/native/components/ion-button.d.ts.map +1 -1
- package/dist/native/components/ion-button.js +3 -3
- package/dist/native/components/ion-buttons.d.ts.map +1 -1
- package/dist/native/components/ion-buttons.js +3 -2
- package/dist/native/definitions.d.ts +8 -15
- package/dist/native/definitions.d.ts.map +1 -1
- package/dist/native/definitions.js +1 -6
- package/dist/native/index.d.ts +1 -2
- package/dist/native/index.d.ts.map +1 -1
- package/dist/native/index.js +64 -28
- package/dist/native/prehide.d.ts.map +1 -1
- package/dist/native/prehide.js +6 -4
- package/dist/native/runtime.d.ts.map +1 -1
- package/dist/native/runtime.js +27 -12
- package/dist/native/shared/candidate.d.ts.map +1 -1
- package/dist/native/shared/candidate.js +8 -0
- package/dist/native/shared/dom.d.ts.map +1 -1
- package/dist/native/shared/dom.js +11 -10
- package/dist/native/shared/modal.d.ts +8 -0
- package/dist/native/shared/modal.d.ts.map +1 -0
- package/dist/native/shared/modal.js +143 -0
- package/dist/native/vertical-bars-web.d.ts.map +1 -1
- package/dist/native/vertical-bars-web.js +11 -3
- package/dist/native-integration/index.d.ts.map +1 -1
- package/dist/native-integration/index.js +7 -2
- package/dist/native-integration/transition.d.ts +3 -0
- package/dist/native-integration/transition.d.ts.map +1 -0
- package/dist/native-integration/transition.js +7 -0
- package/dist/sheets-of-glass/animations.d.ts +13 -4
- package/dist/sheets-of-glass/animations.d.ts.map +1 -1
- package/dist/sheets-of-glass/animations.js +56 -40
- package/dist/sheets-of-glass/index.d.ts +1 -1
- package/dist/sheets-of-glass/index.d.ts.map +1 -1
- package/dist/sheets-of-glass/index.js +64 -20
- package/dist/transition/ios.transition.d.ts.map +1 -1
- package/dist/transition/ios.transition.js +2 -3
- package/dist/vertical-bars.d.ts +2 -2
- package/dist/vertical-bars.d.ts.map +1 -1
- package/dist/vertical-bars.js +1 -1
- package/docs/iphone-duo-with-original-theme.md +171 -0
- package/docs/iphone-duo.md +105 -50
- package/docs/migration.md +23 -0
- package/docs/native-ui-shell.md +10 -6
- package/docs/special-markup.md +3 -14
- package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellVerticalBars.swift +23 -4
- package/ios/Sources/IonicNativeUIShellPlugin/IonicNativeUIShellPlugin.swift +15 -171
- package/ios/Sources/IonicNativeUIShellPlugin/Shared/ShellSnapshot.swift +5 -0
- package/ios/Tests/IonicNativeUIShellPluginTests/ShellSnapshotTests.swift +30 -0
- package/package.json +1 -1
- package/src/index.ts +41 -9
- package/src/native/components/index.ts +6 -1
- package/src/native/components/ion-button.ts +4 -3
- package/src/native/components/ion-buttons.ts +4 -2
- package/src/native/definitions.ts +11 -19
- package/src/native/index.ts +67 -30
- package/src/native/prehide.ts +7 -4
- package/src/native/runtime.ts +28 -11
- package/src/native/shared/candidate.ts +10 -0
- package/src/native/shared/dom.ts +11 -10
- package/src/native/shared/modal.ts +157 -0
- package/src/native/vertical-bars-web.ts +12 -3
- package/src/native-integration/index.ts +8 -2
- package/src/native-integration/transition.ts +15 -0
- package/src/sheets-of-glass/animations.ts +66 -41
- package/src/sheets-of-glass/index.ts +82 -16
- package/src/styles/components/ion-tabs.scss +7 -4
- package/src/styles/vertical-bars.scss +102 -35
- package/src/transition/ios.transition.ts +4 -4
- package/src/vertical-bars.ts +2 -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);
|
|
@@ -46,7 +59,9 @@ ion-app.ios-theme-vertical-bars .ios-transition-shade {
|
|
|
46
59
|
|
|
47
60
|
// Keep page backgrounds and the router full width; move only their foregrounds.
|
|
48
61
|
ion-app.ios-theme-vertical-bars
|
|
49
|
-
ion-content:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(
|
|
62
|
+
ion-content:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(
|
|
63
|
+
:where(ion-menu *, ion-modal:not(.ios-theme-vertical-bars-modal) *, ion-popover *)
|
|
64
|
+
) {
|
|
50
65
|
--ion-safe-area-left: 0px;
|
|
51
66
|
--ion-safe-area-right: 0px;
|
|
52
67
|
|
|
@@ -62,7 +77,9 @@ ion-app.ios-theme-vertical-bars
|
|
|
62
77
|
}
|
|
63
78
|
|
|
64
79
|
ion-app.ios-theme-vertical-bars
|
|
65
|
-
ion-toolbar:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(
|
|
80
|
+
ion-toolbar:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(
|
|
81
|
+
:where(ion-menu *, ion-modal:not(.ios-theme-vertical-bars-modal) *, ion-popover *)
|
|
82
|
+
) {
|
|
66
83
|
--ion-safe-area-left: 0px;
|
|
67
84
|
--ion-safe-area-right: 0px;
|
|
68
85
|
|
|
@@ -131,37 +148,44 @@ ion-app.ios-theme-vertical-bars {
|
|
|
131
148
|
ion-app.ios-theme-vertical-bars
|
|
132
149
|
ion-tabs:not(:where(ion-menu *, ion-modal *, ion-popover *))
|
|
133
150
|
> ion-tab-bar:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled) {
|
|
134
|
-
|
|
135
|
-
--ios-theme-side-tab-bar-
|
|
136
|
-
--ios-theme-side-
|
|
151
|
+
// iOS 27.1 Duo: 48pt platter, 44 × 58pt items with 8pt overlap, 24pt edge gaps.
|
|
152
|
+
--ios-theme-side-tab-bar-width: 48px;
|
|
153
|
+
--ios-theme-side-tab-content-width: 44px;
|
|
154
|
+
--ios-theme-side-tab-bar-gap: 24px;
|
|
137
155
|
contain: layout style;
|
|
138
156
|
position: absolute;
|
|
139
157
|
z-index: 2;
|
|
140
158
|
display: flex;
|
|
141
159
|
flex-direction: column;
|
|
142
|
-
width:
|
|
143
|
-
min-width:
|
|
144
|
-
max-width:
|
|
160
|
+
width: 44px;
|
|
161
|
+
min-width: 44px;
|
|
162
|
+
max-width: 44px;
|
|
145
163
|
height: fit-content;
|
|
146
164
|
min-height: 0;
|
|
147
165
|
padding: 2px;
|
|
148
|
-
border-radius:
|
|
166
|
+
border-radius: 24px;
|
|
149
167
|
left: auto;
|
|
150
|
-
right:
|
|
168
|
+
right: calc(24px + (48px - var(--ios-theme-side-tab-bar-width)) / 2);
|
|
151
169
|
margin: 0;
|
|
152
170
|
top: auto;
|
|
153
|
-
bottom:
|
|
171
|
+
bottom: var(--ios-theme-side-tab-bar-gap);
|
|
172
|
+
|
|
173
|
+
&.ios27-enable-gesture {
|
|
174
|
+
touch-action: pan-x pinch-zoom;
|
|
175
|
+
}
|
|
154
176
|
|
|
155
177
|
> ion-tab-button:not(.ion-cloned-element) {
|
|
156
178
|
display: block;
|
|
157
179
|
flex: none;
|
|
158
|
-
width:
|
|
159
|
-
min-width:
|
|
160
|
-
height:
|
|
161
|
-
min-height:
|
|
162
|
-
border-radius:
|
|
180
|
+
width: 44px;
|
|
181
|
+
min-width: 44px;
|
|
182
|
+
height: 58px;
|
|
183
|
+
min-height: 58px;
|
|
184
|
+
border-radius: 22px;
|
|
163
185
|
&::part(native) {
|
|
164
186
|
justify-content: center;
|
|
187
|
+
min-height: 58px;
|
|
188
|
+
padding: 0;
|
|
165
189
|
}
|
|
166
190
|
ion-label {
|
|
167
191
|
position: absolute;
|
|
@@ -179,32 +203,54 @@ ion-app.ios-theme-vertical-bars
|
|
|
179
203
|
font-size: 28px;
|
|
180
204
|
}
|
|
181
205
|
}
|
|
206
|
+
> ion-tab-button.ion-activated {
|
|
207
|
+
transform: scale(1.16);
|
|
208
|
+
}
|
|
182
209
|
> ion-tab-button:not(.ion-cloned-element) ~ ion-tab-button:not(.ion-cloned-element) {
|
|
183
|
-
margin-block-start:
|
|
210
|
+
margin-block-start: -8px;
|
|
184
211
|
margin-inline-start: 0;
|
|
185
212
|
}
|
|
186
|
-
|
|
213
|
+
// Duo's expanded platter keeps its center and reveals labels without shrinking icons.
|
|
214
|
+
&:is(.ios27-animated, :has(> ion-tab-button:is(.ion-activated, :active))) {
|
|
215
|
+
--ios-theme-side-tab-bar-width: 72px;
|
|
216
|
+
--ios-theme-side-tab-content-width: 64px;
|
|
217
|
+
--ios-theme-side-tab-bar-gap: 20px;
|
|
218
|
+
width: 64px;
|
|
219
|
+
min-width: 64px;
|
|
220
|
+
max-width: 64px;
|
|
221
|
+
padding: 4px;
|
|
222
|
+
border-radius: 36px;
|
|
223
|
+
transform: none;
|
|
224
|
+
-webkit-transform: none;
|
|
225
|
+
}
|
|
226
|
+
&:is(.ios27-animated, :has(> ion-tab-button:is(.ion-activated, :active))) > ion-tab-button:not(.ion-cloned-element) {
|
|
227
|
+
width: 64px;
|
|
228
|
+
min-width: 64px;
|
|
229
|
+
height: 64px;
|
|
230
|
+
min-height: 64px;
|
|
231
|
+
border-radius: 32px;
|
|
187
232
|
&::part(native) {
|
|
188
233
|
flex-direction: column;
|
|
189
|
-
|
|
234
|
+
min-height: 64px;
|
|
235
|
+
padding-block: 11px;
|
|
190
236
|
}
|
|
191
237
|
ion-label {
|
|
192
238
|
position: static;
|
|
193
239
|
width: auto;
|
|
194
240
|
height: auto;
|
|
195
|
-
max-width:
|
|
241
|
+
max-width: 64px;
|
|
196
242
|
padding: 0;
|
|
197
243
|
margin: 1px 0 0;
|
|
198
244
|
overflow: hidden;
|
|
199
245
|
clip: auto;
|
|
200
|
-
font-size:
|
|
201
|
-
line-height:
|
|
246
|
+
font-size: 10px;
|
|
247
|
+
line-height: 12px;
|
|
202
248
|
text-overflow: ellipsis;
|
|
203
249
|
white-space: nowrap;
|
|
204
250
|
}
|
|
205
251
|
ion-icon {
|
|
206
252
|
margin: 0;
|
|
207
|
-
font-size:
|
|
253
|
+
font-size: 28px;
|
|
208
254
|
}
|
|
209
255
|
}
|
|
210
256
|
}
|
|
@@ -212,9 +258,8 @@ ion-app.ios-theme-vertical-bars
|
|
|
212
258
|
ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left
|
|
213
259
|
ion-tabs:not(:where(ion-menu *, ion-modal *, ion-popover *))
|
|
214
260
|
> 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
261
|
right: auto;
|
|
217
|
-
left:
|
|
262
|
+
left: calc(24px + (48px - var(--ios-theme-side-tab-bar-width)) / 2);
|
|
218
263
|
}
|
|
219
264
|
|
|
220
265
|
.ios-theme-native-ui-shell-prehidden {
|
|
@@ -251,8 +296,11 @@ html.ios-theme-native-ui-shell-prehide
|
|
|
251
296
|
visibility: hidden !important;
|
|
252
297
|
}
|
|
253
298
|
|
|
254
|
-
ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready
|
|
255
|
-
|
|
299
|
+
ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready,
|
|
300
|
+
ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready {
|
|
301
|
+
ion-toolbar:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(
|
|
302
|
+
:where(ion-menu *, ion-modal:not(.ios-theme-vertical-bars-modal) *, ion-popover *)
|
|
303
|
+
)
|
|
256
304
|
ion-back-button:is(.ios, .md)[data-native-ui-shell]:not(
|
|
257
305
|
.ios-theme-disabled,
|
|
258
306
|
.ios26-disabled,
|
|
@@ -260,7 +308,9 @@ ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready {
|
|
|
260
308
|
) {
|
|
261
309
|
display: none;
|
|
262
310
|
}
|
|
263
|
-
ion-toolbar:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(
|
|
311
|
+
ion-toolbar:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(
|
|
312
|
+
:where(ion-menu *, ion-modal:not(.ios-theme-vertical-bars-modal) *, ion-popover *)
|
|
313
|
+
)
|
|
264
314
|
ion-buttons:is(.ios, .md)
|
|
265
315
|
> :is(ion-button, ion-menu-button):is(.ios, .md)[data-native-ui-shell]:not(
|
|
266
316
|
.ios-theme-disabled,
|
|
@@ -269,7 +319,9 @@ ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready {
|
|
|
269
319
|
) {
|
|
270
320
|
display: none;
|
|
271
321
|
}
|
|
272
|
-
ion-toolbar:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(
|
|
322
|
+
ion-toolbar:is(.ios, .md):not(.ios-theme-disabled, .ios26-disabled):not(
|
|
323
|
+
:where(ion-menu *, ion-modal:not(.ios-theme-vertical-bars-modal) *, ion-popover *)
|
|
324
|
+
)
|
|
273
325
|
ion-buttons:is(.ios, .md):has(> :is(ion-back-button, ion-button, ion-menu-button)[data-native-ui-shell]):not(
|
|
274
326
|
:has(> :is(ion-back-button, ion-button, ion-menu-button):not([data-native-ui-shell]))
|
|
275
327
|
) {
|
|
@@ -278,7 +330,7 @@ ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready {
|
|
|
278
330
|
> ion-back-button.ios-theme-vertical-bars-back-button-projection {
|
|
279
331
|
position: fixed;
|
|
280
332
|
z-index: 1001;
|
|
281
|
-
top: var(--ios-theme-vertical-bars-toolbar-top, 220px);
|
|
333
|
+
top: var(--ios-theme-vertical-bars-modal-toolbar-top, var(--ios-theme-vertical-bars-toolbar-top, 220px));
|
|
282
334
|
right: max(4px, calc((var(--ios-theme-vertical-bars-safe-area-right-resolved) - 46px) / 2));
|
|
283
335
|
display: block;
|
|
284
336
|
width: 46px;
|
|
@@ -288,7 +340,10 @@ ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready {
|
|
|
288
340
|
> :is(.ios, .md).ios-theme-vertical-bars-toolbar-projection {
|
|
289
341
|
position: fixed;
|
|
290
342
|
z-index: 1001;
|
|
291
|
-
top: calc(
|
|
343
|
+
top: calc(
|
|
344
|
+
var(--ios-theme-vertical-bars-modal-toolbar-top, var(--ios-theme-vertical-bars-toolbar-top, 220px)) +
|
|
345
|
+
var(--ios-theme-vertical-bars-toolbar-offset, 0px)
|
|
346
|
+
);
|
|
292
347
|
right: max(4px, calc((var(--ios-theme-vertical-bars-safe-area-right-resolved) - 46px) / 2));
|
|
293
348
|
width: 46px;
|
|
294
349
|
min-width: 46px;
|
|
@@ -307,10 +362,12 @@ ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready {
|
|
|
307
362
|
border-radius: 50%;
|
|
308
363
|
}
|
|
309
364
|
> ion-button:is(.ios, .md).ios-theme-vertical-bars-toolbar-projection {
|
|
310
|
-
|
|
365
|
+
&:not(.button-solid):not(.button-outline) {
|
|
366
|
+
--background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0.72);
|
|
367
|
+
}
|
|
311
368
|
--border-radius: 50%;
|
|
312
369
|
@include glass.light-shadow('--box-shadow');
|
|
313
|
-
|
|
370
|
+
&:not(.button-outline)::part(native) {
|
|
314
371
|
@include api.glass-control-background($include-background: false, $shadow: var(--box-shadow));
|
|
315
372
|
}
|
|
316
373
|
}
|
|
@@ -333,10 +390,20 @@ ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready {
|
|
|
333
390
|
}
|
|
334
391
|
}
|
|
335
392
|
|
|
336
|
-
ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left
|
|
393
|
+
ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left,
|
|
394
|
+
ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left ion-modal.ios-theme-vertical-bars-modal {
|
|
337
395
|
> ion-back-button.ios-theme-vertical-bars-back-button-projection,
|
|
338
396
|
> :is(.ios, .md).ios-theme-vertical-bars-toolbar-projection {
|
|
339
397
|
right: auto;
|
|
340
398
|
left: max(4px, calc((var(--ios-theme-vertical-bars-safe-area-left-resolved) - 46px) / 2));
|
|
341
399
|
}
|
|
342
400
|
}
|
|
401
|
+
|
|
402
|
+
// The lens is attached to body, outside the rail selectors.
|
|
403
|
+
ion-tab-button.ios.ion-cloned-element.ios27-vertical-tab-effect {
|
|
404
|
+
border-radius: 32px;
|
|
405
|
+
&::part(native) {
|
|
406
|
+
min-height: 0;
|
|
407
|
+
height: 100%;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
@@ -2,7 +2,7 @@ import { createIosTransitionAnimation, shadow } from '@rdlabo/ionic-theme-utils'
|
|
|
2
2
|
import type { Animation } from '@ionic/core';
|
|
3
3
|
import type { TransitionOptions } from './index';
|
|
4
4
|
import { getIonPageElement } from './index';
|
|
5
|
-
import {
|
|
5
|
+
import { withNativeUIShellTransition } from '../native-integration/transition';
|
|
6
6
|
|
|
7
7
|
export { shadow };
|
|
8
8
|
|
|
@@ -13,7 +13,6 @@ export interface IosTransitionConfig {
|
|
|
13
13
|
const transitionConfig = {
|
|
14
14
|
offLeftPercent: 30,
|
|
15
15
|
getIonPageElement,
|
|
16
|
-
connectNativeUIShellTransition,
|
|
17
16
|
shouldAnimateFixedBackButton: (navEl: HTMLElement) => !navEl.closest('ion-app.ios-theme-vertical-bars'),
|
|
18
17
|
radius: 0,
|
|
19
18
|
};
|
|
@@ -22,5 +21,6 @@ export const setConfig = (config: Partial<IosTransitionConfig>): void => {
|
|
|
22
21
|
Object.assign(transitionConfig, config);
|
|
23
22
|
};
|
|
24
23
|
|
|
25
|
-
export const iosTransitionAnimation: (navEl: HTMLElement, opts: TransitionOptions) => Animation =
|
|
26
|
-
createIosTransitionAnimation<TransitionOptions>(transitionConfig)
|
|
24
|
+
export const iosTransitionAnimation: (navEl: HTMLElement, opts: TransitionOptions) => Animation = withNativeUIShellTransition(
|
|
25
|
+
createIosTransitionAnimation<TransitionOptions>(transitionConfig),
|
|
26
|
+
);
|
package/src/vertical-bars.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { enableVerticalControlArea, setVerticalControlAreaPlacement, IonicNativeUIShell } from './native';
|
|
2
|
-
export {
|
|
3
|
-
export type {
|
|
2
|
+
export { withNativeUIShellTransition } from './native-integration/transition';
|
|
3
|
+
export type { NativeUIShellStatus, NativeUIShellSuspension, VerticalBarEdge, VerticalControlAreaHandle } from './native';
|