@rdlabo/ionic-theme-ios27 0.1.0-beta.pr153.sha1c3caf4dc12b → 0.1.0
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 +3 -3
- package/dist/css/components/ion-action-sheet.css +1 -1
- package/dist/css/components/ion-alert.css +1 -1
- package/dist/css/components/ion-button.css +1 -1
- package/dist/css/components/ion-card.css +1 -1
- package/dist/css/components/ion-fab.css +1 -1
- package/dist/css/components/ion-list.css +1 -1
- package/dist/css/components/ion-menu.css +1 -1
- package/dist/css/components/ion-modal.css +1 -1
- package/dist/css/components/ion-popover.css +1 -1
- package/dist/css/components/ion-range.css +1 -1
- package/dist/css/components/ion-segment.css +1 -1
- package/dist/css/components/ion-tabs.css +1 -1
- package/dist/css/components/ion-toast.css +1 -1
- package/dist/css/components/ion-toolbar.css +1 -1
- package/dist/css/default-variables.css +1 -1
- package/dist/css/ionic-theme-ios27-dark-always.css +1 -1
- package/dist/css/ionic-theme-ios27-dark-class.css +1 -1
- package/dist/css/ionic-theme-ios27-dark-system.css +1 -1
- package/dist/css/ionic-theme-ios27.css +1 -1
- package/dist/css/md-ion-list-inset.css +1 -1
- package/dist/css/utils/dark/ion-list.css +1 -0
- package/dist/css/utils/group-heading.css +1 -0
- package/dist/native/components/searchable-tabs.d.ts.map +1 -1
- package/dist/native/components/searchable-tabs.js +9 -1
- package/dist/native/definitions.d.ts +4 -0
- package/dist/native/definitions.d.ts.map +1 -1
- package/dist/native/runtime.d.ts.map +1 -1
- package/dist/native/runtime.js +51 -27
- package/dist/native/shared/candidate.d.ts.map +1 -1
- package/dist/native/shared/candidate.js +17 -0
- package/dist/native/shared/crossfade.d.ts +8 -0
- package/dist/native/shared/crossfade.d.ts.map +1 -0
- package/dist/native/shared/crossfade.js +46 -0
- package/dist/native/shared/dom.d.ts.map +1 -1
- package/dist/native/shared/dom.js +2 -1
- package/dist/popover/animations/ios.enter.d.ts.map +1 -1
- package/dist/popover/animations/ios.enter.js +105 -9
- package/dist/popover/animations/ios.leave.d.ts.map +1 -1
- package/dist/popover/animations/ios.leave.js +15 -1
- package/dist/popover/callout-surface.d.ts +2 -0
- package/dist/popover/callout-surface.d.ts.map +1 -0
- package/dist/popover/callout-surface.js +44 -0
- package/dist/sheets-of-glass/index.js +2 -1
- package/dist/transition/ios.transition.d.ts.map +1 -1
- package/dist/transition/ios.transition.js +0 -223
- package/docs/experimental-animation.md +3 -3
- package/docs/features.md +7 -2
- package/docs/native-ui-shell.md +14 -5
- package/docs/special-markup.md +17 -0
- package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellButton.swift +7 -2
- package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellSearchController.swift +10 -0
- package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellSegment.swift +47 -15
- package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellTabBar.swift +42 -7
- package/ios/Sources/IonicNativeUIShellPlugin/IonicNativeUIShellPlugin.swift +13 -6
- package/ios/Sources/IonicNativeUIShellPlugin/Shared/ShellCrossfade.swift +35 -0
- package/ios/Sources/IonicNativeUIShellPlugin/Shared/ShellSnapshot.swift +6 -1
- package/ios/Tests/IonicNativeUIShellPluginTests/ShellSnapshotTests.swift +59 -0
- package/package.json +1 -1
- package/src/native/components/searchable-tabs.ts +12 -1
- package/src/native/definitions.ts +4 -0
- package/src/native/runtime.ts +54 -31
- package/src/native/shared/candidate.ts +19 -0
- package/src/native/shared/crossfade.ts +49 -0
- package/src/native/shared/dom.ts +4 -1
- package/src/popover/animations/ios.enter.ts +123 -10
- package/src/popover/animations/ios.leave.ts +15 -1
- package/src/popover/callout-surface.ts +54 -0
- package/src/sheets-of-glass/index.ts +2 -2
- package/src/styles/components/ion-action-sheet.scss +35 -17
- package/src/styles/components/ion-alert.scss +51 -31
- package/src/styles/components/ion-button.scss +4 -7
- package/src/styles/components/ion-card.scss +64 -3
- package/src/styles/components/ion-fab.scss +3 -5
- package/src/styles/components/ion-list.scss +14 -1
- package/src/styles/components/ion-menu.scss +19 -7
- package/src/styles/components/ion-modal.scss +63 -14
- package/src/styles/components/ion-popover.scss +52 -9
- package/src/styles/components/ion-range.scss +49 -50
- package/src/styles/components/ion-segment.scss +15 -16
- package/src/styles/components/ion-tabs.scss +73 -13
- package/src/styles/components/ion-toast.scss +16 -25
- package/src/styles/components/ion-toolbar.scss +17 -1
- package/src/styles/default-variables.scss +4 -0
- package/src/styles/utils/_glass.scss +96 -0
- package/src/styles/utils/api.scss +46 -4
- package/src/styles/utils/dark/ion-button.scss +13 -0
- package/src/styles/utils/dark/ion-fab.scss +9 -0
- package/src/styles/utils/dark/ion-list.scss +7 -0
- package/src/styles/utils/dark/ion-segment.scss +8 -3
- package/src/styles/utils/dark/ion-tabs.scss +20 -0
- package/src/styles/utils/group-heading.scss +5 -0
- package/src/styles/utils/structured-list.scss +68 -15
- package/src/styles/utils/theme-dark.scss +23 -0
- package/src/transition/ios.transition.ts +0 -487
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
@use '../utils/structured-list';
|
|
2
2
|
|
|
3
3
|
ion-list.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
4
|
+
--ion-border-color: var(--ion-color-step-100, var(--ion-background-color-step-100, #e8e8e8));
|
|
5
|
+
|
|
4
6
|
@include structured-list.support-text;
|
|
5
7
|
ion-item {
|
|
6
8
|
--background-hover-opacity: 0;
|
|
@@ -9,7 +11,7 @@ ion-list.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
ion-list.list-inset.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
12
|
-
@include structured-list.layout(20px,
|
|
14
|
+
@include structured-list.layout(20px, 28px);
|
|
13
15
|
|
|
14
16
|
ion-radio-group,
|
|
15
17
|
ion-reorder-group {
|
|
@@ -31,6 +33,13 @@ ion-list.list-inset.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
--min-height: 52px;
|
|
36
|
+
font-size: 1rem;
|
|
37
|
+
line-height: 1.29rem;
|
|
38
|
+
|
|
39
|
+
> ion-label:not([slot]) {
|
|
40
|
+
font-size: inherit;
|
|
41
|
+
line-height: inherit;
|
|
42
|
+
}
|
|
34
43
|
|
|
35
44
|
& > ion-input[labelplacement='floating'] {
|
|
36
45
|
transition: transform 200ms ease;
|
|
@@ -42,3 +51,7 @@ ion-list.list-inset.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
|
42
51
|
}
|
|
43
52
|
}
|
|
44
53
|
}
|
|
54
|
+
|
|
55
|
+
ion-list.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
56
|
+
@include structured-list.colors(0.75, 0.38);
|
|
57
|
+
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
@use '../utils/api';
|
|
2
|
-
|
|
3
1
|
ion-split-pane.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
4
2
|
--side-max-width: var(--ios-theme-menu-width, var(--ios26-menu-width));
|
|
5
3
|
}
|
|
@@ -82,7 +80,8 @@ ion-split-pane.ios:not(.ios-theme-disabled, .ios26-disabled).split-pane-visible:
|
|
|
82
80
|
|
|
83
81
|
ion-menu.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
84
82
|
--border: none;
|
|
85
|
-
|
|
83
|
+
// Keep the surface nearly opaque while page transitions remain visible behind it.
|
|
84
|
+
--background: rgba(var(--ios-theme-menu-background-rgb), var(--ios-theme-menu-background-opacity, 0.96));
|
|
86
85
|
--max-width: var(--ios-theme-menu-width, var(--ios26-menu-width));
|
|
87
86
|
position: absolute;
|
|
88
87
|
top: 0;
|
|
@@ -99,17 +98,30 @@ ion-menu.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
|
99
98
|
display: none;
|
|
100
99
|
}
|
|
101
100
|
|
|
101
|
+
&::part(container) {
|
|
102
|
+
border-radius: 0;
|
|
103
|
+
box-shadow: none;
|
|
104
|
+
-webkit-backdrop-filter: blur(3px);
|
|
105
|
+
backdrop-filter: blur(3px);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
ion-list:not(.ios-theme-disabled, .ios26-disabled, .ion-color) {
|
|
109
|
+
background: transparent;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
ion-item:not(.ios-theme-disabled, .ios26-disabled, .ion-color) {
|
|
113
|
+
--background: transparent;
|
|
114
|
+
}
|
|
115
|
+
|
|
102
116
|
ion-content {
|
|
103
117
|
--background: transparent;
|
|
104
118
|
--ios26-content-box-shadow-rgb: transparent;
|
|
105
119
|
--ios-theme-content-box-shadow-rgb: var(--ios26-content-box-shadow-rgb);
|
|
106
120
|
|
|
107
121
|
&::part(scroll) {
|
|
108
|
-
@include api.glass-background;
|
|
109
122
|
margin: calc(var(--ios-theme-floating-safe-area-top, var(--ios26-floating-safe-area-top)) + 6px)
|
|
110
|
-
calc(16px + var(--ion-safe-area-right)) var(--ios-theme-floating-safe-area-bottom, var(--ios26-floating-safe-area-bottom))
|
|
111
|
-
calc(12px + var(--ion-safe-area-left));
|
|
112
|
-
border-radius: 24px;
|
|
123
|
+
calc(16px + var(--ion-safe-area-right, 0px)) var(--ios-theme-floating-safe-area-bottom, var(--ios26-floating-safe-area-bottom))
|
|
124
|
+
calc(12px + var(--ion-safe-area-left, 0px));
|
|
113
125
|
}
|
|
114
126
|
}
|
|
115
127
|
}
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
@use '../utils/api';
|
|
2
2
|
|
|
3
|
+
@mixin sheet-glass {
|
|
4
|
+
&::part(content) {
|
|
5
|
+
@include api.glass-background($opacity: 1, $include-background: false);
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
3
10
|
ion-modal.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
4
11
|
--backdrop-opacity: 0.2;
|
|
5
12
|
|
|
6
13
|
&::part(handle) {
|
|
7
|
-
|
|
14
|
+
top: 6px;
|
|
15
|
+
width: 60px;
|
|
16
|
+
height: 4px;
|
|
17
|
+
border-radius: 2px;
|
|
18
|
+
background: var(--ion-background-color-step-250, var(--ion-color-step-250, #c8c7cc));
|
|
8
19
|
}
|
|
9
20
|
|
|
10
21
|
ion-toolbar {
|
|
@@ -12,19 +23,33 @@ ion-modal.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
|
12
23
|
padding-left: var(--ion-safe-area-left);
|
|
13
24
|
}
|
|
14
25
|
|
|
26
|
+
&.modal-card,
|
|
15
27
|
&.modal-sheet {
|
|
16
|
-
|
|
17
|
-
padding-right: calc(var(--ion-safe-area-right) + 4px);
|
|
18
|
-
padding-left: calc(var(--ion-safe-area-left) + 4px);
|
|
19
|
-
}
|
|
28
|
+
--border-radius: 32px;
|
|
20
29
|
}
|
|
21
30
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
// Match the iPad form and page presentations without changing phone fullscreen modals.
|
|
32
|
+
@media (min-width: 768px) and (min-height: 600px) {
|
|
33
|
+
--border-radius: 32px;
|
|
34
|
+
--width: 580px;
|
|
35
|
+
--height: min(660px, calc(100% - 64px));
|
|
36
|
+
--box-shadow: 0 24px 64px color-mix(in srgb, var(--ion-box-shadow-color, #000) 18%, transparent);
|
|
37
|
+
|
|
38
|
+
&:not(.modal-card, .modal-sheet)::part(content) {
|
|
39
|
+
// Keep translucent headers from sampling the shadow outside the rounded surface.
|
|
40
|
+
clip-path: inset(0 round var(--border-radius));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
&.modal-card {
|
|
44
|
+
--width: min(936px, calc(100% - 40px));
|
|
45
|
+
--max-width: 936px;
|
|
46
|
+
--height: calc(100% - max(32px, var(--ion-safe-area-top, 0px)) * 2);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&.modal-sheet {
|
|
50
|
+
--width: min(936px, calc(100vw - 40px));
|
|
51
|
+
--height: calc(100% - max(32px, var(--ion-modal-offset-top, 0px)));
|
|
52
|
+
}
|
|
28
53
|
}
|
|
29
54
|
|
|
30
55
|
&:has(.ion-delegate-host):has(ion-datetime) {
|
|
@@ -33,10 +58,34 @@ ion-modal.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
|
33
58
|
}
|
|
34
59
|
|
|
35
60
|
&.modal-sheet {
|
|
36
|
-
--border-radius: 30px;
|
|
37
61
|
--background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 1);
|
|
38
|
-
|
|
39
|
-
@include
|
|
62
|
+
@media (max-width: 767px), (max-height: 599px) {
|
|
63
|
+
@include sheet-glass;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@media (min-width: 768px) and (min-height: 600px) {
|
|
68
|
+
&.modal-sheet:not(.modal-no-expand-scroll) {
|
|
69
|
+
@include sheet-glass;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Ionic sizes the page at each breakpoint when expandToScroll is false.
|
|
73
|
+
&.modal-sheet.modal-no-expand-scroll {
|
|
74
|
+
--background: transparent;
|
|
75
|
+
--box-shadow: none;
|
|
76
|
+
--border-width: 0;
|
|
77
|
+
--overflow: visible;
|
|
78
|
+
|
|
79
|
+
&::part(content) {
|
|
80
|
+
bottom: 20px;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
> .ion-page {
|
|
84
|
+
border-radius: var(--border-radius);
|
|
85
|
+
overflow: hidden;
|
|
86
|
+
background: var(--ion-background-color, #fff);
|
|
87
|
+
box-shadow: 0 24px 64px color-mix(in srgb, var(--ion-box-shadow-color, #000) 18%, transparent);
|
|
88
|
+
}
|
|
40
89
|
}
|
|
41
90
|
}
|
|
42
91
|
}
|
|
@@ -1,22 +1,65 @@
|
|
|
1
1
|
@use '../utils/api';
|
|
2
2
|
|
|
3
3
|
ion-popover.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
4
|
-
|
|
5
|
-
--background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0.
|
|
4
|
+
@include api.glass-overlay-variables;
|
|
5
|
+
--background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0.42);
|
|
6
|
+
--backdrop-opacity: 0;
|
|
6
7
|
--box-shadow:
|
|
7
|
-
inset 0 0
|
|
8
|
-
0
|
|
8
|
+
inset 0 0.5px 1px rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.6),
|
|
9
|
+
0 4px 16px color-mix(in srgb, var(--ion-box-shadow-color, #000) 12%, transparent);
|
|
10
|
+
|
|
9
11
|
&::part(arrow) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
width: 34px;
|
|
13
|
+
height: 14px;
|
|
14
|
+
|
|
15
|
+
&::after {
|
|
16
|
+
width: 100%;
|
|
17
|
+
height: 100%;
|
|
18
|
+
top: 0;
|
|
19
|
+
inset-inline-start: 0;
|
|
20
|
+
border-radius: 0;
|
|
21
|
+
transform: none;
|
|
22
|
+
// Rounded tip and concave shoulders join the popover's straight edge.
|
|
23
|
+
clip-path: path('M 0 14 L 0 13 C 3 13 4.5 12 6.5 10 L 14.5 1.5 C 16 -0.5 18 -0.5 19.5 1.5 L 27.5 10 C 29.5 12 31 13 34 13 L 34 14 Z');
|
|
24
|
+
backdrop-filter: blur(12px) saturate(115%) brightness(1.35);
|
|
25
|
+
-webkit-backdrop-filter: blur(12px) saturate(115%) brightness(1.35);
|
|
13
26
|
}
|
|
14
27
|
}
|
|
28
|
+
|
|
15
29
|
&::part(content) {
|
|
16
|
-
@include api.glass-
|
|
17
|
-
|
|
30
|
+
@include api.glass-overlay-surface;
|
|
31
|
+
backdrop-filter: blur(12px) saturate(115%) brightness(1.35);
|
|
32
|
+
-webkit-backdrop-filter: blur(12px) saturate(115%) brightness(1.35);
|
|
33
|
+
border-radius: 34px;
|
|
18
34
|
padding: 0;
|
|
19
35
|
}
|
|
36
|
+
|
|
37
|
+
&.ios-theme-callout::part(content) {
|
|
38
|
+
background: transparent;
|
|
39
|
+
border-color: transparent;
|
|
40
|
+
box-shadow: none;
|
|
41
|
+
backdrop-filter: none;
|
|
42
|
+
-webkit-backdrop-filter: none;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
&.ios-theme-callout::part(arrow)::after {
|
|
46
|
+
display: none;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&::part(callout-glass) {
|
|
50
|
+
background: var(--background);
|
|
51
|
+
backdrop-filter: blur(12px) saturate(115%) brightness(1.35);
|
|
52
|
+
-webkit-backdrop-filter: blur(12px) saturate(115%) brightness(1.35);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
&::part(callout-border) {
|
|
56
|
+
background: color-mix(in srgb, var(--border-color) 60%, transparent);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
&::part(callout-shadow) {
|
|
60
|
+
background: color-mix(in srgb, var(--ion-box-shadow-color, #000) 8%, transparent);
|
|
61
|
+
}
|
|
62
|
+
|
|
20
63
|
ion-select-popover {
|
|
21
64
|
ion-list {
|
|
22
65
|
background: transparent;
|
|
@@ -1,14 +1,29 @@
|
|
|
1
|
-
@
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
@mixin pressed-knob($offset: 0px) {
|
|
2
|
+
// iPadOS 27: 38 × 24 at rest, approximately 58 × 38 while tracking.
|
|
3
|
+
transform: translateX($offset) scale(1.53, 1.58);
|
|
4
|
+
background: linear-gradient(
|
|
5
|
+
180deg,
|
|
6
|
+
rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.04),
|
|
7
|
+
rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.08) 35%,
|
|
8
|
+
rgba(255, 255, 255, 0.12) 65%,
|
|
9
|
+
rgba(255, 255, 255, 0.24)
|
|
10
|
+
);
|
|
11
|
+
box-shadow:
|
|
12
|
+
inset 0 0 0 0.65px rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.28),
|
|
13
|
+
inset 0 1px 1px rgba(255, 255, 255, 0.8),
|
|
14
|
+
0 4px 6px rgba(0, 0, 0, 0.14);
|
|
6
15
|
}
|
|
7
16
|
|
|
8
17
|
ion-range.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
9
|
-
--knob-size:
|
|
18
|
+
--knob-size: 24px;
|
|
10
19
|
--knob-width: 38px;
|
|
11
20
|
--knob-border-radius: 24px;
|
|
21
|
+
--bar-height: 6px;
|
|
22
|
+
--bar-border-radius: 3px;
|
|
23
|
+
|
|
24
|
+
&.ion-color {
|
|
25
|
+
--bar-background-active: var(--ion-color-base);
|
|
26
|
+
}
|
|
12
27
|
|
|
13
28
|
&.range-label-placement-start::part(label) {
|
|
14
29
|
margin-inline: 0 24px;
|
|
@@ -27,64 +42,48 @@ ion-range.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
|
27
42
|
}
|
|
28
43
|
|
|
29
44
|
&::part(knob) {
|
|
45
|
+
overflow: hidden;
|
|
30
46
|
width: var(--knob-width);
|
|
31
|
-
margin-inline-start: -
|
|
47
|
+
margin-inline-start: calc((var(--knob-size) - var(--knob-width)) / 2);
|
|
32
48
|
transition:
|
|
33
|
-
transform
|
|
34
|
-
margin 300ms ease,
|
|
49
|
+
transform 200ms ease,
|
|
35
50
|
box-shadow 200ms ease;
|
|
36
51
|
}
|
|
37
52
|
|
|
38
|
-
&:not(.range-dual-knobs).range-pressed {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
&::part(knob) {
|
|
43
|
-
@include api.glass-background(0.1, 0, 120%, $include-background: false, $include-box-shadow: false, $include-border: false);
|
|
44
|
-
@include scaled-transform(0px);
|
|
45
|
-
}
|
|
53
|
+
&:not(.range-dual-knobs).range-pressed::part(knob) {
|
|
54
|
+
@include pressed-knob;
|
|
55
|
+
}
|
|
46
56
|
|
|
47
|
-
|
|
48
|
-
|
|
57
|
+
// Ionic does not expose each dual thumb's endpoint state through parts.
|
|
58
|
+
// Keep its width fixed so either thumb can be pressed at coincident endpoints.
|
|
59
|
+
&.range-dual-knobs.range-pressed-a::part(knob-a),
|
|
60
|
+
&.range-dual-knobs.range-pressed-b::part(knob-b) {
|
|
61
|
+
@include pressed-knob;
|
|
62
|
+
transform: scaleY(1.58);
|
|
63
|
+
}
|
|
49
64
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
&.range-value-max {
|
|
55
|
-
--knob-box-shadow:
|
|
56
|
-
0 0.5px 4px rgba(0, 0, 0, 0.12), 0 6px 4px rgba(0, 0, 0, 0.05), inset 0.4px 0.4px 1px 0.2px var(--bar-background-active);
|
|
65
|
+
// Keep the enlarged thumb inside the same outer edge at either endpoint.
|
|
66
|
+
&:not(.range-dual-knobs).range-pressed.range-value-min::part(knob) {
|
|
67
|
+
@include pressed-knob(calc(var(--knob-width) * 0.53 / 2));
|
|
68
|
+
}
|
|
57
69
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
}
|
|
70
|
+
&:not(.range-dual-knobs).range-pressed.range-value-max::part(knob) {
|
|
71
|
+
@include pressed-knob(calc(var(--knob-width) * -0.53 / 2));
|
|
62
72
|
}
|
|
63
73
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
@include api.glass-background(0.1, 0, 120%, $include-border: false);
|
|
68
|
-
@include scaled-transform(0px);
|
|
69
|
-
box-shadow:
|
|
70
|
-
0 0.5px 4px rgba(0, 0, 0, 0.12),
|
|
71
|
-
0 6px 4px rgba(0, 0, 0, 0.05),
|
|
72
|
-
inset 0.4px 0.4px 1px 0 var(--bar-background-active);
|
|
74
|
+
&:dir(rtl) {
|
|
75
|
+
&:not(.range-dual-knobs).range-pressed.range-value-min::part(knob) {
|
|
76
|
+
@include pressed-knob(calc(var(--knob-width) * -0.53 / 2));
|
|
73
77
|
}
|
|
74
78
|
|
|
75
|
-
|
|
76
|
-
@include
|
|
77
|
-
box-shadow:
|
|
78
|
-
0 0.5px 4px rgba(0, 0, 0, 0.12),
|
|
79
|
-
0 6px 4px rgba(0, 0, 0, 0.05);
|
|
79
|
+
&:not(.range-dual-knobs).range-pressed.range-value-max::part(knob) {
|
|
80
|
+
@include pressed-knob(calc(var(--knob-width) * 0.53 / 2));
|
|
80
81
|
}
|
|
82
|
+
}
|
|
81
83
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
0 0.5px 4px rgba(0, 0, 0, 0.12),
|
|
86
|
-
0 6px 4px rgba(0, 0, 0, 0.05),
|
|
87
|
-
inset 0.4px 0.4px 1px 0.2px var(--bar-background-active);
|
|
84
|
+
@media (prefers-reduced-motion: reduce) {
|
|
85
|
+
&::part(knob) {
|
|
86
|
+
transition: none;
|
|
88
87
|
}
|
|
89
88
|
}
|
|
90
89
|
}
|
|
@@ -14,18 +14,8 @@ ion-segment.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
|
14
14
|
|
|
15
15
|
// UIKit uses a larger control in navigation bars, but not in content.
|
|
16
16
|
&.in-toolbar:not(.segment-expand) {
|
|
17
|
-
@include api.glass-background($include-border: false);
|
|
18
17
|
--border-radius: 24px;
|
|
19
18
|
min-height: 48px;
|
|
20
|
-
// Draw the shared reflective rim without adding to the control's measured bounds.
|
|
21
|
-
&::before {
|
|
22
|
-
@include api.glass-background($include-background: false, $include-box-shadow: false, $blur: 0, $saturate: 100%);
|
|
23
|
-
content: '';
|
|
24
|
-
position: absolute;
|
|
25
|
-
inset: 0;
|
|
26
|
-
border-radius: inherit;
|
|
27
|
-
pointer-events: none;
|
|
28
|
-
}
|
|
29
19
|
// UIKit's container spring: grow on press, then briefly shrink below rest on release.
|
|
30
20
|
transition: transform 517ms
|
|
31
21
|
linear(
|
|
@@ -67,9 +57,9 @@ ion-segment.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
|
67
57
|
}
|
|
68
58
|
|
|
69
59
|
ion-segment-button {
|
|
70
|
-
min-height:
|
|
71
|
-
margin:
|
|
72
|
-
font-size:
|
|
60
|
+
min-height: 44px;
|
|
61
|
+
margin: 2px 0;
|
|
62
|
+
font-size: 0.94rem;
|
|
73
63
|
}
|
|
74
64
|
}
|
|
75
65
|
|
|
@@ -161,9 +151,14 @@ ion-segment-button.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
|
161
151
|
min-width: 65px;
|
|
162
152
|
min-height: 28px;
|
|
163
153
|
margin: 2px 0;
|
|
164
|
-
font-size:
|
|
154
|
+
font-size: 0.81rem;
|
|
155
|
+
font-weight: 500;
|
|
165
156
|
line-height: normal;
|
|
166
157
|
|
|
158
|
+
&.segment-button-disabled {
|
|
159
|
+
opacity: 0.2;
|
|
160
|
+
}
|
|
161
|
+
|
|
167
162
|
&::part(indicator-background) {
|
|
168
163
|
transition:
|
|
169
164
|
var(--indicator-transition),
|
|
@@ -180,8 +175,12 @@ ion-segment-button.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
|
180
175
|
}
|
|
181
176
|
|
|
182
177
|
// Public customization properties remain overridable by ordinary app selectors.
|
|
183
|
-
|
|
184
|
-
|
|
178
|
+
// The resting track is a flat system fill; only the moving lens has a glass rim.
|
|
179
|
+
:where(ion-segment.ios:not(.ios-theme-disabled, .ios26-disabled)) {
|
|
180
|
+
--background: rgba(var(--ion-color-medium-rgb, 99, 100, 105), 0.11);
|
|
181
|
+
}
|
|
182
|
+
:where(ion-segment.ios:not(.ios-theme-disabled, .ios26-disabled) ion-segment-button) {
|
|
183
|
+
--indicator-color: var(--ion-background-color, #fff);
|
|
185
184
|
}
|
|
186
185
|
:where(ion-segment.ios:not(.ios-theme-disabled, .ios26-disabled).ion-color ion-segment-button.in-segment-color) {
|
|
187
186
|
--indicator-color: var(--ion-color-base);
|
|
@@ -1,11 +1,30 @@
|
|
|
1
1
|
@use '../utils/api';
|
|
2
2
|
|
|
3
3
|
ion-tab-bar.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
4
|
-
|
|
4
|
+
// Ionic forces content-box on the host. Keep the Glass border in a
|
|
5
|
+
// separate layer so its physical-pixel rounding cannot resize the bar.
|
|
6
|
+
border: 0;
|
|
7
|
+
background: transparent;
|
|
8
|
+
contain: size layout style;
|
|
5
9
|
z-index: 2;
|
|
10
|
+
--background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0.53);
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
12
|
+
&::before {
|
|
13
|
+
@include api.glass-control-background($include-background: false);
|
|
14
|
+
background-color: var(--background);
|
|
15
|
+
backdrop-filter: blur(6px) saturate(180%) brightness(1.05);
|
|
16
|
+
content: '';
|
|
17
|
+
position: absolute;
|
|
18
|
+
inset: 0;
|
|
19
|
+
box-sizing: border-box;
|
|
20
|
+
border-radius: inherit;
|
|
21
|
+
pointer-events: none;
|
|
22
|
+
z-index: -1;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
border-radius: 31px;
|
|
26
|
+
--ios-theme-tab-overlap: 20px;
|
|
27
|
+
--color: var(--ion-text-color-step-50, #0d0d0d);
|
|
9
28
|
|
|
10
29
|
&[slot='top'] {
|
|
11
30
|
position: absolute;
|
|
@@ -42,17 +61,41 @@ ion-tab-bar.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
|
42
61
|
/**
|
|
43
62
|
* 100% - margin-left - margin-right - right-fab - margin-left-fab
|
|
44
63
|
*/
|
|
45
|
-
width: calc(100% - calc(18px + var(--ion-safe-area-left, 0px)) - calc(18px + var(--ion-safe-area-right, 0px)) -
|
|
46
|
-
max-width:
|
|
47
|
-
|
|
64
|
+
width: calc(100% - calc(18px + var(--ion-safe-area-left, 0px)) - calc(18px + var(--ion-safe-area-right, 0px)) - 75px);
|
|
65
|
+
max-width: 471px;
|
|
66
|
+
height: 54px;
|
|
67
|
+
min-height: 54px;
|
|
48
68
|
&:has(> ion-tab-button:nth-child(2):last-child) {
|
|
49
|
-
width:
|
|
69
|
+
width: 180px; // 188px including the 4px inset on each side.
|
|
50
70
|
}
|
|
51
71
|
&:has(:nth-child(5)) {
|
|
52
|
-
width: calc(100% - calc(18px + var(--ion-safe-area-left, 0px)) - calc(18px + var(--ion-safe-area-right, 0px)));
|
|
53
|
-
max-width:
|
|
72
|
+
width: calc(100% - calc(18px + var(--ion-safe-area-left, 0px)) - calc(18px + var(--ion-safe-area-right, 0px)) - 3px);
|
|
73
|
+
max-width: 543px;
|
|
74
|
+
}
|
|
75
|
+
padding: 4px;
|
|
76
|
+
|
|
77
|
+
> ion-tab-button:not(.ion-cloned-element) ~ ion-tab-button:not(.ion-cloned-element) {
|
|
78
|
+
margin-inline-start: calc(-1 * var(--ios-theme-tab-overlap));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
&:not(:has(> ion-tab-button:nth-child(4 of ion-tab-button:not(.ion-cloned-element)))) {
|
|
82
|
+
--ios-theme-tab-overlap: 8px;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// iPad's stacked UIKit tabs use a compact platter instead of filling the
|
|
86
|
+
// available width. Keep the phone sizing and constrain only roomy layouts.
|
|
87
|
+
@media (min-width: 768px) {
|
|
88
|
+
--ios-theme-tab-overlap: 16px;
|
|
89
|
+
@each $count, $width in (2: 188px, 3: 274px, 4: 336px, 5: 414px) {
|
|
90
|
+
&:has(
|
|
91
|
+
> ion-tab-button:nth-child(#{$count} of ion-tab-button:not(.ion-cloned-element)):nth-last-child(
|
|
92
|
+
1 of ion-tab-button:not(.ion-cloned-element)
|
|
93
|
+
)
|
|
94
|
+
) {
|
|
95
|
+
max-width: $width - 8px;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
54
98
|
}
|
|
55
|
-
padding: 2px 2px;
|
|
56
99
|
|
|
57
100
|
transition: transform var(--ios-theme-activated-transition-duration, var(--ios26-activated-transition-duration)) ease-out;
|
|
58
101
|
|
|
@@ -118,10 +161,28 @@ ion-tab-bar.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
|
118
161
|
|
|
119
162
|
ion-tab-button.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
120
163
|
transform-origin: center 65%;
|
|
164
|
+
font-size: 0.59rem;
|
|
165
|
+
border-radius: 27px;
|
|
121
166
|
|
|
122
167
|
ion-icon {
|
|
123
168
|
font-size: 26px;
|
|
124
169
|
}
|
|
170
|
+
&.tab-layout-icon-top.tab-has-icon.tab-has-label {
|
|
171
|
+
--padding-top: 7px;
|
|
172
|
+
--padding-bottom: 7px;
|
|
173
|
+
justify-content: flex-start;
|
|
174
|
+
|
|
175
|
+
ion-icon {
|
|
176
|
+
flex-shrink: 0;
|
|
177
|
+
margin-block: 0 2px;
|
|
178
|
+
}
|
|
179
|
+
ion-label {
|
|
180
|
+
margin: 0;
|
|
181
|
+
font-size: inherit;
|
|
182
|
+
line-height: 1.2;
|
|
183
|
+
min-height: 0;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
125
186
|
ion-label,
|
|
126
187
|
ion-icon {
|
|
127
188
|
transition:
|
|
@@ -129,12 +190,11 @@ ion-tab-button.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
|
129
190
|
color var(--ios-theme-activated-transition-duration, var(--ios26-activated-transition-duration)) ease;
|
|
130
191
|
}
|
|
131
192
|
background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0);
|
|
132
|
-
height:
|
|
193
|
+
height: 54px;
|
|
133
194
|
transition: transform var(--ios-theme-activated-transition-duration, var(--ios26-activated-transition-duration)) ease;
|
|
134
195
|
&::part(native) {
|
|
135
196
|
overflow: visible;
|
|
136
|
-
min-height:
|
|
137
|
-
border-radius: 32px;
|
|
197
|
+
min-height: 54px;
|
|
138
198
|
}
|
|
139
199
|
|
|
140
200
|
&.ion-activated {
|
|
@@ -1,36 +1,27 @@
|
|
|
1
1
|
@use '../utils/api';
|
|
2
2
|
|
|
3
3
|
ion-toast.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
4
|
-
|
|
5
|
-
--border-radius:
|
|
6
|
-
--
|
|
7
|
-
--border-width: 0.5px;
|
|
8
|
-
--box-shadow:
|
|
9
|
-
inset 0 0 8px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.2),
|
|
10
|
-
0 0 10px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.82);
|
|
4
|
+
@include api.glass-overlay-variables($shadow-opacity: 0.06);
|
|
5
|
+
--border-radius: 28px;
|
|
6
|
+
--max-width: 560px;
|
|
11
7
|
--start: 16px;
|
|
12
8
|
--end: 16px;
|
|
9
|
+
font-size: 0.94rem;
|
|
13
10
|
|
|
14
11
|
&::part(wrapper) {
|
|
15
|
-
@include api.glass-
|
|
16
|
-
border-top-color: rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 1);
|
|
17
|
-
border-right-color: rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.8);
|
|
18
|
-
border-bottom-color: rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 1);
|
|
19
|
-
border-left-color: rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.6);
|
|
12
|
+
@include api.glass-overlay-surface($include-background: false, $include-frame: false);
|
|
20
13
|
}
|
|
21
14
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
border-left-color: rgba(var(--ion-color-base-rgb), 0.6);
|
|
34
|
-
}
|
|
15
|
+
&::part(header) {
|
|
16
|
+
font-size: 0.94rem;
|
|
17
|
+
font-weight: 600;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&::part(message) {
|
|
21
|
+
line-height: 1.33;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&.ion-color::part(wrapper) {
|
|
25
|
+
background: rgba(var(--ion-color-base-rgb), 0.87);
|
|
35
26
|
}
|
|
36
27
|
}
|
|
@@ -13,7 +13,23 @@ 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
|
-
padding-top:
|
|
16
|
+
padding-top: 0;
|
|
17
|
+
padding-bottom: 0;
|
|
18
|
+
--min-height: 64px;
|
|
19
|
+
--padding-start: 3px;
|
|
20
|
+
--padding-end: 3px;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@media (min-width: 768px) and (min-height: 600px) {
|
|
25
|
+
ion-modal.ios:not(.ios-theme-disabled, .ios26-disabled) {
|
|
26
|
+
ion-header.ios:not(.ios-theme-disabled, .ios26-disabled) ion-toolbar.ios:not(.ios-theme-disabled, .ios26-disabled):first-of-type {
|
|
27
|
+
padding-top: 0;
|
|
28
|
+
padding-bottom: 0;
|
|
29
|
+
--min-height: 64px;
|
|
30
|
+
--padding-start: 3px;
|
|
31
|
+
--padding-end: 3px;
|
|
32
|
+
}
|
|
17
33
|
}
|
|
18
34
|
}
|
|
19
35
|
|