@rdlabo/ionic-theme-ios27 0.2.1-beta.pr185.sha0793981f6cf4 → 1.0.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 +64 -124
- package/docs/migration.md +105 -3
- package/package.json +1 -1
- package/docs/ios-adaptive.md +0 -89
package/README.md
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
# Ionic Theme iOS27
|
|
2
2
|
|
|
3
|
-
A theme for Ionic apps that brings iOS 27 Liquid Glass and motion to the Web
|
|
3
|
+
A theme for Ionic apps that brings iOS 27 Liquid Glass and motion to the Web. Capacitor iOS apps can also opt into an experimental Native UI Shell for supported controls.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
> This `main` branch contains the iOS 27 theme under the package name `@rdlabo/ionic-theme-ios27`. For the iOS 26 theme (`@rdlabo/ionic-theme-ios26`), see the [`ios26` branch](https://github.com/rdlabo-dev/ionic-theme-ios27/tree/ios26).
|
|
7
|
-
|
|
8
|
-
> All versions before 1.0.0 are release candidates (RC). APIs, CSS variables, classes, styling, and behavior may change without backward compatibility, including in minor and patch releases. A stable compatibility commitment starts with 1.0.0.
|
|
5
|
+
**[Ionic 9 demo](https://ionic-theme-ios27.rdlabo.dev/) · [Ionic 8 demo](https://ionic8-theme-ios27.rdlabo.dev/) · [Documentation](https://docs.rdlabo.dev/projects/ionic-theme-ios27)**
|
|
9
6
|
|
|
10
7
|
<!-- rdlabo-docs-pick -->
|
|
11
8
|
|
|
@@ -33,84 +30,63 @@ On Capacitor iOS, the optional, experimental [Native UI Shell](https://docs.rdla
|
|
|
33
30
|
|
|
34
31
|
### Follow the user's device
|
|
35
32
|
|
|
36
|
-
Pair the iOS 26 and iOS 27 themes so supported Safari versions can present the design of each generation: the iOS 26 look for iOS 26 users and the iOS 27 look for iOS 27 users. The [
|
|
37
|
-
|
|
38
|
-
## Installation
|
|
33
|
+
Pair the iOS 26 and iOS 27 themes so supported Safari versions can present the design of each generation: the iOS 26 look for iOS 26 users and the iOS 27 look for iOS 27 users. The [default setup](#get-started) uses browser feature checks to select the corresponding **styles**; it does not read the iOS version. When both packages are installed, keep the **page transition** on the iOS 27 animation. On even earlier iOS versions, Ionic's default iOS appearance remains when Safari supports neither feature. In a Capacitor iOS app, Native UI Shell's UIKit material follows the installed iOS version.
|
|
39
34
|
|
|
40
|
-
|
|
35
|
+
## Get started
|
|
41
36
|
|
|
42
|
-
|
|
37
|
+
Install both themes in an existing Ionic 8 or 9 app (`@ionic/core` 8.8.1 or later):
|
|
43
38
|
|
|
44
39
|
```bash
|
|
45
|
-
npm install @rdlabo/ionic-theme-ios27
|
|
40
|
+
npm install @rdlabo/ionic-theme-ios26 @rdlabo/ionic-theme-ios27
|
|
46
41
|
```
|
|
47
42
|
|
|
48
|
-
|
|
43
|
+
In your global Sass stylesheet (for example, `src/styles.scss`), load the styles by browser capability:
|
|
49
44
|
|
|
50
|
-
```
|
|
51
|
-
@
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
*/
|
|
67
|
-
|
|
68
|
-
/*
|
|
69
|
-
* Support Dark Mode
|
|
70
|
-
* We support Ionic Dark Mode. More information is here: https://ionicframework.com/docs/theming/dark-mode
|
|
71
|
-
* use Always: @import '@rdlabo/ionic-theme-ios27/dist/css/ionic-theme-ios27-dark-always.css'
|
|
72
|
-
* use System: @import '@rdlabo/ionic-theme-ios27/dist/css/ionic-theme-ios27-dark-system.css'
|
|
73
|
-
* use CSS Class: @import '@rdlabo/ionic-theme-ios27/dist/css/ionic-theme-ios27-dark-class.css'
|
|
74
|
-
*/
|
|
45
|
+
```scss
|
|
46
|
+
@use 'sass:meta';
|
|
47
|
+
|
|
48
|
+
@supports (overflow-anchor: auto) {
|
|
49
|
+
@include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/default-variables');
|
|
50
|
+
@include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/ionic-theme-ios27');
|
|
51
|
+
@include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/ionic-theme-ios27-dark-class');
|
|
52
|
+
@include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/md-remove-ios-class-effect');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@supports (text-wrap: pretty) and (not (overflow-anchor: auto)) {
|
|
56
|
+
@include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/default-variables');
|
|
57
|
+
@include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/ionic-theme-ios26');
|
|
58
|
+
@include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/ionic-theme-ios26-dark-class');
|
|
59
|
+
@include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/md-remove-ios-class-effect');
|
|
60
|
+
}
|
|
75
61
|
```
|
|
76
62
|
|
|
63
|
+
These checks select styles by browser features, not by iOS version. Browsers without either feature retain Ionic's default iOS appearance. The example uses class-based dark mode: also load [Ionic's matching dark palette](https://ionicframework.com/docs/theming/dark-mode). For system or always-dark mode, replace both `-dark-class` imports with the matching variant. The `md-remove-ios-class-effect` styles prevent iOS-specific classes from affecting Material Design mode.
|
|
64
|
+
|
|
77
65
|
### Configure animations
|
|
78
66
|
|
|
79
|
-
|
|
67
|
+
Keep the iOS 27 page transition and popover animations for both styled generations. Resolve these options before Ionic initializes. For Angular:
|
|
80
68
|
|
|
81
69
|
```ts
|
|
82
|
-
import { isPlatform } from '@ionic/
|
|
70
|
+
import { isPlatform, provideIonicAngular } from '@ionic/angular/standalone'; // Ionic 8
|
|
83
71
|
import { iosTransitionAnimation, popoverEnterAnimation, popoverLeaveAnimation } from '@rdlabo/ionic-theme-ios27';
|
|
84
72
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
popoverEnter: isPlatform('ios') ? popoverEnterAnimation: undefined,
|
|
98
|
-
popoverLeave: isPlatform('ios') ? popoverLeaveAnimation: undefined,
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
// Vue
|
|
102
|
-
createApp(App)
|
|
103
|
-
.use(IonicVue, {
|
|
104
|
-
...
|
|
105
|
-
navAnimation: isPlatform('ios') ? iosTransitionAnimation: undefined,
|
|
106
|
-
popoverEnter: isPlatform('ios') ? popoverEnterAnimation: undefined,
|
|
107
|
-
popoverLeave: isPlatform('ios') ? popoverLeaveAnimation: undefined,
|
|
108
|
-
})
|
|
73
|
+
function loadIOSAnimations() {
|
|
74
|
+
if (typeof CSS === 'undefined') return {};
|
|
75
|
+
if (!CSS.supports('overflow-anchor: auto') && !CSS.supports('text-wrap: pretty')) return {};
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
navAnimation: iosTransitionAnimation,
|
|
79
|
+
popoverEnter: popoverEnterAnimation,
|
|
80
|
+
popoverLeave: popoverLeaveAnimation,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
provideIonicAngular(isPlatform('ios') ? loadIOSAnimations() : {});
|
|
109
85
|
```
|
|
110
86
|
|
|
111
|
-
|
|
87
|
+
For Ionic 9 Angular, import `isPlatform` and `provideIonicAngular` from `@ionic/angular`. React and Vue can pass the same options to `setupIonicReact` or `IonicVue` during initialization. In server-rendered apps, run the selection during browser initialization.
|
|
112
88
|
|
|
113
|
-
The page-transition radius defaults to `0`. Native apps can update it after measuring the
|
|
89
|
+
The page-transition radius defaults to `0`. Native apps can update it after measuring the WebView:
|
|
114
90
|
|
|
115
91
|
```ts
|
|
116
92
|
import { setConfig } from '@rdlabo/ionic-theme-ios27';
|
|
@@ -133,17 +109,29 @@ Use this markup to preview the inset grouped list look. For the list structure t
|
|
|
133
109
|
</ion-list>
|
|
134
110
|
```
|
|
135
111
|
|
|
136
|
-
|
|
112
|
+
## Optional setups
|
|
137
113
|
|
|
138
|
-
|
|
114
|
+
### Use only the iOS 27 theme
|
|
139
115
|
|
|
140
|
-
|
|
116
|
+
Install only `@rdlabo/ionic-theme-ios27` and import its styles unconditionally in your global stylesheet:
|
|
141
117
|
|
|
142
|
-
```
|
|
143
|
-
|
|
118
|
+
```css
|
|
119
|
+
@import '@rdlabo/ionic-theme-ios27/dist/css/default-variables.css';
|
|
120
|
+
@import '@rdlabo/ionic-theme-ios27/dist/css/ionic-theme-ios27.css';
|
|
121
|
+
@import '@rdlabo/ionic-theme-ios27/dist/css/md-remove-ios-class-effect.css';
|
|
122
|
+
@import '@rdlabo/ionic-theme-ios27/dist/css/ionic-theme-ios27-dark-class.css';
|
|
144
123
|
```
|
|
145
124
|
|
|
146
|
-
|
|
125
|
+
The last import uses class-based dark mode; choose the `-dark-system` or `-dark-always` variant and matching Ionic palette for another mode. Configure the iOS 27 animations with `isPlatform('ios')` as above, without the browser feature checks.
|
|
126
|
+
|
|
127
|
+
### Other options
|
|
128
|
+
|
|
129
|
+
- **Native controls:** Follow the [Native UI Shell setup guide](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/native-ui-shell). Stylesheet imports alone do not enable it.
|
|
130
|
+
- **Inset lists on Android:** Load the matching package's `md-ion-list-inset` stylesheet inside each `@supports` branch if needed. It is already included in `@rdlabo/ionic-theme-md3`.
|
|
131
|
+
|
|
132
|
+
### Use with the MD3 theme
|
|
133
|
+
|
|
134
|
+
For the iOS 27-only setup above, install `@rdlabo/ionic-theme-md3` to style both Ionic modes. Both themes require `@ionic/core` 8.8.1 or later. In a global Sass stylesheet, load the iOS 27 styles before MD3:
|
|
147
135
|
|
|
148
136
|
```scss
|
|
149
137
|
@use '@rdlabo/ionic-theme-ios27/src/styles/default-variables.scss' as ios27-vars;
|
|
@@ -154,58 +142,24 @@ When your global stylesheet uses Sass, initialize the themes in this order:
|
|
|
154
142
|
@use '@rdlabo/ionic-theme-md3/dist/css/ionic-theme-md3.css';
|
|
155
143
|
```
|
|
156
144
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
Configure both transition implementations when both themes are installed:
|
|
160
|
-
|
|
161
|
-
```ts
|
|
162
|
-
import { isPlatform } from '@ionic/core'; // or @ionic/angular (Ionic 9), @ionic/angular/standalone (Ionic 8), @ionic/react, @ionic/vue
|
|
163
|
-
import { iosTransitionAnimation, popoverEnterAnimation, popoverLeaveAnimation } from '@rdlabo/ionic-theme-ios27';
|
|
164
|
-
import { mdTransitionAnimation } from '@rdlabo/ionic-theme-md3';
|
|
165
|
-
|
|
166
|
-
// Angular
|
|
167
|
-
provideIonicAngular({
|
|
168
|
-
...
|
|
169
|
-
navAnimation: isPlatform('ios') ? iosTransitionAnimation : mdTransitionAnimation,
|
|
170
|
-
popoverEnter: isPlatform('ios') ? popoverEnterAnimation : undefined,
|
|
171
|
-
popoverLeave: isPlatform('ios') ? popoverLeaveAnimation : undefined,
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
// React
|
|
175
|
-
setupIonicReact({
|
|
176
|
-
...
|
|
177
|
-
navAnimation: isPlatform('ios') ? iosTransitionAnimation : mdTransitionAnimation,
|
|
178
|
-
popoverEnter: isPlatform('ios') ? popoverEnterAnimation : undefined,
|
|
179
|
-
popoverLeave: isPlatform('ios') ? popoverLeaveAnimation : undefined,
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
// Vue
|
|
183
|
-
createApp(App)
|
|
184
|
-
.use(IonicVue, {
|
|
185
|
-
...
|
|
186
|
-
navAnimation: isPlatform('ios') ? iosTransitionAnimation : mdTransitionAnimation,
|
|
187
|
-
popoverEnter: isPlatform('ios') ? popoverEnterAnimation : undefined,
|
|
188
|
-
popoverLeave: isPlatform('ios') ? popoverLeaveAnimation : undefined,
|
|
189
|
-
});
|
|
190
|
-
```
|
|
145
|
+
Load Ionic's matching dark palette too. To use MD3's page transition in Material Design mode, set `navAnimation` to `isPlatform('ios') ? iosTransitionAnimation : mdTransitionAnimation`, importing the latter from `@rdlabo/ionic-theme-md3`.
|
|
191
146
|
|
|
192
147
|
## Documentation
|
|
193
148
|
|
|
194
149
|
**Full documentation:** [Ionic Theme iOS27](https://docs.rdlabo.dev/projects/ionic-theme-ios27)
|
|
195
150
|
|
|
196
|
-
- [Adaptive iOS themes](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/ios-adaptive) — select iOS 26 or iOS 27 styles by browser capabilities; keep the iOS 27 page transition when both packages are installed.
|
|
197
151
|
- [Using ion-item-group](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/using-ion-item-group) — required markup for inset lists.
|
|
198
152
|
- [Special markup and classes](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/special-markup) — opt-in markup and utility classes used by the theme.
|
|
199
153
|
- [ESLint](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/eslint) — check list structure with ESLint rules.
|
|
200
154
|
- [Features](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/features) — CSS variables, Liquid Glass, selective imports, and dark mode.
|
|
201
155
|
- [Native UI Shell (Experimental)](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/native-ui-shell) — project supported Ionic controls, text, and icons into UIKit.
|
|
202
156
|
- [Animation](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/experimental-animation) — tab, segment, and searchable effects.
|
|
203
|
-
- [Migration](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/migration) — stylesheet, class, and CSS variable
|
|
157
|
+
- [Migration from iOS 26](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/migration) — upgrade an existing app, including stylesheet, class, and CSS variable changes.
|
|
204
158
|
- [iOS 26 migration history](https://docs.rdlabo.dev/projects/ionic-theme-ios26/docs/migration) — earlier major-version changes for the previous package.
|
|
205
159
|
|
|
206
160
|
<!-- rdlabo-docs-omit -->
|
|
207
161
|
|
|
208
|
-
**iOS 26
|
|
162
|
+
**iOS 26 theme:** See the [`ios26` branch](https://github.com/rdlabo-dev/ionic-theme-ios27/tree/ios26) and [iOS 26 documentation](https://docs.rdlabo.dev/projects/ionic-theme-ios26).
|
|
209
163
|
|
|
210
164
|
## Development & Testing
|
|
211
165
|
|
|
@@ -246,23 +200,9 @@ npm run test:e2e:debug
|
|
|
246
200
|
npm run test:e2e:update
|
|
247
201
|
```
|
|
248
202
|
|
|
249
|
-
###
|
|
250
|
-
|
|
251
|
-
An open, non-draft pull request can be published to the npm `beta` dist-tag after its `Lint`, `E2E Screenshot Tests Pull Request`, and `Package Candidate` workflows pass. A repository owner or maintainer must add a comment whose entire body is:
|
|
252
|
-
|
|
253
|
-
```text
|
|
254
|
-
/beta
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
The request authorizes only the pull request head SHA and base branch that existed when the comment was added. The workflow revalidates the owner or maintainer permission, head SHA, and base branch immediately before publishing. Any new commit or retargeting invalidates the request; the new state must pass CI and receive a fresh owner or maintainer `/beta` comment. Fork pull requests are supported. Pull requests that change a release-gating workflow cannot be beta-published until those workflow changes land on their target branch.
|
|
258
|
-
|
|
259
|
-
Beta versions use `<base>-beta.pr<PR number>.sha<12-character SHA>`. The pull request receives a comment containing the immutable version and exact `npm install` command.
|
|
260
|
-
|
|
261
|
-
When a pull request is merged into `main` or `ios26`, it is automatically published to the npm `beta` dist-tag only after `Lint`, `E2E Screenshot Tests`, and `Package Candidate` all succeed for that exact merge commit. Direct pushes do not publish a candidate. Merge candidates use `<base>-beta.pr<PR number>.sha<12-character SHA>` and the merged pull request receives the exact install command.
|
|
262
|
-
|
|
263
|
-
Candidate code is built in a read-only workflow without npm publishing credentials. The privileged release workflow never checks out or executes pull request code; it revalidates the source workflow and package identity, then publishes only the immutable packed artifact with lifecycle scripts disabled. The install-command comment is a separate best-effort notification and cannot invalidate a successful npm publish.
|
|
203
|
+
### Releases
|
|
264
204
|
|
|
265
|
-
|
|
205
|
+
Stable `ios27-vX.Y.Z` tags publish to npm `latest` through the [release workflow](./.github/workflows/release.yml). Maintainers create release tags with `npm run release`. Pull request and merge candidates use the npm `beta` tag; prerelease tags use `next`.
|
|
266
206
|
|
|
267
207
|
<!-- /rdlabo-docs-omit -->
|
|
268
208
|
|
package/docs/migration.md
CHANGED
|
@@ -4,9 +4,111 @@ title: Migration
|
|
|
4
4
|
|
|
5
5
|
# Migration
|
|
6
6
|
|
|
7
|
+
## From the iOS 26 theme
|
|
8
|
+
|
|
9
|
+
For an app using `@rdlabo/ionic-theme-ios26`, the recommended migration keeps that package and adds `@rdlabo/ionic-theme-ios27`. The [README setup](https://docs.rdlabo.dev/projects/ionic-theme-ios27#get-started) selects iOS 27 or iOS 26 styles by browser capability and leaves Ionic's default iOS appearance on older browsers.
|
|
10
|
+
|
|
11
|
+
### 1. Add the new package
|
|
12
|
+
|
|
13
|
+
Keep the iOS 26 package and add iOS 27. The new theme requires `@ionic/core` 8.8.1 or later (Ionic 8 or 9).
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @rdlabo/ionic-theme-ios27
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### 2. Make the styles adaptive
|
|
20
|
+
|
|
21
|
+
Replace unconditional iOS 26 imports in your global Sass stylesheet with two mutually exclusive branches. This example uses class-based dark mode:
|
|
22
|
+
|
|
23
|
+
```diff
|
|
24
|
+
+@use 'sass:meta';
|
|
25
|
+
+
|
|
26
|
+
-@use '@rdlabo/ionic-theme-ios26/src/styles/default-variables.scss';
|
|
27
|
+
-@use '@rdlabo/ionic-theme-ios26/src/styles/ionic-theme-ios26.scss';
|
|
28
|
+
-@use '@rdlabo/ionic-theme-ios26/src/styles/ionic-theme-ios26-dark-class.scss';
|
|
29
|
+
-@use '@rdlabo/ionic-theme-ios26/src/styles/md-remove-ios-class-effect.scss';
|
|
30
|
+
+@supports (overflow-anchor: auto) {
|
|
31
|
+
+ @include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/default-variables');
|
|
32
|
+
+ @include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/ionic-theme-ios27');
|
|
33
|
+
+ @include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/ionic-theme-ios27-dark-class');
|
|
34
|
+
+ @include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/md-remove-ios-class-effect');
|
|
35
|
+
+}
|
|
36
|
+
+
|
|
37
|
+
+@supports (text-wrap: pretty) and (not (overflow-anchor: auto)) {
|
|
38
|
+
+ @include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/default-variables');
|
|
39
|
+
+ @include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/ionic-theme-ios26');
|
|
40
|
+
+ @include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/ionic-theme-ios26-dark-class');
|
|
41
|
+
+ @include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/md-remove-ios-class-effect');
|
|
42
|
+
+}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Keep Ionic's matching dark palette. For system or always-dark mode, replace both `-dark-class` imports with the matching variant. If you use `md-ion-list-inset`, load the corresponding package's stylesheet inside each branch. Browsers without either feature retain Ionic's default styling.
|
|
46
|
+
|
|
47
|
+
### 3. Switch the animations
|
|
48
|
+
|
|
49
|
+
Replace the iOS 26 animation import and gate the iOS 27 animations on the same browser features. Resolve the options before Ionic initializes:
|
|
50
|
+
|
|
51
|
+
```diff
|
|
52
|
+
-import { iosTransitionAnimation, popoverEnterAnimation, popoverLeaveAnimation } from '@rdlabo/ionic-theme-ios26';
|
|
53
|
+
+import { iosTransitionAnimation, popoverEnterAnimation, popoverLeaveAnimation } from '@rdlabo/ionic-theme-ios27';
|
|
54
|
+
+
|
|
55
|
+
+function loadIOSAnimations() {
|
|
56
|
+
+ if (typeof CSS === 'undefined') return {};
|
|
57
|
+
+ if (!CSS.supports('overflow-anchor: auto') && !CSS.supports('text-wrap: pretty')) return {};
|
|
58
|
+
+
|
|
59
|
+
+ return {
|
|
60
|
+
+ navAnimation: iosTransitionAnimation,
|
|
61
|
+
+ popoverEnter: popoverEnterAnimation,
|
|
62
|
+
+ popoverLeave: popoverLeaveAnimation,
|
|
63
|
+
+ };
|
|
64
|
+
+}
|
|
65
|
+
|
|
66
|
+
provideIonicAngular({
|
|
67
|
+
- navAnimation: isPlatform('ios') ? iosTransitionAnimation : undefined,
|
|
68
|
+
- popoverEnter: isPlatform('ios') ? popoverEnterAnimation : undefined,
|
|
69
|
+
- popoverLeave: isPlatform('ios') ? popoverLeaveAnimation : undefined,
|
|
70
|
+
+ ...(isPlatform('ios') ? loadIOSAnimations() : {}),
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The iOS 27 page transition and popover animations serve both styled generations. Older browsers keep Ionic's defaults. The example uses Angular; pass the same options to React's `setupIonicReact` or Vue's `IonicVue`.
|
|
75
|
+
|
|
76
|
+
### 4. Update customizations
|
|
77
|
+
|
|
78
|
+
Rename theme variables and opt-out classes used by your app. For example:
|
|
79
|
+
|
|
80
|
+
```diff
|
|
81
|
+
ion-content {
|
|
82
|
+
- --ios26-content-box-shadow-rgb: 0, 0, 0;
|
|
83
|
+
+ --ios-theme-content-box-shadow-rgb: 0, 0, 0;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
-<ion-button class="ios26-disabled">Standard Ionic button</ion-button>
|
|
87
|
+
+<ion-button class="ios-theme-disabled">Standard Ionic button</ion-button>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The old names remain as deprecated fallbacks. Check the resulting screens in light and dark modes on the browsers you support.
|
|
91
|
+
|
|
92
|
+
### iOS 27 only
|
|
93
|
+
|
|
94
|
+
To switch entirely to iOS 27, remove the iOS 26 package and replace its stylesheet and animation imports. The stylesheet changes are:
|
|
95
|
+
|
|
96
|
+
```diff
|
|
97
|
+
-@use '@rdlabo/ionic-theme-ios26/src/styles/default-variables.scss';
|
|
98
|
+
-@use '@rdlabo/ionic-theme-ios26/src/styles/ionic-theme-ios26.scss';
|
|
99
|
+
-@use '@rdlabo/ionic-theme-ios26/src/styles/ionic-theme-ios26-dark-class.scss';
|
|
100
|
+
-@use '@rdlabo/ionic-theme-ios26/src/styles/md-remove-ios-class-effect.scss';
|
|
101
|
+
+@use '@rdlabo/ionic-theme-ios27/src/styles/default-variables.scss';
|
|
102
|
+
+@use '@rdlabo/ionic-theme-ios27/src/styles/ionic-theme-ios27.scss';
|
|
103
|
+
+@use '@rdlabo/ionic-theme-ios27/src/styles/ionic-theme-ios27-dark-class.scss';
|
|
104
|
+
+@use '@rdlabo/ionic-theme-ios27/src/styles/md-remove-ios-class-effect.scss';
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Change the animation import from `@rdlabo/ionic-theme-ios26` to `@rdlabo/ionic-theme-ios27`; the existing `isPlatform('ios')` configuration can stay. See the README's [iOS 27-only setup](https://docs.rdlabo.dev/projects/ionic-theme-ios27#use-only-the-ios-27-theme). Unconditional imports apply the new styles on every browser using Ionic iOS mode.
|
|
108
|
+
|
|
7
109
|
## iOS 27 naming
|
|
8
110
|
|
|
9
|
-
|
|
111
|
+
For the iOS 27 branch or an iOS 27-only app, use `@rdlabo/ionic-theme-ios27`. Its stylesheets are `ionic-theme-ios27.scss` or `ionic-theme-ios27.css`, including the `-dark-always`, `-dark-system`, and `-dark-class` variants. Keep the iOS 26 stylesheet names in the iOS 26 branch of an adaptive setup.
|
|
10
112
|
|
|
11
113
|
Use the version-independent `--ios-theme-*` CSS variables. The corresponding `--ios26-*` variables remain supported as deprecated fallbacks. When both are set, the new name takes precedence. For example, use `--ios-theme-content-box-shadow-rgb` instead of `--ios26-content-box-shadow-rgb`.
|
|
12
114
|
|
|
@@ -22,7 +124,7 @@ Submit buttons now use each Ionic color's standard contrast value and an iOS 27
|
|
|
22
124
|
|
|
23
125
|
```diff
|
|
24
126
|
:root {
|
|
25
|
-
-
|
|
26
|
-
-
|
|
127
|
+
- --ion-color-primary-brightness-rgb: 130, 255, 255;
|
|
128
|
+
- --ion-color-primary-brightness: #96feff;
|
|
27
129
|
}
|
|
28
130
|
```
|
package/package.json
CHANGED
package/docs/ios-adaptive.md
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Adaptive iOS themes
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Adaptive iOS themes
|
|
6
|
-
|
|
7
|
-
Use CSS feature queries to choose a theme while keeping Ionic's default iOS styles on older browsers. The newer theme branch uses `overflow-anchor` support; see the [MDN `overflow-anchor` documentation](https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-anchor).
|
|
8
|
-
|
|
9
|
-
These checks detect browser capabilities, not the operating system version. Other browsers may support the same features. Keep Ionic mode and platform-specific animation configuration consistent with your application.
|
|
10
|
-
|
|
11
|
-
## Load only the iOS 27 theme
|
|
12
|
-
|
|
13
|
-
In your global Sass stylesheet, use `meta.load-css` inside the feature query. Unlike `@use`, it can emit the theme inside `@supports`.
|
|
14
|
-
|
|
15
|
-
```scss
|
|
16
|
-
@use 'sass:meta';
|
|
17
|
-
|
|
18
|
-
@supports (overflow-anchor: auto) {
|
|
19
|
-
@include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/default-variables');
|
|
20
|
-
@include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/ionic-theme-ios27');
|
|
21
|
-
@include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/ionic-theme-ios27-dark-class');
|
|
22
|
-
@include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/md-remove-ios-class-effect');
|
|
23
|
-
}
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Configure animations from the same package as in the [README](https://docs.rdlabo.dev/projects/ionic-theme-ios27#configure-animations).
|
|
27
|
-
|
|
28
|
-
## Use the iOS 26 and iOS 27 themes together
|
|
29
|
-
|
|
30
|
-
Install both packages:
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
npm install @rdlabo/ionic-theme-ios26 @rdlabo/ionic-theme-ios27
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
Use this global Sass configuration instead of unconditional theme imports:
|
|
37
|
-
|
|
38
|
-
```scss
|
|
39
|
-
@use 'sass:meta';
|
|
40
|
-
|
|
41
|
-
@supports (overflow-anchor: auto) {
|
|
42
|
-
@include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/default-variables');
|
|
43
|
-
@include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/ionic-theme-ios27');
|
|
44
|
-
@include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/ionic-theme-ios27-dark-class');
|
|
45
|
-
@include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/md-remove-ios-class-effect');
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
@supports (text-wrap: pretty) and (not (overflow-anchor: auto)) {
|
|
49
|
-
@include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/default-variables');
|
|
50
|
-
@include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/ionic-theme-ios26');
|
|
51
|
-
@include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/ionic-theme-ios26-dark-class');
|
|
52
|
-
@include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/md-remove-ios-class-effect');
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
The branches are mutually exclusive. Browsers without either feature retain Ionic's default styling. The `text-wrap: pretty` check preserves the earlier theme's capability-based fallback when `overflow-anchor` is unavailable.
|
|
57
|
-
|
|
58
|
-
Both examples use class-based dark mode. Load Ionic's matching dark palette in your application; for system or always-dark mode, replace the `-dark-class` imports with the matching variant. If you also use `md-ion-list-inset`, load the corresponding package's stylesheet inside each branch.
|
|
59
|
-
|
|
60
|
-
### Page transition and overlay animations
|
|
61
|
-
|
|
62
|
-
When both packages are installed, keep **page transition** (`navAnimation`) on the iOS 27 animation. Styles still follow the feature queries above; only the transition stays on `@rdlabo/ionic-theme-ios27`. Use the same package for popover enter/leave so overlay motion stays consistent with that transition.
|
|
63
|
-
|
|
64
|
-
```ts
|
|
65
|
-
import { iosTransitionAnimation, popoverEnterAnimation, popoverLeaveAnimation } from '@rdlabo/ionic-theme-ios27';
|
|
66
|
-
|
|
67
|
-
function loadIOSAnimations() {
|
|
68
|
-
if (typeof CSS === 'undefined') {
|
|
69
|
-
return {};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Styles are adaptive; apply iOS theme animations when either generation matches.
|
|
73
|
-
if (!CSS.supports('overflow-anchor: auto') && !CSS.supports('text-wrap: pretty')) {
|
|
74
|
-
return {};
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return {
|
|
78
|
-
navAnimation: iosTransitionAnimation,
|
|
79
|
-
popoverEnter: popoverEnterAnimation,
|
|
80
|
-
popoverLeave: popoverLeaveAnimation,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Resolve synchronously before bootstrapping so Ionic's global config exists before any element upgrades.
|
|
85
|
-
const animations = isPlatform('ios') ? loadIOSAnimations() : {};
|
|
86
|
-
provideIonicAngular({ ...animations });
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
Import `isPlatform` and `provideIonicAngular` from your Ionic Angular entry point as shown in the README. Pass the same options to `setupIonicReact` or `IonicVue` when using those frameworks. In server-rendered apps, run the selection during browser initialization.
|