@rdlabo/ionic-theme-ios27 1.2.1 → 2.0.0-beta.pr303.shaf4f5ca16816f
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 +24 -280
- 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/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/layout/index.d.ts +18 -0
- package/dist/layout/index.d.ts.map +1 -0
- package/dist/layout/index.js +26 -0
- package/dist/layout/index.js.map +1 -0
- package/dist/segment/index.js +3 -3
- package/dist/segment/index.js.map +1 -1
- package/dist/sheets-of-glass/index.js +7 -7
- package/dist/sheets-of-glass/index.js.map +1 -1
- package/dist/tab-bar-searchable/dismiss-button.js +53 -3
- package/dist/tab-bar-searchable/dismiss-button.js.map +1 -1
- package/dist/tab-bar-searchable/index.js +18 -3
- package/dist/tab-bar-searchable/index.js.map +1 -1
- package/dist/transition/ios.transition.d.ts.map +1 -1
- package/dist/transition/ios.transition.js +7 -4
- package/dist/transition/ios.transition.js.map +1 -1
- package/dist/transition/native-ui.d.ts +6 -0
- package/dist/transition/native-ui.d.ts.map +1 -0
- package/dist/{native-integration/index.js → transition/native-ui.js} +16 -30
- package/dist/transition/native-ui.js.map +1 -0
- package/docs/adaptive-themes.md +151 -0
- package/docs/add-native-ui.md +53 -0
- package/docs/animation.md +1 -1
- package/docs/eslint.md +1 -1
- package/docs/features.md +3 -3
- package/docs/iphone-duo-with-original-theme.md +40 -28
- package/docs/iphone-duo.md +29 -32
- package/docs/migration.md +12 -24
- package/docs/setup.md +82 -0
- package/docs/special-markup.md +5 -5
- package/docs/using-ion-item-group.md +2 -2
- package/docs/vertical-bars-layout.md +47 -0
- package/package.json +12 -42
- package/src/index.ts +3 -1
- package/src/layout/index.ts +29 -0
- package/src/segment/index.ts +3 -3
- package/src/sheets-of-glass/index.ts +7 -7
- package/src/styles/components/ion-toolbar.scss +1 -1
- package/src/styles/vertical-bars.scss +15 -18
- package/src/tab-bar-searchable/dismiss-button.ts +73 -4
- package/src/tab-bar-searchable/index.ts +20 -3
- package/src/transition/ios.transition.ts +7 -4
- package/src/{native-integration/index.ts → transition/native-ui.ts} +17 -46
- package/Package.swift +0 -21
- package/dist/_virtual/_rolldown/runtime.js +0 -13
- package/dist/native/components/index.d.ts +0 -19
- package/dist/native/components/index.d.ts.map +0 -1
- package/dist/native/components/index.js +0 -40
- package/dist/native/components/index.js.map +0 -1
- package/dist/native/components/ion-back-button.d.ts +0 -9
- package/dist/native/components/ion-back-button.d.ts.map +0 -1
- package/dist/native/components/ion-back-button.js +0 -20
- package/dist/native/components/ion-back-button.js.map +0 -1
- package/dist/native/components/ion-button.d.ts +0 -10
- package/dist/native/components/ion-button.d.ts.map +0 -1
- package/dist/native/components/ion-button.js +0 -23
- package/dist/native/components/ion-button.js.map +0 -1
- package/dist/native/components/ion-buttons.d.ts +0 -11
- package/dist/native/components/ion-buttons.d.ts.map +0 -1
- package/dist/native/components/ion-buttons.js +0 -30
- package/dist/native/components/ion-buttons.js.map +0 -1
- package/dist/native/components/ion-fab.d.ts +0 -10
- package/dist/native/components/ion-fab.d.ts.map +0 -1
- package/dist/native/components/ion-fab.js +0 -132
- package/dist/native/components/ion-fab.js.map +0 -1
- package/dist/native/components/ion-menu-button.d.ts +0 -13
- package/dist/native/components/ion-menu-button.d.ts.map +0 -1
- package/dist/native/components/ion-menu-button.js +0 -31
- package/dist/native/components/ion-menu-button.js.map +0 -1
- package/dist/native/components/ion-segment.d.ts +0 -11
- package/dist/native/components/ion-segment.d.ts.map +0 -1
- package/dist/native/components/ion-segment.js +0 -30
- package/dist/native/components/ion-segment.js.map +0 -1
- package/dist/native/components/ion-tab-bar.d.ts +0 -11
- package/dist/native/components/ion-tab-bar.d.ts.map +0 -1
- package/dist/native/components/ion-tab-bar.js +0 -50
- package/dist/native/components/ion-tab-bar.js.map +0 -1
- package/dist/native/components/searchable-tabs.d.ts +0 -20
- package/dist/native/components/searchable-tabs.d.ts.map +0 -1
- package/dist/native/components/searchable-tabs.js +0 -383
- package/dist/native/components/searchable-tabs.js.map +0 -1
- package/dist/native/definitions.d.ts +0 -152
- package/dist/native/definitions.d.ts.map +0 -1
- package/dist/native/definitions.js +0 -0
- package/dist/native/foldable/fold-state.d.ts +0 -5
- package/dist/native/foldable/fold-state.d.ts.map +0 -1
- package/dist/native/foldable/fold-state.js +0 -14
- package/dist/native/foldable/fold-state.js.map +0 -1
- package/dist/native/foldable/types.d.ts +0 -12
- package/dist/native/foldable/types.d.ts.map +0 -1
- package/dist/native/foldable/types.js +0 -0
- package/dist/native/index.d.ts +0 -11
- package/dist/native/index.d.ts.map +0 -1
- package/dist/native/index.js +0 -242
- package/dist/native/index.js.map +0 -1
- package/dist/native/prehide.d.ts +0 -7
- package/dist/native/prehide.d.ts.map +0 -1
- package/dist/native/prehide.js +0 -230
- package/dist/native/prehide.js.map +0 -1
- package/dist/native/runtime.d.ts +0 -5
- package/dist/native/runtime.d.ts.map +0 -1
- package/dist/native/runtime.js +0 -640
- package/dist/native/runtime.js.map +0 -1
- package/dist/native/shared/candidate.d.ts +0 -21
- package/dist/native/shared/candidate.d.ts.map +0 -1
- package/dist/native/shared/candidate.js +0 -98
- package/dist/native/shared/candidate.js.map +0 -1
- package/dist/native/shared/crossfade.d.ts +0 -10
- package/dist/native/shared/crossfade.d.ts.map +0 -1
- package/dist/native/shared/crossfade.js +0 -50
- package/dist/native/shared/crossfade.js.map +0 -1
- package/dist/native/shared/dom.d.ts +0 -46
- package/dist/native/shared/dom.d.ts.map +0 -1
- package/dist/native/shared/dom.js +0 -172
- package/dist/native/shared/dom.js.map +0 -1
- package/dist/native/shared/events.d.ts +0 -11
- package/dist/native/shared/events.d.ts.map +0 -1
- package/dist/native/shared/events.js +0 -13
- package/dist/native/shared/events.js.map +0 -1
- package/dist/native/shared/icons.d.ts +0 -8
- package/dist/native/shared/icons.d.ts.map +0 -1
- package/dist/native/shared/icons.js +0 -61
- package/dist/native/shared/icons.js.map +0 -1
- package/dist/native/shared/modal.d.ts +0 -10
- package/dist/native/shared/modal.d.ts.map +0 -1
- package/dist/native/shared/modal.js +0 -160
- package/dist/native/shared/modal.js.map +0 -1
- package/dist/native/vertical-bars-web-search.d.ts +0 -9
- package/dist/native/vertical-bars-web-search.d.ts.map +0 -1
- package/dist/native/vertical-bars-web-search.js +0 -84
- package/dist/native/vertical-bars-web-search.js.map +0 -1
- package/dist/native/vertical-bars-web.d.ts +0 -5
- package/dist/native/vertical-bars-web.d.ts.map +0 -1
- package/dist/native/vertical-bars-web.js +0 -341
- package/dist/native/vertical-bars-web.js.map +0 -1
- package/dist/native-integration/index.d.ts +0 -23
- package/dist/native-integration/index.d.ts.map +0 -1
- package/dist/native-integration/index.js.map +0 -1
- package/dist/native-integration/transition.d.ts +0 -5
- package/dist/native-integration/transition.d.ts.map +0 -1
- package/dist/native-integration/transition.js +0 -16
- package/dist/native-integration/transition.js.map +0 -1
- package/dist/vertical-bars.d.ts +0 -5
- package/dist/vertical-bars.js +0 -4
- package/docs/e2e-testing.md +0 -51
- package/docs/feedback.md +0 -65
- package/docs/native-ui-shell.md +0 -285
- package/docs/vertical-bars.md +0 -285
- package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellButton.swift +0 -71
- package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellButtons.swift +0 -24
- package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellComponents.swift +0 -18
- package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellFab.swift +0 -83
- package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellSearchController.swift +0 -432
- package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellSegment.swift +0 -91
- package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellTabBar.swift +0 -221
- package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellVerticalBars.swift +0 -437
- package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellVerticalSearch.swift +0 -118
- package/ios/Sources/IonicNativeUIShellPlugin/IonicNativeUIShellPlugin.swift +0 -396
- package/ios/Sources/IonicNativeUIShellPlugin/Shared/ShellCrossfade.swift +0 -35
- package/ios/Sources/IonicNativeUIShellPlugin/Shared/ShellHost.swift +0 -8
- package/ios/Sources/IonicNativeUIShellPlugin/Shared/ShellRendering.swift +0 -27
- package/ios/Sources/IonicNativeUIShellPlugin/Shared/ShellSnapshot.swift +0 -135
- package/ios/Tests/IonicNativeUIShellPluginTests/ShellSnapshotTests.swift +0 -650
- package/src/native/components/index.ts +0 -53
- package/src/native/components/ion-back-button.ts +0 -19
- package/src/native/components/ion-button.ts +0 -24
- package/src/native/components/ion-buttons.ts +0 -38
- package/src/native/components/ion-fab.ts +0 -151
- package/src/native/components/ion-menu-button.ts +0 -24
- package/src/native/components/ion-segment.ts +0 -27
- package/src/native/components/ion-tab-bar.ts +0 -50
- package/src/native/components/searchable-tabs.ts +0 -459
- package/src/native/definitions.ts +0 -191
- package/src/native/foldable/fold-state.ts +0 -9
- package/src/native/foldable/types.ts +0 -4
- package/src/native/index.ts +0 -281
- package/src/native/prehide.ts +0 -265
- package/src/native/runtime.ts +0 -781
- package/src/native/shared/candidate.ts +0 -150
- package/src/native/shared/crossfade.ts +0 -50
- package/src/native/shared/dom.ts +0 -286
- package/src/native/shared/events.ts +0 -8
- package/src/native/shared/icons.ts +0 -57
- package/src/native/shared/modal.ts +0 -157
- package/src/native/vertical-bars-web-search.ts +0 -80
- package/src/native/vertical-bars-web.ts +0 -411
- package/src/native-integration/transition.ts +0 -15
- package/src/vertical-bars.ts +0 -11
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
---
|
|
2
|
-
title:
|
|
2
|
+
title: Add Vertical Bars while keeping your theme
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
#
|
|
5
|
+
# Add Vertical Bars while keeping your theme
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Keep your app's existing appearance and add Vertical Bars. Choose the setup for your app's components, whether you use Angular, React, Vue or another framework.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Read [how projection works](../../capacitor-native-ui/README.md#how-projection-works) for the relationship between source DOM, projected controls and actions. Then choose your setup below.
|
|
10
|
+
|
|
11
|
+
## Choose your setup
|
|
12
|
+
|
|
13
|
+
| Your app | Start here | What you add |
|
|
14
|
+
| ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
15
|
+
| Ionic components with your own theme, Ionic's default styles, or another theme | [Ionic setup below](#try-it-in-your-existing-ionic-app) | Standalone rail CSS and the Ionic Native UI adapter. Keep your existing theme. |
|
|
16
|
+
| No Ionic components (plain HTML, React, Vue, Angular, etc.) | [HTML setup](../../capacitor-native-ui/docs/framework-independent.md), then its [Web rail configuration](../../capacitor-native-ui/docs/framework-independent.md#optional-web-rail) | Only `@rdlabo/capacitor-native-ui`, using its `/core` entry. Your app supplies the rail layout. |
|
|
17
|
+
| Already using the iOS 27 theme and Native UI | [Connect device placement](iphone-duo.md#project-controls-into-the-rail) | Reuse your existing runtime. Do not start another one. |
|
|
18
|
+
|
|
19
|
+
**Without Ionic, follow the HTML guide instead of the steps below.** You do not need this theme package, `vertical-bars.css`, `ion-app`, or Ionic navigation animations. Explicitly marked HTML buttons and back buttons are supported; arbitrary HTML tabs are not automatically converted. A browser preview requires an application-styled `webHost`; native rail presentation also requires supported iOS hardware and software.
|
|
20
|
+
|
|
21
|
+
The rest of this page is for **Ionic apps**. Both Ionic `ios` and `md` modes are supported. Tabs and supported toolbar actions move to the side; content and horizontal controls keep their existing appearance.
|
|
10
22
|
|
|
11
23
|
Available in `1.2.0` as a **preview** feature. APIs and supported behavior may change.
|
|
12
24
|
|
|
@@ -14,10 +26,10 @@ Available in `1.2.0` as a **preview** feature. APIs and supported behavior may c
|
|
|
14
26
|
|
|
15
27
|
### 1. Install and load the standalone stylesheet
|
|
16
28
|
|
|
17
|
-
|
|
29
|
+
Start with your existing Ionic app (Ionic `>=8.8.1 <10`, Capacitor 8). Add the two packages:
|
|
18
30
|
|
|
19
31
|
```bash
|
|
20
|
-
npm install @rdlabo/ionic-theme-ios27@
|
|
32
|
+
npm install @rdlabo/ionic-theme-ios27 @rdlabo/capacitor-native-ui
|
|
21
33
|
```
|
|
22
34
|
|
|
23
35
|
Keep your existing theme imports. Add this to your global Sass file:
|
|
@@ -26,7 +38,7 @@ Keep your existing theme imports. Add this to your global Sass file:
|
|
|
26
38
|
@use '@rdlabo/ionic-theme-ios27/dist/css/vertical-bars.css';
|
|
27
39
|
```
|
|
28
40
|
|
|
29
|
-
The
|
|
41
|
+
The full iOS 27 theme stylesheets are not required. Preview these steps in Chrome before connecting an iPhone Duo.
|
|
30
42
|
|
|
31
43
|
### 2. Opt your app into the side layout
|
|
32
44
|
|
|
@@ -50,13 +62,13 @@ If you have not configured `navAnimation`, wrap Ionic's standard builders. Selec
|
|
|
50
62
|
|
|
51
63
|
```ts
|
|
52
64
|
import { iosTransitionAnimation, mdTransitionAnimation, type AnimationBuilder } from '@ionic/core';
|
|
53
|
-
import {
|
|
65
|
+
import { withNativeUITransition } from '@rdlabo/ionic-theme-ios27';
|
|
54
66
|
|
|
55
67
|
const defaultTransition: AnimationBuilder = (baseEl, opts) =>
|
|
56
68
|
(opts.mode === 'ios' ? iosTransitionAnimation : mdTransitionAnimation)(baseEl, opts);
|
|
57
69
|
|
|
58
70
|
const ionicConfig = {
|
|
59
|
-
navAnimation:
|
|
71
|
+
navAnimation: withNativeUITransition(defaultTransition),
|
|
60
72
|
};
|
|
61
73
|
```
|
|
62
74
|
|
|
@@ -82,11 +94,11 @@ If your app uses another builder for `navAnimation`, wrap it:
|
|
|
82
94
|
|
|
83
95
|
```ts
|
|
84
96
|
import type { AnimationBuilder } from '@ionic/core';
|
|
85
|
-
import {
|
|
97
|
+
import { withNativeUITransition } from '@rdlabo/ionic-theme-ios27';
|
|
86
98
|
|
|
87
99
|
// Pass the animation builder your app already uses.
|
|
88
100
|
const configureNavigation = (existingTransition: AnimationBuilder) => ({
|
|
89
|
-
navAnimation:
|
|
101
|
+
navAnimation: withNativeUITransition(existingTransition),
|
|
90
102
|
});
|
|
91
103
|
```
|
|
92
104
|
|
|
@@ -99,36 +111,36 @@ The adapter keeps the builder's animation targets, including any horizontal back
|
|
|
99
111
|
Call this once from your application startup after `ion-app` exists in the DOM:
|
|
100
112
|
|
|
101
113
|
```ts
|
|
102
|
-
import {
|
|
114
|
+
import { enableNativeUI } from '@rdlabo/capacitor-native-ui';
|
|
103
115
|
|
|
104
|
-
const rail = await
|
|
116
|
+
const rail = await enableNativeUI({ verticalBars: { only: true } });
|
|
105
117
|
```
|
|
106
118
|
|
|
107
119
|
**What you should see:** your existing tab bar moves to the side, and fixed-toolbar buttons with an `ion-icon` or SVG using `slot="icon-only"` appear there too. Content keeps its existing theme and leaves room for the controls. The Web tab rail displays icons; pressing and dragging reveals tab labels.
|
|
108
120
|
|
|
109
121
|
Use your existing Ionic click handlers, routing, and form associations. All button fills (`default`, `clear`, `solid`, and `outline`) use the same `icon-only` rule, including submit buttons. Actions without that slot remain horizontal. Add `.ios-theme-horizontal-only` to an `ion-buttons` group or individual `ion-button` to keep an action in the horizontal toolbar.
|
|
110
122
|
|
|
111
|
-
When the application owner is disposed, call `await rail.destroy()` to restore the original controls and release the runtime. If you already use `
|
|
123
|
+
When the application owner is disposed, call `await rail.destroy()` to restore the original controls and release the runtime. If you already use `enableNativeUI()`, keep that runtime and follow the [shared placement guide](iphone-duo.md#project-controls-into-the-rail).
|
|
112
124
|
|
|
113
125
|
### Optional: choose native button appearance
|
|
114
126
|
|
|
115
|
-
`buttonProjection` and local projection settings are available in `1.2.0`. See [Choose button appearance](
|
|
127
|
+
`buttonProjection` and local projection settings are available in `1.2.0`. See [Choose button appearance](../../capacitor-native-ui/docs/vertical-bars.md#choose-button-appearance) for availability and migration details.
|
|
116
128
|
|
|
117
|
-
The
|
|
129
|
+
The default is `system`: SwiftUI styles vertical buttons and tints their icons. If your existing theme should supply their fill and colors, replace the startup call in step 4 with:
|
|
118
130
|
|
|
119
131
|
```ts
|
|
120
|
-
const rail = await
|
|
132
|
+
const rail = await enableNativeUI({ verticalBars: { only: true, buttonProjection: 'source', buttonDefaultFill: 'solid' } });
|
|
121
133
|
```
|
|
122
134
|
|
|
123
|
-
The `solid` default suits ordinary Ionic buttons. Buttons inside `ion-buttons` still default to clear; set `fill="solid"` explicitly to project their background. For one-off exceptions, use the [local projection settings](
|
|
135
|
+
The `solid` default suits ordinary Ionic buttons. Buttons inside `ion-buttons` still default to clear; set `fill="solid"` explicitly to project their background. For one-off exceptions, use the [local projection settings](../../capacitor-native-ui/docs/vertical-bars.md#override-individual-buttons-or-groups). These settings affect native vertical buttons only; Web clones keep their existing appearance.
|
|
124
136
|
|
|
125
137
|
### If the preview does not appear
|
|
126
138
|
|
|
127
|
-
| What you see
|
|
128
|
-
|
|
|
129
|
-
| No space at the side
|
|
130
|
-
| Space appears, but controls stay horizontal | Start `
|
|
131
|
-
| One action stays horizontal
|
|
139
|
+
| What you see | What to check |
|
|
140
|
+
| ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
141
|
+
| No space at the side | Load `vertical-bars.css` and put the class on `ion-app`. |
|
|
142
|
+
| Space appears, but controls stay horizontal | Start `enableNativeUI({ verticalBars: { only: true } })` after mounting the app root. Use existing tabs or `slot="icon-only"` actions in a fixed header/footer toolbar. |
|
|
143
|
+
| One action stays horizontal | Check for `slot="icon-only"` on the icon and a fixed toolbar outside scrolling content. Explicitly excluded controls and controls in centered modals stay horizontal; `fill` and `type="submit"` do not prevent movement. See [control requirements](../../capacitor-native-ui/docs/vertical-bars.md#toolbar-actions). |
|
|
132
144
|
|
|
133
145
|
## Connect an iPhone Duo
|
|
134
146
|
|
|
@@ -139,11 +151,11 @@ npm install @erkamyaman/capacitor-foldable
|
|
|
139
151
|
npx cap sync ios
|
|
140
152
|
```
|
|
141
153
|
|
|
142
|
-
Use Capacitor 8.5 or later and build with Xcode 27.1 or newer for actual rail placement and hinge posture on iOS 27.1.
|
|
154
|
+
Use Capacitor 8.5 or later and build with Xcode 27.1 or newer for actual rail placement and hinge posture on iOS 27.1. Keep your existing SPM or CocoaPods integration; see [Native UI setup](../../capacitor-native-ui/docs/setup.md#4-build-sync-and-run). Keep this package's `vertical-bars.css`; the device plugin's `ionic-tabs.css` is not needed with our rail projection.
|
|
143
155
|
|
|
144
|
-
Replace the browser-only startup with the [device placement setup](
|
|
156
|
+
Replace the browser-only startup with the [device placement setup](iphone-duo.md#project-controls-into-the-rail). That setup sends initial values and `barPlacementChange` events to `setVerticalBarsLayout({ edge: verticalBarEdge, inset })`, with subscriptions and cleanup kept in your application.
|
|
145
157
|
|
|
146
|
-
Pass
|
|
158
|
+
Pass Foldable's reported logical edge and measured inset to `setVerticalBarsLayout`. The helper resolves RTL. A null edge restores the ordinary Web layout; Native UI detects native rail availability independently.
|
|
147
159
|
|
|
148
160
|
On supported iOS, controls in the rail use native SwiftUI rendering; your custom Web styling still applies to ordinary content and horizontal controls. Web and Android use Web clones.
|
|
149
161
|
|
|
@@ -151,8 +163,8 @@ On supported iOS, controls in the rail use native SwiftUI rendering; your custom
|
|
|
151
163
|
|
|
152
164
|
If your existing theme needs only a posture-driven split pane or a layout switch, do not start a projection runtime or add `.ios-theme-vertical-bars`. Pass `Foldable.getFoldState()` results and `foldStateChange` events to `applyFoldStateClasses(root, fold)`, removing the listener when finished. There is no separate start/stop monitoring call.
|
|
153
165
|
|
|
154
|
-
See [Read the device layout](
|
|
166
|
+
See [Read the device layout](iphone-duo.md#read-the-device-layout) for the subscription example, null values, and monitoring lifetime. See [Adapt the split pane](iphone-duo.md#adapt-the-split-pane) for the opt-in width rules and half-open state.
|
|
155
167
|
|
|
156
168
|
## Shared layout rules and API
|
|
157
169
|
|
|
158
|
-
Safe-area handling, overlays, RTL, control eligibility, Web simulation, and the handle API are documented in [Vertical Bars](
|
|
170
|
+
Safe-area handling, overlays, RTL, control eligibility, Web simulation, and the handle API are documented in [Vertical Bars](../../capacitor-native-ui/docs/vertical-bars.md). Read that reference when you need to customize this setup; it is not an additional installation step.
|
package/docs/iphone-duo.md
CHANGED
|
@@ -6,27 +6,27 @@ title: iPhone Duo support (preview)
|
|
|
6
6
|
|
|
7
7
|
Adapt your Ionic app to iPhone Duo: place navigation and actions in its vertical system rail, and adjust your split pane as the device opens and closes. Existing Ionic markup remains the source of labels, icons, routing, and click handlers.
|
|
8
8
|
|
|
9
|
-
**New here?** Start with [iPhone Duo with your existing theme](
|
|
9
|
+
**New here?** Start with [iPhone Duo with your existing theme](iphone-duo-with-original-theme.md) to preview the side layout in Chrome. This page explains device events, placement and split panes. [Vertical Bars](../../capacitor-native-ui/docs/vertical-bars.md) documents control projection and the runtime API.
|
|
10
10
|
|
|
11
|
-
Available in `1.2.0` as a **preview** feature alongside [Native UI
|
|
11
|
+
Available in `1.2.0` as a **preview** feature alongside [Native UI](../../capacitor-native-ui/docs/native-ui.md). APIs and supported behavior may change before stable status. Stable status is planned after the official release of Xcode 27.1. The real system rail and hinge reporting require iOS 27.1 or later and an app built with Xcode 27.1 or newer.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Use the theme layout and native plugin independently for that hardware. Neither requires the full iOS 27 appearance:
|
|
14
14
|
|
|
15
|
-
- `dist/css/vertical-bars.css` — opt-in classes that reserve the rail's safe area, plus a registered custom property for a posture-driven split-pane width.
|
|
16
|
-
- `
|
|
15
|
+
- Theme: `dist/css/vertical-bars.css` — opt-in classes that reserve the rail's safe area, plus a registered custom property for a posture-driven split-pane width.
|
|
16
|
+
- Native UI: `enableNativeUI({ verticalBars: { only: true } })` — moves eligible tabs and toolbar controls into the reserved area. On Capacitor iOS they are rendered by a native SwiftUI `TabView` and toolbar; everywhere else the same controls appear as Web clones.
|
|
17
17
|
|
|
18
|
-
Device state belongs to [`@erkamyaman/capacitor-foldable`](https://github.com/erkamyaman/capacitor-foldable). The **application** subscribes to its events and chooses its layout.
|
|
18
|
+
Device state belongs to [`@erkamyaman/capacitor-foldable`](https://github.com/erkamyaman/capacitor-foldable). The **application** subscribes to its events and chooses its layout. The theme reserves space and adapts the split pane; Native UI projects eligible controls. The theme does not monitor hinge state or bar placement.
|
|
19
19
|
|
|
20
20
|
## Choose what to adopt
|
|
21
21
|
|
|
22
|
-
To keep your existing theme and add only the standalone support, follow [iPhone Duo with your existing theme](
|
|
22
|
+
To keep your existing theme and add only the standalone support, follow [iPhone Duo with your existing theme](iphone-duo-with-original-theme.md). This page covers the shared device-layout rules.
|
|
23
23
|
|
|
24
|
-
| Goal
|
|
25
|
-
|
|
|
26
|
-
| Hinge posture only (layout switches)
|
|
27
|
-
| Posture-driven split-pane width
|
|
28
|
-
| Vertical rail for tabs and toolbar actions
|
|
29
|
-
| Native shell plus the rail
|
|
24
|
+
| Goal | Stylesheet | Runtime |
|
|
25
|
+
| ------------------------------------------ | ------------------- | -------------------------------------------------- |
|
|
26
|
+
| Hinge posture only (layout switches) | none | none — subscribe to `Foldable` directly |
|
|
27
|
+
| Posture-driven split-pane width | `vertical-bars.css` | none — subscribe to `Foldable` directly |
|
|
28
|
+
| Vertical rail for tabs and toolbar actions | `vertical-bars.css` | `enableNativeUI({ verticalBars: { only: true } })` |
|
|
29
|
+
| Native shell plus the rail | `vertical-bars.css` | `enableNativeUI()` — includes rail projection |
|
|
30
30
|
|
|
31
31
|
```scss
|
|
32
32
|
@use '@rdlabo/ionic-theme-ios27/dist/css/vertical-bars.css';
|
|
@@ -51,7 +51,7 @@ After `ion-app` is mounted, pass device state to `applyFoldStateClasses`. The ap
|
|
|
51
51
|
|
|
52
52
|
```ts
|
|
53
53
|
import { Foldable } from '@erkamyaman/capacitor-foldable';
|
|
54
|
-
import { applyFoldStateClasses } from '@rdlabo/ionic-theme-ios27
|
|
54
|
+
import { applyFoldStateClasses } from '@rdlabo/ionic-theme-ios27';
|
|
55
55
|
|
|
56
56
|
const root = document.querySelector('ion-app')!;
|
|
57
57
|
const listener = await Foldable.addListener('foldStateChange', (fold) => applyFoldStateClasses(root, fold));
|
|
@@ -68,7 +68,7 @@ Subscribe to changes, then read the current state. The same helper handles initi
|
|
|
68
68
|
|
|
69
69
|
`applyFoldStateClasses` keeps one of `ios-theme-fold-flat`, `ios-theme-fold-half-opened`, and `ios-theme-fold-closed` on the supplied root, preserving unrelated classes. It also sets `ios-theme-fold-expanded` for a half-opened state or a flat state with hinge geometry. A flat state without geometry (including the Web fallback) and a closed state clear that class. The helper does not subscribe to the plugin or change Ionic's split-pane `when` property.
|
|
70
70
|
|
|
71
|
-
For rail placement, use `
|
|
71
|
+
For rail placement, use `setVerticalBarsLayout` as shown below. Import this Web layout helper from the theme and pass the reported logical `edge` with the measured `inset`. It does not report native availability or activate projection. Leading is the physical left in LTR and the physical right in RTL. A null edge restores the ordinary layout; an inset of zero clears the explicit width. No start/stop monitoring calls are needed.
|
|
72
72
|
|
|
73
73
|
WebView corner radius remains a rendering concern: `configureNativeTransition()` uses the shell's `getWebViewMetrics()` API, independently of `Foldable`.
|
|
74
74
|
|
|
@@ -76,22 +76,23 @@ WebView corner radius remains a rendering concern: `configureNativeTransition()`
|
|
|
76
76
|
|
|
77
77
|
## Reserve the vertical rail
|
|
78
78
|
|
|
79
|
-
Load `vertical-bars.css` as shown above. For class-based browser simulation, safe-area handling, RTL and overlay layout, see [Reserve the vertical rail](
|
|
79
|
+
Load `vertical-bars.css` as shown above. For class-based browser simulation, safe-area handling, RTL and overlay layout, see [Reserve the vertical rail](vertical-bars-layout.md#reserve-the-vertical-rail). On device, the placement helper below applies the layout classes and measured inset.
|
|
80
80
|
|
|
81
81
|
## Project controls into the rail
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
Enable rail projection once after `ion-app` is mounted, and apply Foldable's placement to the Web layout with `setVerticalBarsLayout`:
|
|
84
84
|
|
|
85
85
|
```ts
|
|
86
86
|
import { Foldable } from '@erkamyaman/capacitor-foldable';
|
|
87
|
-
import {
|
|
87
|
+
import { setVerticalBarsLayout } from '@rdlabo/ionic-theme-ios27';
|
|
88
|
+
import { enableNativeUI } from '@rdlabo/capacitor-native-ui';
|
|
88
89
|
|
|
89
|
-
const rail = await
|
|
90
|
+
const rail = await enableNativeUI({ verticalBars: { only: true } });
|
|
90
91
|
const listener = await Foldable.addListener('barPlacementChange', ({ verticalBarEdge, inset }) =>
|
|
91
|
-
|
|
92
|
+
setVerticalBarsLayout({ edge: verticalBarEdge, inset }),
|
|
92
93
|
);
|
|
93
94
|
const { verticalBarEdge, inset } = await Foldable.getBarPlacement();
|
|
94
|
-
|
|
95
|
+
setVerticalBarsLayout({ edge: verticalBarEdge, inset });
|
|
95
96
|
```
|
|
96
97
|
|
|
97
98
|
When the application owner is disposed:
|
|
@@ -101,30 +102,26 @@ await listener.remove();
|
|
|
101
102
|
await rail.destroy();
|
|
102
103
|
```
|
|
103
104
|
|
|
104
|
-
|
|
105
|
+
Native UI detects native availability independently through its own device metrics. The theme helper controls Web layout only. The measured `inset` is passed through instead of assuming a fixed width. Devices without a reported rail, including Web and Android, return a null edge and retain the ordinary layout. For browser simulation, use the [class-based preview](vertical-bars-layout.md#reserve-the-vertical-rail) without connecting device placement.
|
|
105
106
|
|
|
106
|
-
Start either `
|
|
107
|
+
Start either `enableNativeUI({ verticalBars: { only: true } })` or the full `enableNativeUI()` — not both. If the app already uses Native UI, keep that runtime and use the same `setVerticalBarsLayout` callback. The application owner removes its listeners and destroys its runtime on teardown.
|
|
107
108
|
|
|
108
|
-
On supported iOS versions the runtime hands eligible tabs, back navigation, menu buttons, and fixed-toolbar actions to a native SwiftUI `TabView` and toolbar; on Web, Android, or when native projection is unavailable, Web clones remain the fallback. See [Toolbar actions](
|
|
109
|
+
On supported iOS versions the runtime hands eligible tabs, back navigation, menu buttons, and fixed-toolbar actions to a native SwiftUI `TabView` and toolbar; on Web, Android, or when native projection is unavailable, Web clones remain the fallback. See [Toolbar actions](../../capacitor-native-ui/docs/vertical-bars.md#toolbar-actions) for control eligibility.
|
|
109
110
|
|
|
110
111
|
### Toolbar actions
|
|
111
112
|
|
|
112
|
-
See [Vertical Bars: Toolbar actions](
|
|
113
|
+
See [Vertical Bars: Toolbar actions](../../capacitor-native-ui/docs/vertical-bars.md#toolbar-actions) for eligible markup, placement, button appearance and local overrides.
|
|
113
114
|
|
|
114
115
|
### Tab bar
|
|
115
116
|
|
|
116
|
-
See [Vertical Bars: Tab bar](
|
|
117
|
+
See [Vertical Bars: Tab bar](../../capacitor-native-ui/docs/vertical-bars.md#tab-bar) for navigation, labels and Web fallback behavior.
|
|
117
118
|
|
|
118
119
|
## Adapt the split pane
|
|
119
120
|
|
|
120
121
|
For a side-by-side menu on iPhone Duo, opt the `ion-split-pane` into the separately measured Settings layout. The sidebar is 320pt when fully unfolded and reaches the display midpoint when half-opened (50vw). The application supplies the posture; both states have the same viewport width, so a width media query cannot distinguish them:
|
|
121
122
|
|
|
122
123
|
```html
|
|
123
|
-
<ion-split-pane
|
|
124
|
-
class="split-pane-fold-layout"
|
|
125
|
-
contentId="main-content"
|
|
126
|
-
when="(min-width: 900px)"
|
|
127
|
-
>
|
|
124
|
+
<ion-split-pane class="split-pane-fold-layout" contentId="main-content" when="(min-width: 900px)">
|
|
128
125
|
<ion-menu contentId="main-content">...</ion-menu>
|
|
129
126
|
<div id="main-content">...</div>
|
|
130
127
|
</ion-split-pane>
|
|
@@ -147,4 +144,4 @@ Ionic's `when` still controls whether the menu is persistent. The example choose
|
|
|
147
144
|
|
|
148
145
|
## Vertical Control Area API
|
|
149
146
|
|
|
150
|
-
The runtime handle reference is maintained in [Vertical Bars](
|
|
147
|
+
The runtime handle reference is maintained in [Vertical Bars](../../capacitor-native-ui/docs/vertical-bars.md#vertical-control-area-api).
|
package/docs/migration.md
CHANGED
|
@@ -1,35 +1,23 @@
|
|
|
1
1
|
---
|
|
2
|
-
title:
|
|
2
|
+
title: Theme migration
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
#
|
|
5
|
+
# Theme migration
|
|
6
6
|
|
|
7
|
-
## Native UI
|
|
7
|
+
## Native UI package separation
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Theme styles and ordinary theme API imports remain supported. If you previously used native controls through this package, the `/native` and `/vertical-bars` entries have been removed:
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
-
|
|
11
|
+
| Previous import | Replacement |
|
|
12
|
+
| ----------------------------------------- | ------------------------------------------- |
|
|
13
|
+
| `@rdlabo/ionic-theme-ios27/native` | `@rdlabo/capacitor-native-ui` |
|
|
14
|
+
| `@rdlabo/ionic-theme-ios27/vertical-bars` | `@rdlabo/capacitor-native-ui/vertical-bars` |
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
+ import { withNativeUIShellTransition } from '@rdlabo/ionic-theme-ios27/vertical-bars';
|
|
17
|
-
|
|
18
|
-
const ionicConfig = {
|
|
19
|
-
- navAnimation: existingTransition,
|
|
20
|
-
+ navAnimation: withNativeUIShellTransition(existingTransition),
|
|
21
|
-
};
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
Merge this option into your existing Ionic configuration before initialization. The adapter preserves the animation's effects, duration, and easing while coordinating native retirement, swipe progress, and cancellation. Keep your existing theme stylesheet imports and Native UI Shell or Vertical Control Area startup.
|
|
25
|
-
|
|
26
|
-
Use the adapter only for navigation; leave modal and popover animations unchanged. Your builder must create a fresh `Animation` for each navigation because Ionic destroys it afterward. Keep lifecycle events for control registration and transitions without animation. If the custom builder animates a horizontal back button separately, exclude that effect while `.ios-theme-vertical-bars` is active.
|
|
27
|
-
|
|
28
|
-
See [Connect your navigation animation](./iphone-duo-with-original-theme.md#3.-connect-your-navigation-animation) for the setup and supported scope.
|
|
16
|
+
Add the native package as a direct application dependency, update imports, rebuild Web assets, and run `npx cap sync ios`. Follow the [Native UI migration guide](https://github.com/rdlabo-dev/ionic-theme-ios27/blob/main/packages/capacitor-native-ui/docs/migration.md) for the intermediate package rename and old Swift package references. Theme-only apps do not need native startup or plugin setup.
|
|
29
17
|
|
|
30
18
|
## From the iOS 26 theme
|
|
31
19
|
|
|
32
|
-
For an app using `@rdlabo/ionic-theme-ios26`, the recommended migration keeps that package and adds `@rdlabo/ionic-theme-ios27`. The [
|
|
20
|
+
For an app using `@rdlabo/ionic-theme-ios26`, the recommended migration keeps that package and adds `@rdlabo/ionic-theme-ios27`. The [adaptive theme setup](adaptive-themes.md) selects iOS 27 or iOS 26 styles by browser capability and leaves Ionic's default iOS appearance on older browsers.
|
|
33
21
|
|
|
34
22
|
### 1. Add the new package
|
|
35
23
|
|
|
@@ -127,7 +115,7 @@ To switch entirely to iOS 27, remove the iOS 26 package and replace its styleshe
|
|
|
127
115
|
+ @use '@rdlabo/ionic-theme-ios27/src/styles/md-remove-ios-class-effect.scss';
|
|
128
116
|
```
|
|
129
117
|
|
|
130
|
-
Change the animation import from `@rdlabo/ionic-theme-ios26` to `@rdlabo/ionic-theme-ios27`; the existing `isPlatform('ios')` configuration can stay. See the
|
|
118
|
+
Change the animation import from `@rdlabo/ionic-theme-ios26` to `@rdlabo/ionic-theme-ios27`; the existing `isPlatform('ios')` configuration can stay. See the [iOS 27 setup](setup.md). Unconditional imports apply the new styles on every browser using Ionic iOS mode.
|
|
131
119
|
|
|
132
120
|
## iOS 27 naming
|
|
133
121
|
|
|
@@ -137,7 +125,7 @@ Use the version-independent `--ios-theme-*` CSS variables. The corresponding `--
|
|
|
137
125
|
|
|
138
126
|
For opting out of the theme, use the version-independent `ios-theme-disabled` class. The `ios26-disabled` class remains supported as a deprecated alias; migrate existing markup when convenient.
|
|
139
127
|
|
|
140
|
-
See [Special markup and classes](
|
|
128
|
+
See [Special markup and classes](special-markup.md) and [Default variables](../src/styles/default-variables.scss) for the current names.
|
|
141
129
|
|
|
142
130
|
Earlier migration notes are preserved in the [iOS 26 migration guide](https://docs.rdlabo.dev/projects/ionic-theme-ios26/docs/migration).
|
|
143
131
|
|
package/docs/setup.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Set up the iOS 27 theme
|
|
2
|
+
|
|
3
|
+
Give an existing Ionic app the iOS 27 appearance in four steps. This guide uses the iOS 27 theme on its own and system dark mode. For browser-dependent iOS 26/27 styling or MD3, use [adaptive themes](adaptive-themes.md) instead.
|
|
4
|
+
|
|
5
|
+
## Before you start
|
|
6
|
+
|
|
7
|
+
Use an existing Ionic Angular, React, or Vue application with Ionic `>=8.8.1 <10`. Keep Ionic's base CSS imports. Capacitor is not required, including for browser-only apps.
|
|
8
|
+
|
|
9
|
+
## 1. Install the theme
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install @rdlabo/ionic-theme-ios27
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 2. Load the styles
|
|
16
|
+
|
|
17
|
+
Add these imports to your global stylesheet after Ionic's base styles. Replace an existing Ionic dark palette import rather than loading multiple palettes:
|
|
18
|
+
|
|
19
|
+
```css
|
|
20
|
+
@import '@ionic/core/css/palettes/dark.system.css';
|
|
21
|
+
@import '@rdlabo/ionic-theme-ios27/dist/css/default-variables.css';
|
|
22
|
+
@import '@rdlabo/ionic-theme-ios27/dist/css/ionic-theme-ios27.css';
|
|
23
|
+
@import '@rdlabo/ionic-theme-ios27/dist/css/md-remove-ios-class-effect.css';
|
|
24
|
+
@import '@rdlabo/ionic-theme-ios27/dist/css/ionic-theme-ios27-dark-system.css';
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
For a manual dark-mode toggle, use Ionic's `dark.class.css` and the theme's `ionic-theme-ios27-dark-class.css`, then toggle `ion-palette-dark` on the document root. For always-dark styling, use `dark.always.css` and `ionic-theme-ios27-dark-always.css`. Choose one matching pair.
|
|
28
|
+
|
|
29
|
+
## 3. Configure Ionic animations
|
|
30
|
+
|
|
31
|
+
Set these options in your existing Ionic initialization, before rendering the app:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { iosTransitionAnimation, popoverEnterAnimation, popoverLeaveAnimation } from '@rdlabo/ionic-theme-ios27';
|
|
35
|
+
|
|
36
|
+
const ionicConfig = {
|
|
37
|
+
mode: 'ios' as const,
|
|
38
|
+
navAnimation: iosTransitionAnimation,
|
|
39
|
+
popoverEnter: popoverEnterAnimation,
|
|
40
|
+
popoverLeave: popoverLeaveAnimation,
|
|
41
|
+
};
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
This example deliberately uses `ios` mode so desktop browsers show the theme too. Pass `ionicConfig` to the initializer your app already uses:
|
|
45
|
+
|
|
46
|
+
| Framework | Apply the options |
|
|
47
|
+
| ----------------- | ---------------------------------------------------------------------------- |
|
|
48
|
+
| Angular / Ionic 8 | `provideIonicAngular(ionicConfig)` imported from `@ionic/angular/standalone` |
|
|
49
|
+
| Angular / Ionic 9 | `provideIonicAngular(ionicConfig)` imported from `@ionic/angular` |
|
|
50
|
+
| React | `setupIonicReact(ionicConfig)` imported from `@ionic/react` |
|
|
51
|
+
| Vue | `app.use(IonicVue, ionicConfig)` with `IonicVue` from `@ionic/vue` |
|
|
52
|
+
|
|
53
|
+
Merge with existing options; do not initialize Ionic twice. To retain Material Design mode on Android, keep your platform-based mode selection and apply these animation options only to the iOS configuration. See [adaptive themes](adaptive-themes.md) for a complete platform-aware example.
|
|
54
|
+
|
|
55
|
+
## 4. Preview your first screen
|
|
56
|
+
|
|
57
|
+
Start your application's usual development server and open an existing page. Add this markup inside its `ion-content` (use your framework's component syntax):
|
|
58
|
+
|
|
59
|
+
```html
|
|
60
|
+
<ion-list inset="true">
|
|
61
|
+
<ion-item-group>
|
|
62
|
+
<ion-item><ion-label>Notifications</ion-label></ion-item>
|
|
63
|
+
<ion-item><ion-label>Appearance</ion-label></ion-item>
|
|
64
|
+
</ion-item-group>
|
|
65
|
+
</ion-list>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
You should see an inset group with rounded edges. Switch the system between light and dark appearance, then navigate between pages to see the theme transition. Read [Using ion-item-group](using-ion-item-group.md) for list structure.
|
|
69
|
+
|
|
70
|
+
| If you see… | Check… |
|
|
71
|
+
| ----------------------------------- | ------------------------------------------------------------- |
|
|
72
|
+
| Material Design controls on desktop | Set `mode: 'ios'` in the existing Ionic initializer. |
|
|
73
|
+
| Unstyled controls | Load the theme stylesheet globally after Ionic's base styles. |
|
|
74
|
+
| Mixed light and dark surfaces | Use one matching Ionic palette and theme dark-mode variant. |
|
|
75
|
+
| Default page transitions | Pass the animation options before Ionic initializes. |
|
|
76
|
+
|
|
77
|
+
## Next steps
|
|
78
|
+
|
|
79
|
+
- [Customize styles and components](features.md).
|
|
80
|
+
- [Add Native UI](add-native-ui.md) for supported controls in a Capacitor iOS app. Theme installation alone does not enable native controls.
|
|
81
|
+
- [Add Vertical Bars with an existing theme](iphone-duo-with-original-theme.md).
|
|
82
|
+
- [Migrate an existing app](migration.md).
|
package/docs/special-markup.md
CHANGED
|
@@ -49,13 +49,13 @@ These classes do not reposition a separate `ion-fab`; leave room for it when cho
|
|
|
49
49
|
|
|
50
50
|
## Support iPhone Duo (preview)
|
|
51
51
|
|
|
52
|
-
iPhone Duo support, including standalone vertical bars, is available as a **preview** in `1.2.0` alongside Native UI
|
|
52
|
+
iPhone Duo support, including standalone vertical bars, is available as a **preview** in `1.2.0` alongside Native UI. Its APIs and supported behavior may change.
|
|
53
53
|
|
|
54
|
-
iPhone Duo support — the vertical system rail, hinge posture, and the posture-driven split-pane layout — is independent of the iOS 27 theme and the full Native UI
|
|
54
|
+
iPhone Duo support — the vertical system rail, hinge posture, and the posture-driven split-pane layout — is independent of the iOS 27 theme and the full Native UI. See [iPhone Duo support](https://github.com/rdlabo-dev/ionic-theme-ios27/blob/main/packages/theme-ios27/docs/iphone-duo.md) for the complete setup, including device-layout monitoring without a projection runtime.
|
|
55
55
|
|
|
56
|
-
See [Vertical Bars](https://
|
|
56
|
+
See [Vertical Bars](https://github.com/rdlabo-dev/ionic-theme-ios27/blob/main/packages/capacitor-native-ui/docs/vertical-bars.md) for rail layout classes, control eligibility and native button appearance.
|
|
57
57
|
|
|
58
|
-
For standalone setup while keeping your existing theme, see [iPhone Duo with your existing theme](https://
|
|
58
|
+
For standalone setup while keeping your existing theme, see [iPhone Duo with your existing theme](https://github.com/rdlabo-dev/ionic-theme-ios27/blob/main/packages/theme-ios27/docs/iphone-duo-with-original-theme.md).
|
|
59
59
|
|
|
60
60
|
## Two-line inset list items
|
|
61
61
|
|
|
@@ -178,4 +178,4 @@ Add `.ios-theme-disabled` to an individual Ionic component when it must retain I
|
|
|
178
178
|
<ion-button>iOS 27 theme</ion-button> <ion-button class="ios-theme-disabled">Standard Ionic button</ion-button>
|
|
179
179
|
```
|
|
180
180
|
|
|
181
|
-
For the background model behind inset lists, see [Using `ion-item-group`](
|
|
181
|
+
For the background model behind inset lists, see [Using `ion-item-group`](using-ion-item-group.md).
|
|
@@ -20,7 +20,7 @@ The examples use framework-neutral Web Component markup. In React or Vue, use th
|
|
|
20
20
|
|
|
21
21
|
No wrapper is required for lists that do not use `inset="true"`.
|
|
22
22
|
|
|
23
|
-
[Check list structure with ESLint](
|
|
23
|
+
[Check list structure with ESLint](eslint.md).
|
|
24
24
|
|
|
25
25
|
## Why the wrapper is required
|
|
26
26
|
|
|
@@ -44,4 +44,4 @@ When an application uses this package without `@rdlabo/ionic-theme-md3`, import
|
|
|
44
44
|
@import '@rdlabo/ionic-theme-ios27/dist/css/md-ion-list-inset.css';
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
For two-line items and section-header groups, see [Special markup and classes](
|
|
47
|
+
For two-line items and section-header groups, see [Special markup and classes](special-markup.md).
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Vertical Bars layout
|
|
2
|
+
|
|
3
|
+
This optional theme stylesheet owns Web spacing and positioning around a vertical rail. It can be used with your existing theme without loading the full iOS 27 appearance. Native rendering and state synchronization are provided separately by [Capacitor Native UI](https://github.com/rdlabo-dev/ionic-theme-ios27/blob/main/packages/capacitor-native-ui/docs/vertical-bars.md).
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npm install @rdlabo/ionic-theme-ios27
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```scss
|
|
10
|
+
@use '@rdlabo/ionic-theme-ios27/dist/css/vertical-bars.css';
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The layout behavior below assumes this stylesheet is loaded. For native runtime setup and device placement, follow the [integration guide](https://github.com/rdlabo-dev/ionic-theme-ios27/blob/main/packages/theme-ios27/docs/iphone-duo-with-original-theme.md).
|
|
14
|
+
|
|
15
|
+
## Reserve the vertical rail
|
|
16
|
+
|
|
17
|
+
Add `.ios-theme-vertical-bars` to `ion-app` to reserve the rail region on the physical right, or add `.ios-theme-vertical-bars-left` as well to use the physical left:
|
|
18
|
+
|
|
19
|
+
```html
|
|
20
|
+
<ion-app class="ios-theme-vertical-bars">...</ion-app>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The classes are physical — `-left` always means the physical left edge — because CSS and the native renderer work in physical coordinates. `setVerticalBarsLayout` applies the logical `verticalBarEdge` reported by the device plugin and resolves it through the document's direction, so an RTL app does not need its own conversion.
|
|
24
|
+
|
|
25
|
+
For Chrome development, no native plugin is needed — the class alone reserves `80px` to simulate iPhone Duo. When `setVerticalBarsLayout` receives `{ edge, inset }`, the inset replaces the fallback width, even when it is less than `80px`. Override `--ios-theme-vertical-bars-safe-area-left` or `--ios-theme-vertical-bars-safe-area-right` when simulating a different layout.
|
|
26
|
+
|
|
27
|
+
This keeps routers and component backgrounds full-viewport. `ion-content` moves its scroll foreground, `ion-toolbar` moves its container foreground, and `ion-fab` adjusts only when placed beside the system UI. The corresponding Ionic safe-area variable is reset inside those foreground components so descendants do not add the inset again.
|
|
28
|
+
|
|
29
|
+
`ion-modal` applies the same foreground correction when its visible dialog spans the viewport width. With the Vertical Control Area runtime enabled, the topmost full-width modal also projects eligible toolbar buttons into its own rail; centered dialogs keep their toolbar buttons and receive no page-rail inset. This includes full-width sheet modals: their rail follows the visible sheet bounds as the breakpoint changes. Eligibility follows the visible dialog width, not the hinge posture or modal type. `ion-menu` and `ion-popover` are handled as separate surfaces: their internal foreground components do not receive the main-page conversion and retain Ionic's standard safe-area handling. A menu presented beside the system UI keeps Ionic's full-viewport animation host and offsets only its visible container by the corresponding inset; a menu from the opposite side is unchanged. Left and right remain physical coordinates in RTL, while Ionic's `side="start"` and `side="end"` values remain logical.
|
|
30
|
+
|
|
31
|
+
The mode is component-mode independent: an app can keep Ionic `mode: 'md'` on iOS and still enable Vertical Bars. No component needs `mode="ios"`.
|
|
32
|
+
|
|
33
|
+
## Layout API
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { setVerticalBarsLayout } from '@rdlabo/ionic-theme-ios27';
|
|
37
|
+
|
|
38
|
+
setVerticalBarsLayout({ edge: 'trailing', inset: 80 });
|
|
39
|
+
// Optionally supply a root element and explicit RTL boolean as the next arguments.
|
|
40
|
+
setVerticalBarsLayout({ edge: null }); // restore ordinary Web layout
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The helper operates on Web CSS only and work without Capacitor or Native UI startup. The application supplies device state and owns subscriptions. Starting, disabling or destroying Native UI does not change these layout classes or the reserved inset. Unsupported native rails retain the chosen Web rail; choose `edge: null` explicitly if the application wants a horizontal layout instead.
|
|
44
|
+
|
|
45
|
+
## Migration
|
|
46
|
+
|
|
47
|
+
Move `setVerticalControlAreaPlacement` calls from the plugin to `setVerticalBarsLayout({ edge, inset })` from the theme. Move `applyFoldStateClasses` imports to the theme too. Remove `nativeEdge`: it no longer reports availability. The old plugin helpers are deprecated; update existing imports using the [migration guide](../../capacitor-native-ui/docs/migration.md#web-layout-ownership).
|