@rdlabo/ionic-theme-ios27 1.2.0 → 1.2.1
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/dist/css/components/ion-button.css +1 -1
- package/dist/css/components/ion-toolbar.css +1 -1
- package/dist/css/ionic-theme-ios27.css +1 -1
- package/dist/css/vertical-bars.css +1 -1
- package/dist/native/components/index.js +2 -2
- package/dist/native/components/index.js.map +1 -1
- package/dist/native/prehide.d.ts.map +1 -1
- package/dist/native/prehide.js +6 -2
- package/dist/native/prehide.js.map +1 -1
- package/dist/native/runtime.d.ts.map +1 -1
- package/dist/native/runtime.js +4 -3
- package/dist/native/runtime.js.map +1 -1
- package/dist/native/shared/dom.d.ts +2 -0
- package/dist/native/shared/dom.d.ts.map +1 -1
- package/dist/native/shared/dom.js +5 -1
- package/dist/native/shared/dom.js.map +1 -1
- package/dist/native/vertical-bars-web.d.ts.map +1 -1
- package/dist/native/vertical-bars-web.js +4 -2
- package/dist/native/vertical-bars-web.js.map +1 -1
- package/dist/native-integration/index.d.ts +1 -1
- package/dist/native-integration/index.js.map +1 -1
- package/dist/native-integration/transition.d.ts +1 -1
- package/dist/native-integration/transition.js.map +1 -1
- package/dist/sheets-of-glass/animations.d.ts +1 -1
- package/dist/sheets-of-glass/animations.js +1 -1
- package/dist/sheets-of-glass/animations.js.map +1 -1
- package/dist/sheets-of-glass/index.js +1 -1
- package/dist/sheets-of-glass/index.js.map +1 -1
- package/dist/tab-bar-searchable/animations/enter.d.ts +1 -1
- package/dist/tab-bar-searchable/animations/enter.d.ts.map +1 -1
- package/dist/tab-bar-searchable/animations/enter.js +1 -1
- package/dist/tab-bar-searchable/animations/enter.js.map +1 -1
- package/dist/tab-bar-searchable/animations/leave.d.ts +1 -1
- package/dist/tab-bar-searchable/animations/leave.d.ts.map +1 -1
- package/dist/tab-bar-searchable/animations/leave.js +1 -1
- package/dist/tab-bar-searchable/animations/leave.js.map +1 -1
- package/dist/tab-bar-searchable/index.js +1 -1
- package/dist/tab-bar-searchable/index.js.map +1 -1
- package/dist/transition/index.d.ts +1 -1
- package/dist/transition/index.js +1 -1
- package/dist/transition/index.js.map +1 -1
- package/dist/transition/ios.transition.d.ts +1 -1
- package/dist/transition/ios.transition.js.map +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js.map +1 -1
- package/docs/native-ui-shell.md +2 -2
- package/docs/vertical-bars.md +3 -1
- package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellSearchController.swift +65 -91
- package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellTabBar.swift +9 -3
- package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellVerticalBars.swift +4 -2
- package/package.json +1 -1
- package/src/native/components/index.ts +3 -2
- package/src/native/prehide.ts +6 -1
- package/src/native/runtime.ts +5 -1
- package/src/native/shared/dom.ts +14 -0
- package/src/native/vertical-bars-web.ts +11 -1
- package/src/native-integration/index.ts +1 -1
- package/src/native-integration/transition.ts +1 -1
- package/src/sheets-of-glass/animations.ts +2 -2
- package/src/sheets-of-glass/index.ts +2 -2
- package/src/styles/components/ion-button.scss +47 -0
- package/src/styles/components/ion-toolbar.scss +62 -7
- package/src/styles/vertical-bars.scss +23 -0
- package/src/tab-bar-searchable/animations/enter.ts +2 -1
- package/src/tab-bar-searchable/animations/leave.ts +2 -1
- package/src/tab-bar-searchable/index.ts +1 -1
- package/src/transition/index.ts +3 -3
- package/src/transition/ios.transition.ts +1 -1
- package/src/utils.ts +1 -1
|
@@ -15,6 +15,8 @@ import {
|
|
|
15
15
|
preferredVerticalBarsBack,
|
|
16
16
|
verticalBarsOwned,
|
|
17
17
|
marker,
|
|
18
|
+
syncToolbarText,
|
|
19
|
+
toolbarTextMarker,
|
|
18
20
|
prehideOnlyMutation,
|
|
19
21
|
prehiddenClass,
|
|
20
22
|
unprojected,
|
|
@@ -271,6 +273,7 @@ export const createVerticalBarsWebProjection = (
|
|
|
271
273
|
};
|
|
272
274
|
const performUpdate = () => {
|
|
273
275
|
frame = 0;
|
|
276
|
+
syncToolbarText(doc);
|
|
274
277
|
const currentRoot = verticalBarsRoot();
|
|
275
278
|
if (observingVerticalBars !== !!currentRoot) {
|
|
276
279
|
observingVerticalBars = !!currentRoot;
|
|
@@ -278,6 +281,7 @@ export const createVerticalBarsWebProjection = (
|
|
|
278
281
|
observer.observe(doc.documentElement, {
|
|
279
282
|
subtree: true,
|
|
280
283
|
childList: true,
|
|
284
|
+
characterData: observingVerticalBars,
|
|
281
285
|
attributes: true,
|
|
282
286
|
attributeOldValue: true,
|
|
283
287
|
attributeFilter: observingVerticalBars ? undefined : ['class'],
|
|
@@ -335,7 +339,13 @@ export const createVerticalBarsWebProjection = (
|
|
|
335
339
|
);
|
|
336
340
|
if (
|
|
337
341
|
(observingVerticalBars &&
|
|
338
|
-
records.some(
|
|
342
|
+
records.some(
|
|
343
|
+
(record) =>
|
|
344
|
+
record.attributeName !== marker &&
|
|
345
|
+
record.attributeName !== toolbarTextMarker &&
|
|
346
|
+
!prehideOnlyMutation(record) &&
|
|
347
|
+
!insideProjection(record.target),
|
|
348
|
+
)) ||
|
|
339
349
|
(!observingVerticalBars && verticalBarsChanged && records.some((record) => !prehideOnlyMutation(record)))
|
|
340
350
|
)
|
|
341
351
|
schedule();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Animation, AnimationKeyFrames } from '@ionic/core';
|
|
1
|
+
import type { Animation, AnimationKeyFrames, GestureDetail } from '@ionic/core/components';
|
|
2
2
|
import { AnimationPosition, EffectScales } from './interfaces';
|
|
3
|
-
import { createAnimation
|
|
3
|
+
import { createAnimation } from '@ionic/core/components/index.js';
|
|
4
4
|
import { getStep } from '../utils';
|
|
5
5
|
|
|
6
6
|
// Work in main/cross-axis coordinates so native horizontal samples also drive the rail.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AnimationPosition, EffectScales, registeredEffect } from './interfaces';
|
|
2
|
-
import { createAnimation, createGesture } from '@ionic/core';
|
|
3
|
-
import type { Animation, Gesture, GestureDetail } from '@ionic/core';
|
|
2
|
+
import { createAnimation, createGesture } from '@ionic/core/components/index.js';
|
|
3
|
+
import type { Animation, Gesture, GestureDetail } from '@ionic/core/components';
|
|
4
4
|
import { changeSelectedElement, cloneElement, getStep } from '../utils';
|
|
5
5
|
import { isNativeUIShell } from '../native-integration';
|
|
6
6
|
import {
|
|
@@ -436,3 +436,50 @@ ion-button.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
|
436
436
|
ion-back-button.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
437
437
|
@include theme-button($is-back-button: true);
|
|
438
438
|
}
|
|
439
|
+
|
|
440
|
+
// Toolbar button typography and spacing follow system toolbar controls.
|
|
441
|
+
ion-toolbar.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
442
|
+
ion-button.ios:not(.ios-theme-disabled, .ios26-disabled):not(.button-small, .button-large):not(
|
|
443
|
+
:where(ion-buttons.ios-theme-disabled *, ion-buttons.ios26-disabled *)
|
|
444
|
+
) {
|
|
445
|
+
font-size: 1rem;
|
|
446
|
+
font-weight: 400;
|
|
447
|
+
// TODO(v2.0.0): Remove .back-button-has-icon-only; Ionic only adds it to ion-back-button.
|
|
448
|
+
&:not(.button-has-icon-only, .back-button-has-icon-only) {
|
|
449
|
+
--padding-start: 16px;
|
|
450
|
+
--padding-end: 16px;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
ion-buttons.ios:not(.ios-theme-disabled, .ios26-disabled):has(ion-button ~ ion-button):not(
|
|
455
|
+
:has(
|
|
456
|
+
ion-back-button,
|
|
457
|
+
ion-button:not(.button-clear),
|
|
458
|
+
ion-menu-button,
|
|
459
|
+
.ios-theme-disabled,
|
|
460
|
+
.ios26-disabled,
|
|
461
|
+
.button-small,
|
|
462
|
+
.button-large
|
|
463
|
+
)
|
|
464
|
+
) {
|
|
465
|
+
height: 44px;
|
|
466
|
+
padding-inline: 3.5px;
|
|
467
|
+
// SwiftUI toolbar items share glass with 16pt between their inner controls.
|
|
468
|
+
gap: 16px;
|
|
469
|
+
|
|
470
|
+
ion-button.ios:not(.ios-theme-disabled, .ios26-disabled).button-clear {
|
|
471
|
+
// Keep the action's hit area through the group's height, while the
|
|
472
|
+
// inner plain control follows the system's 36px visual layout.
|
|
473
|
+
height: 100%;
|
|
474
|
+
display: inline-flex;
|
|
475
|
+
align-items: center;
|
|
476
|
+
--padding-start: 7px;
|
|
477
|
+
--padding-end: 7px;
|
|
478
|
+
&::part(native) {
|
|
479
|
+
width: auto;
|
|
480
|
+
height: 36px;
|
|
481
|
+
min-height: 36px;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
@@ -13,22 +13,27 @@ ion-header.ios:not(.ios-theme-disabled, .ios26-disabled) ion-toolbar:not(.ios-th
|
|
|
13
13
|
ion-modal.ios:not(.ios-theme-disabled, .ios26-disabled).modal-card,
|
|
14
14
|
ion-modal.ios:not(.ios-theme-disabled, .ios26-disabled).modal-sheet {
|
|
15
15
|
ion-header.ios:not(.ios-theme-disabled, .ios26-disabled) ion-toolbar.ios:not(.ios-theme-disabled, .ios26-disabled):first-of-type {
|
|
16
|
-
|
|
16
|
+
// The system's modal safe area places the 44px control 16px below the
|
|
17
|
+
// content edge, with or without a sheet drag indicator.
|
|
18
|
+
padding-top: 6px;
|
|
17
19
|
padding-bottom: 0;
|
|
18
20
|
--min-height: 64px;
|
|
19
|
-
--padding-start: 3px;
|
|
20
|
-
--padding-end: 3px;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
@media (min-width: 768px) and (min-height: 600px) {
|
|
25
|
-
ion-modal.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
25
|
+
ion-modal.ios:not(.ios-theme-disabled, .ios26-disabled):not(.modal-sheet) {
|
|
26
26
|
ion-header.ios:not(.ios-theme-disabled, .ios26-disabled) ion-toolbar.ios:not(.ios-theme-disabled, .ios26-disabled):first-of-type {
|
|
27
|
-
|
|
27
|
+
// Center a 44px control at 10px, retaining the safe area in fullscreen modals.
|
|
28
|
+
padding-top: max(calc(var(--ion-safe-area-top, 0px) - 10px), 0px);
|
|
28
29
|
padding-bottom: 0;
|
|
29
30
|
--min-height: 64px;
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Ionic keeps the root safe area in card modals, including centered dialogs.
|
|
34
|
+
ion-modal.ios:not(.ios-theme-disabled, .ios26-disabled).modal-card {
|
|
35
|
+
ion-header.ios:not(.ios-theme-disabled, .ios26-disabled) ion-toolbar.ios:not(.ios-theme-disabled, .ios26-disabled):first-of-type {
|
|
36
|
+
padding-top: 0;
|
|
32
37
|
}
|
|
33
38
|
}
|
|
34
39
|
}
|
|
@@ -106,4 +111,54 @@ ion-toolbar.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
|
106
111
|
ion-buttons > ion-back-button {
|
|
107
112
|
margin-inline: 0;
|
|
108
113
|
}
|
|
114
|
+
|
|
115
|
+
// Keep the outer inset for individual actions too. Adjacent actions in the
|
|
116
|
+
// same slot share a 12px gap rather than adding two outer margins together.
|
|
117
|
+
> ion-button:not(.ios-theme-disabled, .ios26-disabled) {
|
|
118
|
+
margin-inline: 12px;
|
|
119
|
+
}
|
|
120
|
+
// Rail sources leave toolbar layout; ordinary native projection retains it.
|
|
121
|
+
$visible: ':not([hidden], .ios-theme-native-ui-shell-prehidden, [data-native-ui-shell][data-native-ui-shell-vertical-bars], ion-menu-button.menu-button-hidden, ion-back-button:not(.show-back-button))';
|
|
122
|
+
$button: ':is(ion-button, ion-back-button)#{$visible}';
|
|
123
|
+
$group: 'ion-buttons#{$visible}';
|
|
124
|
+
$action: ':is(#{$button}, #{$group}:has(> #{$visible}))';
|
|
125
|
+
$optOut: ':is(.ios-theme-disabled, .ios26-disabled)';
|
|
126
|
+
|
|
127
|
+
> ion-buttons:not(:has(> #{$visible})) {
|
|
128
|
+
display: none;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@each $slot in start, end, primary, secondary {
|
|
132
|
+
// Keep standalone margins when the slot includes a visible opted-out action.
|
|
133
|
+
&:not(.toolbar-searchbar):not(:has(> #{$button}#{$optOut}[slot='#{$slot}'], > #{$group}#{$optOut}[slot='#{$slot}'] > #{$visible})) {
|
|
134
|
+
> #{$action}[slot='#{$slot}'] {
|
|
135
|
+
margin-inline: 6px;
|
|
136
|
+
}
|
|
137
|
+
> :nth-child(1 of #{$action}[slot='#{$slot}']) {
|
|
138
|
+
margin-inline-start: 12px;
|
|
139
|
+
}
|
|
140
|
+
> :nth-last-child(1 of #{$action}[slot='#{$slot}']) {
|
|
141
|
+
margin-inline-end: 12px;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Ionic orders these slots together, independently of their DOM order.
|
|
146
|
+
@each $first, $second in (start, secondary), (primary, end) {
|
|
147
|
+
&:not(.toolbar-searchbar):has(> #{$button}[slot='#{$first}'], > #{$group}[slot='#{$first}'] > #{$visible}):has(
|
|
148
|
+
> #{$button}[slot='#{$second}'],
|
|
149
|
+
> #{$group}[slot='#{$second}'] > #{$visible}
|
|
150
|
+
):not(
|
|
151
|
+
:has(
|
|
152
|
+
> #{$button}#{$optOut}:is([slot='#{$first}'], [slot='#{$second}']),
|
|
153
|
+
> #{$group}#{$optOut}:is([slot='#{$first}'], [slot='#{$second}']) > #{$visible}
|
|
154
|
+
)
|
|
155
|
+
) {
|
|
156
|
+
> :nth-last-child(1 of #{$action}[slot='#{$first}']) {
|
|
157
|
+
margin-inline-end: 6px;
|
|
158
|
+
}
|
|
159
|
+
> :nth-child(1 of #{$action}[slot='#{$second}']) {
|
|
160
|
+
margin-inline-start: 6px;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
109
164
|
}
|
|
@@ -92,8 +92,31 @@ ion-app.ios-theme-vertical-bars
|
|
|
92
92
|
--ion-safe-area-left: 0px;
|
|
93
93
|
--ion-safe-area-right: 0px;
|
|
94
94
|
|
|
95
|
+
// Reserve the final layout before a page transition, using the same prehide
|
|
96
|
+
// decision as its rail controls. Horizontal native projection keeps its space.
|
|
97
|
+
// Titles, custom content and horizontal-only controls keep the toolbar visible.
|
|
98
|
+
&:not([data-native-ui-shell-toolbar-text]):has(
|
|
99
|
+
> .ios-theme-native-ui-shell-prehidden,
|
|
100
|
+
> ion-buttons > .ios-theme-native-ui-shell-prehidden
|
|
101
|
+
):not(:has(> :not(ion-buttons, .ios-theme-native-ui-shell-prehidden))):not(
|
|
102
|
+
:has(> ion-buttons:not(.ios-theme-native-ui-shell-prehidden) > :not(.ios-theme-native-ui-shell-prehidden))
|
|
103
|
+
) {
|
|
104
|
+
display: none;
|
|
105
|
+
}
|
|
106
|
+
|
|
95
107
|
// Collapse headers already sit inside the padded ion-content scroll area.
|
|
96
108
|
&:not(:where(ion-header.header-collapse-condense *, ion-footer.footer-collapse-fade *)) {
|
|
109
|
+
// Ionic's centered iOS title is absolute and does not follow container padding.
|
|
110
|
+
// Center it within the same foreground width as the page content.
|
|
111
|
+
> ion-title.ios.title-default:not(.ios-theme-disabled, .ios26-disabled) {
|
|
112
|
+
inset-inline-start: var(--ios-theme-vertical-bars-safe-area-left-resolved);
|
|
113
|
+
width: calc(100% - var(--ios-theme-vertical-bars-safe-area-left-resolved) - var(--ios-theme-vertical-bars-safe-area-right-resolved));
|
|
114
|
+
|
|
115
|
+
&:dir(rtl) {
|
|
116
|
+
inset-inline-start: var(--ios-theme-vertical-bars-safe-area-right-resolved);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
97
120
|
&::part(container) {
|
|
98
121
|
padding-inline-start: calc(var(--padding-start, 0px) + var(--ios-theme-vertical-bars-safe-area-left-resolved));
|
|
99
122
|
padding-inline-end: calc(var(--padding-end, 0px) + var(--ios-theme-vertical-bars-safe-area-right-resolved));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Animation
|
|
1
|
+
import type { Animation } from '@ionic/core/components';
|
|
2
|
+
import { createAnimation } from '@ionic/core/components/index.js';
|
|
2
3
|
import { ANIMATION_DELAY_CLOSE_BUTTONS, OPACITY_TRANSITION, type ElementReferences, type ElementSizes } from '@rdlabo/ionic-theme-utils';
|
|
3
4
|
import { cloneElement } from '../../utils';
|
|
4
5
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Animation
|
|
1
|
+
import type { Animation } from '@ionic/core/components';
|
|
2
|
+
import { createAnimation } from '@ionic/core/components/index.js';
|
|
2
3
|
import { ANIMATION_DELAY_CLOSE_BUTTONS, OPACITY_TRANSITION, type ElementReferences, type ElementSizes } from '@rdlabo/ionic-theme-utils';
|
|
3
4
|
import { cloneElement } from '../../utils';
|
|
4
5
|
|
package/src/transition/index.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { config } from '../utils';
|
|
2
2
|
import { Build, writeTask } from '@stencil/core';
|
|
3
3
|
|
|
4
|
-
import { LIFECYCLE_DID_ENTER, LIFECYCLE_DID_LEAVE, LIFECYCLE_WILL_ENTER, LIFECYCLE_WILL_LEAVE } from '@ionic/core';
|
|
5
|
-
import type { NavOptions, NavDirection } from '@ionic/core';
|
|
6
|
-
import type { Animation, AnimationBuilder } from '@ionic/core';
|
|
4
|
+
import { LIFECYCLE_DID_ENTER, LIFECYCLE_DID_LEAVE, LIFECYCLE_WILL_ENTER, LIFECYCLE_WILL_LEAVE } from '@ionic/core/components/index.js';
|
|
5
|
+
import type { NavOptions, NavDirection } from '@ionic/core/components';
|
|
6
|
+
import type { Animation, AnimationBuilder } from '@ionic/core/components';
|
|
7
7
|
import { createFocusController } from '../focus-controller';
|
|
8
8
|
import { raf } from '../utils';
|
|
9
9
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createIosTransitionAnimation, shadow } from '@rdlabo/ionic-theme-utils';
|
|
2
|
-
import type { Animation } from '@ionic/core';
|
|
2
|
+
import type { Animation } from '@ionic/core/components';
|
|
3
3
|
import type { TransitionOptions } from './index';
|
|
4
4
|
import { getIonPageElement } from './index';
|
|
5
5
|
import { withNativeUIShellTransition } from '../native-integration/transition';
|
package/src/utils.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AnimationPosition } from './sheets-of-glass/interfaces';
|
|
2
|
-
import { IonicConfig } from '@ionic/core';
|
|
2
|
+
import type { IonicConfig } from '@ionic/core/components';
|
|
3
3
|
|
|
4
4
|
declare const __zone_symbol__requestAnimationFrame: ((callback: FrameRequestCallback) => number) | undefined;
|
|
5
5
|
declare const requestAnimationFrame: ((callback: FrameRequestCallback) => number) | undefined;
|