@rdlabo/capacitor-native-ui 1.2.1 → 2.0.0-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -25
- package/dist/core.d.ts +2 -2
- package/dist/native/activation.d.ts.map +1 -1
- package/dist/native/activation.js +19 -19
- package/dist/native/activation.js.map +1 -1
- package/dist/native/definitions.d.ts +22 -40
- package/dist/native/definitions.d.ts.map +1 -1
- package/dist/native/html.d.ts.map +1 -1
- package/dist/native/html.js +10 -1
- package/dist/native/html.js.map +1 -1
- package/dist/native/index.d.ts +2 -2
- package/dist/native/index.d.ts.map +1 -1
- package/dist/native/index.js +2 -11
- package/dist/native/index.js.map +1 -1
- package/dist/native/overlays/controller.js +1 -1
- package/dist/native/overlays/controller.js.map +1 -1
- package/dist/native/prehide.js +1 -1
- package/dist/native/prehide.js.map +1 -1
- package/dist/native/runtime.d.ts +1 -1
- package/dist/native/runtime.d.ts.map +1 -1
- package/dist/native/runtime.js +8 -20
- package/dist/native/runtime.js.map +1 -1
- package/dist/native/shared/candidate.d.ts +2 -2
- package/dist/native/shared/candidate.d.ts.map +1 -1
- package/dist/native/shared/candidate.js +2 -2
- package/dist/native/shared/candidate.js.map +1 -1
- package/dist/native/shared/control-options.d.ts +6 -0
- package/dist/native/shared/control-options.d.ts.map +1 -0
- package/dist/native/shared/control-options.js +17 -0
- package/dist/native/shared/control-options.js.map +1 -0
- package/dist/native/shared/toolbar-options.d.ts +6 -2
- package/dist/native/shared/toolbar-options.d.ts.map +1 -1
- package/dist/native/shared/toolbar-options.js +7 -15
- package/dist/native/shared/toolbar-options.js.map +1 -1
- package/dist/native/startup.d.ts.map +1 -1
- package/dist/native/startup.js +0 -16
- package/dist/native/startup.js.map +1 -1
- package/dist/native/vertical-bars-web.d.ts.map +1 -1
- package/dist/native/vertical-bars-web.js +3 -2
- package/dist/native/vertical-bars-web.js.map +1 -1
- package/dist/vertical-bars.d.ts +2 -2
- package/docs/appearance.md +45 -0
- package/docs/configuration.md +106 -74
- package/docs/framework-independent.md +35 -10
- package/docs/ionic-vertical-bars.md +173 -0
- package/docs/migration.md +65 -87
- package/docs/native-ui-extensions.md +60 -31
- package/docs/native-ui.md +186 -67
- package/docs/setup.md +43 -24
- package/docs/vertical-bars.md +124 -72
- package/ios/Sources/NativeUIPlugin/NativeUIPlugin.swift +1 -1
- package/package.json +1 -1
- package/src/core.ts +1 -2
- package/src/native/activation.ts +13 -22
- package/src/native/definitions.ts +40 -90
- package/src/native/html.ts +11 -5
- package/src/native/index.ts +2 -11
- package/src/native/overlays/controller.ts +1 -1
- package/src/native/prehide.ts +1 -1
- package/src/native/runtime.ts +7 -16
- package/src/native/shared/candidate.ts +4 -4
- package/src/native/shared/control-options.ts +20 -0
- package/src/native/shared/toolbar-options.ts +8 -12
- package/src/native/startup.ts +0 -16
- package/src/native/vertical-bars-web.ts +4 -2
- package/src/vertical-bars.ts +2 -1
- package/docs/native-mini-player.md +0 -47
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
# Native UI without Ionic
|
|
2
2
|
|
|
3
|
-
> This guide targets the upcoming package split. Until the first native package release, use the [candidate archive installation](../README.md#try-the-unreleased-packages) in place of registry install commands.
|
|
4
|
-
|
|
5
3
|
Add native buttons to an existing Web app without Ionic or theme CSS. Keep labels, state, and click handlers on ordinary HTML elements. Standard buttons require no custom Swift registration.
|
|
6
4
|
|
|
7
5
|
Use a Capacitor 8 app with an iOS project, Xcode 26+, and an iOS 26+ device or simulator. Browsers and Android retain Web controls. For custom Android native content, use [Kotlin/Compose extensions](native-ui-extensions.md#2b-register-compose-content-on-android).
|
|
8
6
|
|
|
7
|
+
Start with [how projection works](../README.md#how-projection-works): the HTML element remains the source while native controls or Web proxies provide its presentation.
|
|
8
|
+
|
|
9
|
+
**Want only Vertical Bars?** Follow steps 1–2 to install and mark your HTML buttons, then use the [Web rail configuration](#optional-web-rail) in place of step 3. Remove explicit markers from buttons you want to leave on the Web. Style the rail host in your application and build with step 4 for iOS. You do not need Ionic, `@rdlabo/ionic-theme-ios27`, or `vertical-bars.css`.
|
|
10
|
+
|
|
11
|
+
For Vertical Bars in an app using `ion-tabs`, `ion-toolbar` or other Ionic components with a custom theme, use the [Ionic Vertical Bars setup](ionic-vertical-bars.md#try-it-in-your-existing-ionic-app) instead. The framework (Angular, React or Vue) alone does not determine which adapter to use.
|
|
12
|
+
|
|
9
13
|
## 1. Install the plugin
|
|
10
14
|
|
|
11
15
|
Keep your existing Capacitor 8 installation and add the plugin directly:
|
|
@@ -26,12 +30,25 @@ The `/core` entry requires `@capacitor/core` but no Ionic dependencies. If this
|
|
|
26
30
|
<aside id="rail" aria-label="Navigation"></aside>
|
|
27
31
|
```
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
-
|
|
33
|
+
| Attribute | Value | Effect |
|
|
34
|
+
| -------------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
35
|
+
| `data-native-ui` | `button` | Project a standard action button. |
|
|
36
|
+
| `data-native-ui` | `back-button` | Project a standard back button. The source click handler owns navigation; the plugin never calls `history.back()`. |
|
|
37
|
+
| `data-native-ui` | `disabled` | Exclude the element and its subtree from projection. |
|
|
38
|
+
| `data-native-ui-placement` | `element` (default) | Use the source element's rectangle. |
|
|
39
|
+
| `data-native-ui-placement` | `rail` | Request Vertical Bars; use the optional Web rail host when native rail presentation is unavailable. |
|
|
40
|
+
|
|
41
|
+
Apply `button` and `back-button` to `<button>`, explicitly marked `ion-button`, or elements exposing `role="button"` and click behavior. Unmarked HTML is never inferred to be a control. `data-native-ui-placement` chooses placement for a declared source; it does not opt an unmarked HTML element into projection.
|
|
42
|
+
|
|
43
|
+
Keep the control's data and behavior on its source:
|
|
33
44
|
|
|
34
|
-
|
|
45
|
+
| Source property | Projection behavior |
|
|
46
|
+
| -------------------- | ------------------------------------------------------------------------------------------ |
|
|
47
|
+
| Accessible name | Resolves from `aria-labelledby`, then `aria-label`, then text. |
|
|
48
|
+
| Artwork | Uses supported static SVG. |
|
|
49
|
+
| Disabled state | Respects native `disabled`, a disabled fieldset, and `aria-disabled="true"`. |
|
|
50
|
+
| Visibility and scope | Hidden, removed, excluded or out-of-scope sources are retired; stale actions are rejected. |
|
|
51
|
+
| Application handlers | Remain on the original element. |
|
|
35
52
|
|
|
36
53
|
Native and Web-proxy actions click the original element. An ordinary `<button type="submit">` therefore keeps its original form behavior. Use `type="button"` for actions that must not submit. The native bridge does not preserve browser user-activation privileges for APIs such as popup opening.
|
|
37
54
|
|
|
@@ -47,9 +64,13 @@ const shell = await enableNativeUI({
|
|
|
47
64
|
|
|
48
65
|
Call once after the source root exists. Keep the handle and call `await shell.destroy()` when that root is disposed. The plugin does not add page padding or safe-area rules; retain your application's CSS. For Angular, React, or Vue, use the [app-root lifecycle examples](setup.md#place-startup-in-your-frameworks-app-root) with the `/core` import. For animated navigation, use [suspension through completion and cancellation](setup.md#navigation-without-the-theme).
|
|
49
66
|
|
|
67
|
+
### Match the HTML theme
|
|
68
|
+
|
|
69
|
+
For a custom HTML theme, declare `color-scheme: light` or `color-scheme: dark` in the same CSS that selects your Web palette. Background colors alone do not select native appearance. See [Light and dark appearance](appearance.md) for a manual-toggle example, precedence when Ionic/theme variables are present, and shared rail behavior.
|
|
70
|
+
|
|
50
71
|
## 4. Build and run on iOS
|
|
51
72
|
|
|
52
|
-
Build your Web app, run `npx cap sync ios`, and launch the iOS project from Xcode.
|
|
73
|
+
Build your Web app, run `npx cap sync ios`, and launch the iOS project from Xcode. With the step 3 configuration, Add renders natively and invokes its original click handler. With the rail configuration below, Add retains native element placement and Back uses the native rail when available. In a browser, the same button remains an ordinary Web button. Unmarked HTML remains unchanged.
|
|
53
74
|
|
|
54
75
|
If a button stays on the Web on supported iOS, check that it is visible within the configured root, has an accessible name, and that the direct plugin dependency was synced and the iOS app rebuilt.
|
|
55
76
|
|
|
@@ -57,9 +78,11 @@ In an app that also uses Ionic, set `ionic: { auto: false }` to project only exp
|
|
|
57
78
|
|
|
58
79
|
## Optional Web rail
|
|
59
80
|
|
|
60
|
-
|
|
81
|
+
For a Web fallback rail, use this instead of the startup call in step 3. Call once after both the source root and rail host are mounted; call `await shell.destroy()` when their owner is disposed. Do not start a second shell:
|
|
61
82
|
|
|
62
83
|
```ts
|
|
84
|
+
import { enableNativeUI } from '@rdlabo/capacitor-native-ui/core';
|
|
85
|
+
|
|
63
86
|
const shell = await enableNativeUI({
|
|
64
87
|
root: document.querySelector<HTMLElement>('#app')!,
|
|
65
88
|
verticalBars: {
|
|
@@ -73,10 +96,12 @@ const shell = await enableNativeUI({
|
|
|
73
96
|
|
|
74
97
|
The plugin uses device-reported rail availability and resolves leading/trailing through the document direction. A placement preference never forces an unsupported system rail. Native rejection restores Web presentation. With `webHost`, explicitly rail-marked HTML controls have Web proxies when native projection is unavailable. Without it, their originals remain visible. The application styles and positions the host and reserves any content spacing. The host must be outside the source root.
|
|
75
98
|
|
|
76
|
-
To
|
|
99
|
+
Explicit markup chooses placement: Back goes to the rail and Add keeps native element placement. To project only Back, remove `data-native-ui="button"` from Add. `controls` does not disable explicit source declarations. To change rail use later, call `await shell.disableVerticalControlArea()` or `await shell.enableVerticalControlArea()`. Disabling restores original rail controls and removes Web rail proxies without destroying ordinary native projection.
|
|
77
100
|
|
|
78
101
|
Currently the HTML adapter supports buttons and back buttons. Arbitrary HTML tabs, segments, searchbars and FAB structures are not translated. Ionic adapters continue to support their existing controls. Custom element extensions work with the same scoped root; the existing `tab-accessory` extension placement still requires an Ionic tab-bar owner.
|
|
79
102
|
|
|
103
|
+
For device-driven spacing and placement, see [Use with Capacitor Foldable](vertical-bars.md#use-with-capacitor-foldable). Read its initial placement and subscribe to changes, applying the edge and inset to your own CSS; the theme package is not required.
|
|
104
|
+
|
|
80
105
|
## Example
|
|
81
106
|
|
|
82
107
|
The [plain HTML example](https://github.com/rdlabo-dev/ionic-theme-ios27/tree/main/examples/native-ui-html) demonstrates Add, routerless Home/Details/Back navigation, optional Web rail projection and cleanup. It uses no Ionic or theme CSS.
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Add Vertical Bars while keeping your theme
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Add Vertical Bars while keeping your theme
|
|
6
|
+
|
|
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
|
+
|
|
9
|
+
Read [how projection works](../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](framework-independent.md), then its [Web rail configuration](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](../../theme-ios27/docs/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 `@rdlabo/ionic-theme-ios27`, `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.
|
|
22
|
+
|
|
23
|
+
iPhone Duo support and Vertical Bars are stable starting with version 2.0.0.
|
|
24
|
+
|
|
25
|
+
## Try it in your existing Ionic app
|
|
26
|
+
|
|
27
|
+
### 1. Install and load the standalone stylesheet
|
|
28
|
+
|
|
29
|
+
Start with your existing Ionic app (Ionic `>=8.8.1 <10`, Capacitor 8). Add the two packages:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install @rdlabo/ionic-theme-ios27 @rdlabo/capacitor-native-ui
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Keep your existing theme imports. Add this to your global Sass file:
|
|
36
|
+
|
|
37
|
+
```scss
|
|
38
|
+
@use '@rdlabo/ionic-theme-ios27/dist/css/vertical-bars.css';
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The full iOS 27 theme stylesheets are not required. Preview these steps in Chrome before connecting an iPhone Duo.
|
|
42
|
+
|
|
43
|
+
### 2. Opt your app into the side layout
|
|
44
|
+
|
|
45
|
+
Add the class to your existing app root and keep the content inside it:
|
|
46
|
+
|
|
47
|
+
```html
|
|
48
|
+
<ion-app class="ios-theme-vertical-bars">
|
|
49
|
+
<!-- Keep your existing pages, tabs, and toolbar controls here. -->
|
|
50
|
+
</ion-app>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The preview reserves `80px` on the physical right. To preview the left side, also add `ios-theme-vertical-bars-left`.
|
|
54
|
+
|
|
55
|
+
### 3. Connect your navigation animation
|
|
56
|
+
|
|
57
|
+
Configure `navAnimation` before Ionic initializes. Starting the rail runtime does not register this option. The adapter waits for native control retirement and coordinates swipe progress and cancellation while keeping your existing animation.
|
|
58
|
+
|
|
59
|
+
#### Keep Ionic's default animation
|
|
60
|
+
|
|
61
|
+
If you have not configured `navAnimation`, wrap Ionic's standard builders. Select the builder from Ionic's transition `mode` so both `ios` and `md` keep their usual animation:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import { iosTransitionAnimation, mdTransitionAnimation, type AnimationBuilder } from '@ionic/core';
|
|
65
|
+
import { withNativeUITransition } from '@rdlabo/ionic-theme-ios27';
|
|
66
|
+
|
|
67
|
+
const defaultTransition: AnimationBuilder = (baseEl, opts) =>
|
|
68
|
+
(opts.mode === 'ios' ? iosTransitionAnimation : mdTransitionAnimation)(baseEl, opts);
|
|
69
|
+
|
|
70
|
+
const ionicConfig = {
|
|
71
|
+
navAnimation: withNativeUITransition(defaultTransition),
|
|
72
|
+
};
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Merge this option into your existing Ionic configuration before initialization: pass it to Angular's `provideIonicAngular()`, React's `setupIonicReact()`, or Vue's `IonicVue` plugin options. Keep your existing theme stylesheet imports. No iOS 27 theme stylesheet is required.
|
|
76
|
+
|
|
77
|
+
#### Use the theme's iOS animation
|
|
78
|
+
|
|
79
|
+
If you already use the iOS 27 transition, keep this configuration. It includes the native adapter and excludes the horizontal back-button effect in vertical layouts; no additional wrapper is needed. Importing this JavaScript entry point does not load the theme stylesheets.
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
import { iosTransitionAnimation } from '@rdlabo/ionic-theme-ios27';
|
|
83
|
+
|
|
84
|
+
const ionicConfig = {
|
|
85
|
+
navAnimation: iosTransitionAnimation,
|
|
86
|
+
};
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Apply this option to your existing iOS-mode configuration and keep your MD configuration.
|
|
90
|
+
|
|
91
|
+
#### Keep your custom animation
|
|
92
|
+
|
|
93
|
+
If your app uses another builder for `navAnimation`, wrap it:
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import type { AnimationBuilder } from '@ionic/core';
|
|
97
|
+
import { withNativeUITransition } from '@rdlabo/ionic-theme-ios27';
|
|
98
|
+
|
|
99
|
+
// Pass the animation builder your app already uses.
|
|
100
|
+
const configureNavigation = (existingTransition: AnimationBuilder) => ({
|
|
101
|
+
navAnimation: withNativeUITransition(existingTransition),
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The adapter returns the original `Animation`, preserving its effects, duration, and easing. Use it only for navigation, not modal or popover animations. The builder must return a fresh `Animation` for each navigation; Ionic destroys it after the transition. Keep lifecycle events for control registration and transitions without animation.
|
|
106
|
+
|
|
107
|
+
The adapter keeps the builder's animation targets, including any horizontal back-button effect. If you need the iOS 27 transition with that effect excluded in vertical layouts, use `iosTransitionAnimation` from `@rdlabo/ionic-theme-ios27` as your `navAnimation` instead. It already includes the adapter, so no wrapper is needed.
|
|
108
|
+
|
|
109
|
+
### 4. Start the controls after the app root is mounted
|
|
110
|
+
|
|
111
|
+
Call this once from your application startup after `ion-app` exists in the DOM:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
import { enableNativeUI } from '@rdlabo/capacitor-native-ui';
|
|
115
|
+
|
|
116
|
+
const rail = await enableNativeUI({ controls: 'verticalOnly' });
|
|
117
|
+
```
|
|
118
|
+
|
|
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.
|
|
120
|
+
|
|
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.
|
|
122
|
+
|
|
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](../../theme-ios27/docs/iphone-duo.md#project-controls-into-the-rail).
|
|
124
|
+
|
|
125
|
+
### Optional: choose native button appearance
|
|
126
|
+
|
|
127
|
+
See [Choose button appearance](vertical-bars.md#choose-button-appearance) for appearance settings and local overrides.
|
|
128
|
+
|
|
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:
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
const rail = await enableNativeUI({
|
|
133
|
+
controls: 'verticalOnly',
|
|
134
|
+
ionic: { verticalBars: { buttonProjection: 'source', buttonDefaultFill: 'solid' } },
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
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](vertical-bars.md#override-individual-buttons-or-groups). These settings affect native vertical buttons only; Web clones keep their existing appearance.
|
|
139
|
+
|
|
140
|
+
### If the preview does not appear
|
|
141
|
+
|
|
142
|
+
| What you see | What to check |
|
|
143
|
+
| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
144
|
+
| No space at the side | Load `vertical-bars.css` and put the class on `ion-app`. |
|
|
145
|
+
| Space appears, but controls stay horizontal | Start `enableNativeUI({ controls: 'verticalOnly' })` after mounting the app root. Use existing tabs or `slot="icon-only"` actions in a fixed header/footer toolbar. |
|
|
146
|
+
| 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](vertical-bars.md#toolbar-actions). |
|
|
147
|
+
|
|
148
|
+
## Connect an iPhone Duo
|
|
149
|
+
|
|
150
|
+
Install [`@erkamyaman/capacitor-foldable`](https://github.com/erkamyaman/capacitor-foldable) for device state:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
npm install @erkamyaman/capacitor-foldable
|
|
154
|
+
npx cap sync ios
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
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](setup.md#4-build-sync-and-run). Keep the theme's `vertical-bars.css`; the device plugin's `ionic-tabs.css` is not needed with our rail projection.
|
|
158
|
+
|
|
159
|
+
Replace the browser-only startup with the [device placement setup](../../theme-ios27/docs/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.
|
|
160
|
+
|
|
161
|
+
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.
|
|
162
|
+
|
|
163
|
+
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.
|
|
164
|
+
|
|
165
|
+
## Use hinge posture without projecting controls
|
|
166
|
+
|
|
167
|
+
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.
|
|
168
|
+
|
|
169
|
+
See [Read the device layout](../../theme-ios27/docs/iphone-duo.md#read-the-device-layout) for the subscription example, null values, and monitoring lifetime. See [Adapt the split pane](../../theme-ios27/docs/iphone-duo.md#adapt-the-split-pane) for the opt-in width rules and half-open state.
|
|
170
|
+
|
|
171
|
+
## Shared layout rules and API
|
|
172
|
+
|
|
173
|
+
Safe-area handling, overlays, RTL, control eligibility, Web simulation, and the handle API are documented in [Vertical Bars](vertical-bars.md). Read that reference when you need to customize this setup; it is not an additional installation step.
|
package/docs/migration.md
CHANGED
|
@@ -4,18 +4,14 @@ title: Migration
|
|
|
4
4
|
|
|
5
5
|
# Migration
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Upgrading from 1.2.1
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
This guide is for applications using `@rdlabo/ionic-theme-ios27` **1.2.1**, including its Native UI Shell Preview and standalone Vertical Control Area.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
- **Theme only:** update the theme package. Existing theme imports, CSS/Sass paths and animation imports remain valid; no native startup is needed.
|
|
12
|
+
- **Native UI or Vertical Control Area:** install the native package directly, replace imports and startup settings below, then sync Capacitor and rebuild the native app.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
2. Apply the [API and native naming changes](#native-ui-naming-changes), then translate startup settings using [shared shell configuration](#shared-shell-configuration-and-html-adapters), especially partial `controls` objects.
|
|
15
|
-
3. Update [Web layout ownership](#web-layout-ownership) and the [transition adapter](#native-ui-transition-adapter) if used.
|
|
16
|
-
4. Rebuild Web assets, sync Capacitor, and rebuild the native app. A Web-only update cannot replace the native plugin.
|
|
17
|
-
|
|
18
|
-
Native UI remains Preview. App-local SwiftUI / Compose **extensions are experimental**, including their TypeScript definitions, native registration APIs and placement behavior. The `defineNativeUI` and `extensions` names stay unchanged; native registration names change as listed below. Applications using extensions should keep their Web fallback and verify their reader, native renderer and action forwarding together after updates. See the [extension guide](native-ui-extensions.md).
|
|
14
|
+
Native UI remains Preview. Experimental Extensions are documented in the [current extension guide](native-ui-extensions.md); this guide covers the published 1.2.1 controls and setup.
|
|
19
15
|
|
|
20
16
|
## Native UI package separation
|
|
21
17
|
|
|
@@ -23,11 +19,11 @@ For a new native integration, follow [Native UI setup](setup.md) or, if you alre
|
|
|
23
19
|
|
|
24
20
|
The theme and native controls now live in separate packages. Choose dependencies by the behavior your app uses:
|
|
25
21
|
|
|
26
|
-
| App behavior
|
|
27
|
-
|
|
|
28
|
-
| Theme styles, Ionic Web behavior, and theme animations | `@rdlabo/ionic-theme-ios27`
|
|
29
|
-
| Native UI or standalone Vertical Control Area
|
|
30
|
-
| Theme styling together with native controls
|
|
22
|
+
| App behavior | Package to use directly |
|
|
23
|
+
| ------------------------------------------------------ | ----------------------------- |
|
|
24
|
+
| Theme styles, Ionic Web behavior, and theme animations | `@rdlabo/ionic-theme-ios27` |
|
|
25
|
+
| Native UI or standalone Vertical Control Area | `@rdlabo/capacitor-native-ui` |
|
|
26
|
+
| Theme styling together with native controls | Both packages |
|
|
31
27
|
|
|
32
28
|
The theme owns the appearance and behavior of Ionic's Web elements. Native UI owns projecting supported controls into native iOS views and coordinating their lifecycle with Web navigation. Native UI can be used without the iOS 27 theme; installing it does not apply theme styles. Standard controls on Android and browsers retain Web presentation; Android can render [app-local Compose extensions](native-ui-extensions.md#2b-register-compose-content-on-android).
|
|
33
29
|
|
|
@@ -35,7 +31,7 @@ The theme uses the native package's shared transition/search integration interna
|
|
|
35
31
|
|
|
36
32
|
### 1. Update application dependencies
|
|
37
33
|
|
|
38
|
-
|
|
34
|
+
When using both packages, update them together to keep their versions aligned.
|
|
39
35
|
|
|
40
36
|
For theme-only apps, update the theme package. Keep existing theme imports and CSS/Sass paths; no native startup or plugin setup is needed for theme-only use.
|
|
41
37
|
|
|
@@ -51,22 +47,12 @@ npm install @rdlabo/ionic-theme-ios27 @rdlabo/capacitor-native-ui
|
|
|
51
47
|
|
|
52
48
|
For native controls with your existing Web appearance, follow [Native UI only](setup.md). Install the native package directly and keep your existing Web styles. The plugin no longer requires theme variables to select supported controls; Web layout remains the responsibility of your app or theme. Native startup requires Capacitor 8. The Ionic adapter requires Ionic 8.8.1 or later within Ionic 8 or 9; the `/core` entry does not require Ionic.
|
|
53
49
|
|
|
54
|
-
If you used the intermediate `@ionic-theme/capacitor-native-ui` package name during development, remove it and install `@rdlabo/capacitor-native-ui`. Keep the theme dependency if your app uses its styles or APIs.
|
|
55
|
-
|
|
56
|
-
```sh
|
|
57
|
-
npm uninstall @ionic-theme/capacitor-native-ui
|
|
58
|
-
npm install @rdlabo/capacitor-native-ui
|
|
59
|
-
```
|
|
60
|
-
|
|
61
50
|
### 2. Replace native imports
|
|
62
51
|
|
|
63
|
-
| Previous import
|
|
64
|
-
|
|
|
65
|
-
| `@rdlabo/ionic-theme-ios27/native`
|
|
52
|
+
| Previous import | Replacement |
|
|
53
|
+
| ----------------------------------------- | ------------------------------------------- |
|
|
54
|
+
| `@rdlabo/ionic-theme-ios27/native` | `@rdlabo/capacitor-native-ui` |
|
|
66
55
|
| `@rdlabo/ionic-theme-ios27/vertical-bars` | `@rdlabo/capacitor-native-ui/vertical-bars` |
|
|
67
|
-
| `@ionic-theme/capacitor-native-ui` | `@rdlabo/capacitor-native-ui` |
|
|
68
|
-
| `@ionic-theme/capacitor-native-ui/vertical-bars` | `@rdlabo/capacitor-native-ui/vertical-bars` |
|
|
69
|
-
| `@ionic-theme/capacitor-native-ui/integration` | `@rdlabo/capacitor-native-ui/integration` |
|
|
70
56
|
|
|
71
57
|
Update both value and type imports, including lazy imports, test aliases, and bundler configuration. The old theme `/native` and `/vertical-bars` entries have been removed; there are no compatibility aliases.
|
|
72
58
|
|
|
@@ -75,7 +61,7 @@ Update both value and type imports, including lazy imports, test aliases, and bu
|
|
|
75
61
|
+ import { enableNativeUI } from '@rdlabo/capacitor-native-ui';
|
|
76
62
|
```
|
|
77
63
|
|
|
78
|
-
Keep existing control markup; review the [startup option changes](#
|
|
64
|
+
Keep existing control markup; review the [startup option changes](#startup-options), including partial `controls` defaults. The ordinary `@rdlabo/ionic-theme-ios27` entry, theme CSS/Sass paths, and theme animation imports stay unchanged. For custom navigation animations, see the [transition adapter instructions](#native-ui-transition-adapter) below.
|
|
79
65
|
|
|
80
66
|
### 3. Sync the native project
|
|
81
67
|
|
|
@@ -87,45 +73,40 @@ npx cap sync ios
|
|
|
87
73
|
|
|
88
74
|
The Capacitor plugin is now supplied by the native package. Remove manually linked copies of the old theme Swift package so only the new package supplies the plugin. The Swift package/product and CocoaPods pod are now `RdlaboCapacitorNativeUi`; the Swift module is `NativeUIPlugin`. The Capacitor bridge name is now `NativeUI` on JavaScript, iOS and Android. Run Capacitor sync for each native platform you use and rebuild the native app. An OTA/Web-only update cannot migrate an installed binary containing only the old plugin. Use matching JavaScript and native package versions.
|
|
89
75
|
|
|
90
|
-
|
|
76
|
+
Use Capacitor's generated integration for the npm dependency; applications do not need a checkout of this repository or a manually linked Swift package.
|
|
91
77
|
|
|
92
78
|
### 4. Verify the migration
|
|
93
79
|
|
|
94
|
-
- Check
|
|
95
|
-
- Build
|
|
96
|
-
- Build and launch the iOS app after sync. Check native controls, navigation/back gestures, and any app-local Swift extensions you use.
|
|
80
|
+
- Check that native-enabled apps declare `@rdlabo/capacitor-native-ui` directly, then build and confirm no imports of the removed theme entries remain.
|
|
81
|
+
- Build and launch the iOS app after sync. Check native controls, navigation/back gestures, and restored Web controls after teardown.
|
|
97
82
|
- Check browser and Android Web presentation where supported by your app, and confirm the theme still looks correct.
|
|
98
83
|
- Check that previously disabled control kinds remain disabled after expanding partial Preview settings. Test toolbar grouping, individually selected actions and back navigation in both horizontal and vertical layouts.
|
|
99
|
-
- For experimental extensions, check native registration, props, click forwarding and restoration of the original Web UI when projection is unavailable. Rebuild and sync Android as well if the app uses Compose extensions.
|
|
100
84
|
|
|
101
85
|
## Native UI naming changes
|
|
102
86
|
|
|
103
|
-
The split package uses Native UI names throughout. These are breaking renames; the old names are not aliases. The
|
|
87
|
+
The split package uses Native UI names throughout. These are breaking renames; the old names are not aliases. The previous names below refer to the published 1.2.1 Preview.
|
|
104
88
|
|
|
105
|
-
| Previous name
|
|
106
|
-
|
|
|
107
|
-
| `enableNativeUIShell()`
|
|
89
|
+
| Previous name | New name |
|
|
90
|
+
| -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
91
|
+
| `enableNativeUIShell()` | `enableNativeUI()` |
|
|
108
92
|
| `NativeUIShellOptions`, `NativeUIShellHandle`, `NativeUIShellStatus`, `NativeUIShellSuspension`, `NativeUIShellControls`, `NativeUIShellComponent` | `NativeUIOptions`, `NativeUIHandle`, `NativeUIStatus`, `NativeUISuspension`, `NativeUIControls`, `NativeUIComponent` |
|
|
109
|
-
| `IonicNativeUIShell` (plugin export and bridge registration)
|
|
110
|
-
| `withNativeUIShellTransition()`
|
|
111
|
-
| `IonicNativeUIShellPlugin` (Swift module/native class)
|
|
112
|
-
| `
|
|
113
|
-
| `
|
|
114
|
-
|
|
|
115
|
-
| `.ios-theme-shell-disabled` | `.native-ui-disabled` |
|
|
116
|
-
|
|
117
|
-
Replace the `NativeUIShell` part with `NativeUI` in imports from `/integration` as well (for example `suspendNativeUI` and `setNativeUIIntegration`). App-local Swift extensions now use `import NativeUIPlugin`; Kotlin extensions use `import dev.rdlabo.capacitor.nativeui.NativeUI`.
|
|
93
|
+
| `IonicNativeUIShell` (plugin export and bridge registration) | `NativeUI` |
|
|
94
|
+
| `withNativeUIShellTransition()` | `withNativeUITransition()` (still exported by the theme package) |
|
|
95
|
+
| `IonicNativeUIShellPlugin` (Swift module/native class) | `NativeUIPlugin` |
|
|
96
|
+
| `RdlaboIonicThemeIos27` (SPM package/product) | `RdlaboCapacitorNativeUi` |
|
|
97
|
+
| `data-shell="disabled"` | `data-native-ui="disabled"` |
|
|
98
|
+
| `.ios-theme-shell-disabled` | `.native-ui-disabled` |
|
|
118
99
|
|
|
119
100
|
Runtime-owned attributes/events are internal, not configuration: `data-native-ui-shell` is now `data-native-ui-projected`, other `data-native-ui-shell-*` attributes use `data-native-ui-*`, `nativeUIShell*` events use `nativeUI*`, and `.ios-theme-native-ui-shell-*` classes use `.native-ui-*`. Update application tests or diagnostics that inspect them. **Keep explicit source declarations such as `data-native-ui="button"` unchanged**; the projected marker is separate and is managed by the runtime.
|
|
120
101
|
|
|
121
102
|
## Native UI transition adapter
|
|
122
103
|
|
|
123
|
-
The Ionic transition adapter now belongs to `@rdlabo/ionic-theme-ios27`. Replace
|
|
104
|
+
The Ionic transition adapter now belongs to `@rdlabo/ionic-theme-ios27`. Replace the 1.2.1 import of `withNativeUIShellTransition` from `@rdlabo/ionic-theme-ios27/vertical-bars` with `withNativeUITransition` from the theme root. Native-only applications can use `shell.suspend()` and the returned `resume()` directly.
|
|
124
105
|
|
|
125
106
|
Use `withNativeUITransition()` to keep your existing Ionic navigation animation while coordinating Native UI controls.
|
|
126
107
|
|
|
127
|
-
- If you already import `iosTransitionAnimation` from `@rdlabo/ionic-theme-ios27`, keep the [package animation setup](
|
|
128
|
-
- If you use Ionic's default animation without a `navAnimation` option, follow [Keep Ionic's default animation](
|
|
108
|
+
- If you already import `iosTransitionAnimation` from `@rdlabo/ionic-theme-ios27`, keep the [package animation setup](ionic-vertical-bars.md#use-the-themes-ios-animation); no configuration change is needed. It now uses the shared adapter internally; do not add another wrapper.
|
|
109
|
+
- If you use Ionic's default animation without a `navAnimation` option, follow [Keep Ionic's default animation](ionic-vertical-bars.md#keep-ionics-default-animation). The example selects Ionic's standard iOS or MD builder from the transition mode.
|
|
129
110
|
- If you use a custom navigation animation with Native UI or the standalone Vertical Control Area, wrap your existing builder when configuring Ionic:
|
|
130
111
|
|
|
131
112
|
```diff
|
|
@@ -141,66 +122,63 @@ Merge this option into your existing Ionic configuration before initialization.
|
|
|
141
122
|
|
|
142
123
|
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.
|
|
143
124
|
|
|
144
|
-
See [Connect your navigation animation](
|
|
125
|
+
See [Connect your navigation animation](ionic-vertical-bars.md#3-connect-your-navigation-animation) for the setup and supported scope.
|
|
145
126
|
|
|
146
|
-
##
|
|
127
|
+
## Startup options
|
|
147
128
|
|
|
148
|
-
|
|
129
|
+
In 1.2.1, providing `controls` enabled **only fields set to `true`**. In the new API, omitted fields default to `true`, even in a partial object. Expand your old selection when migrating.
|
|
149
130
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
131
|
+
| 1.2.1 | New configuration |
|
|
132
|
+
| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
133
|
+
| No `controls` | No `controls`: all supported kinds remain selected by default. |
|
|
134
|
+
| `controls: {}` | `controls: false` to disable default selection, or `ionic: { auto: false }` to disable Ionic discovery altogether. |
|
|
135
|
+
| `controls.toolbar` | Set `controls.buttonGroup`, `controls.button`, and `controls.backButton` to the old toolbar value. |
|
|
136
|
+
| `controls.tabs`, `.segment`, `.fab` | Same names, but explicitly use `false` for previously omitted fields. |
|
|
137
|
+
| `buttonProjection` | `ionic.verticalBars.buttonProjection` |
|
|
138
|
+
| `buttonDefaultFill: null` | `ionic.verticalBars.buttonDefaultFill: 'glass'` (also the default) |
|
|
139
|
+
| `buttonDefaultFill: 'solid'` | `ionic.verticalBars.buttonDefaultFill: 'solid'` |
|
|
140
|
+
| `verticalBarsOnly: true` | `controls: 'verticalOnly'` for default selection in the rail. For a partial selection, use `'verticalOnly'` on each enabled kind and `false` on the rest. |
|
|
141
|
+
| `enabled: false` | Do not start the runtime, or call the active handle's `destroy()`. |
|
|
158
142
|
|
|
159
|
-
|
|
143
|
+
The old startup option names are removed, without aliases. The standalone `enableVerticalControlArea()` entry remains available and defaults `controls` to `'verticalOnly'`; its appearance settings also move under `ionic.verticalBars`. Use only one startup entry per app.
|
|
144
|
+
|
|
145
|
+
### Preserve a tabs-only configuration
|
|
160
146
|
|
|
161
147
|
```diff
|
|
162
148
|
- import { enableNativeUIShell } from '@rdlabo/ionic-theme-ios27/native';
|
|
163
149
|
+ import { enableNativeUI } from '@rdlabo/capacitor-native-ui';
|
|
164
150
|
|
|
165
151
|
- const shell = await enableNativeUIShell({
|
|
166
|
-
+ const shell = await enableNativeUI({
|
|
167
152
|
- controls: { tabs: true },
|
|
168
153
|
- buttonProjection: 'source',
|
|
169
154
|
- buttonDefaultFill: null,
|
|
170
|
-
+
|
|
171
|
-
+
|
|
155
|
+
+ const shell = await enableNativeUI({
|
|
156
|
+
+ controls: {
|
|
157
|
+
+ buttonGroup: false,
|
|
158
|
+
+ button: false,
|
|
159
|
+
+ backButton: false,
|
|
160
|
+
+ tabs: true,
|
|
161
|
+
+ segment: false,
|
|
162
|
+
+ fab: false,
|
|
163
|
+
+ },
|
|
164
|
+
+ ionic: {
|
|
165
|
+
+ verticalBars: { buttonProjection: 'source', buttonDefaultFill: 'glass' },
|
|
166
|
+
+ },
|
|
172
167
|
});
|
|
173
168
|
```
|
|
174
169
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
### Toolbar selection and grouping by layout
|
|
170
|
+
### Select controls by placement
|
|
178
171
|
|
|
179
|
-
`
|
|
172
|
+
All six control fields accept `boolean | 'horizontalOnly' | 'verticalOnly'`. A scalar `controls` value applies to every field. Horizontal and vertical mean ordinary placement and the rail, not device orientation or model.
|
|
180
173
|
|
|
181
174
|
```ts
|
|
182
|
-
const shell = await enableNativeUI({
|
|
183
|
-
horizontal: false,
|
|
184
|
-
vertical: { buttons: false, button: false, backButton: true },
|
|
185
|
-
});
|
|
175
|
+
const shell = await enableNativeUI({ controls: 'verticalOnly' });
|
|
186
176
|
```
|
|
187
177
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
Do not translate `controls.toolbar` or `ionic.auto.buttons` into `vertical.buttons`: those options govern the entire automatic toolbar category, while `horizontal.buttons` / `vertical.buttons` govern **grouping only**. Within each layout, `button` selects ordinary actions and `backButton` selects back navigation independently. All three fields default to `true`; a layout value of `false` sets all three to `false`.
|
|
191
|
-
|
|
192
|
-
If you used the short-lived development settings at the top level, move `{ buttons, button, backButton }` into `vertical: { buttons, button, backButton }`. Those fields were not part of the published 1.2.0/1.2.1 API and are not compatibility aliases. Existing `buttonProjection` / `buttonDefaultFill` are separate appearance settings, mapped above.
|
|
178
|
+
These are selection defaults, not a hard projection scope. Explicit `data-native-ui` sources and local `data-horizontal-bars="true"` / `data-vertical-bars="true"` can opt in even when a matching default is `false`. Remove the explicit marker or use `data-native-ui="disabled"` to leave an individual source on the Web. `ionic.auto: false` disables automatic Ionic discovery, including local layout opt-ins, but leaves explicit source declarations enabled.
|
|
193
179
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
See [all settings and defaults](configuration.md) and [plain HTML setup](framework-independent.md). Standard HTML buttons use the same Swift controls as Ionic; they do not require an application-specific Swift extension.
|
|
180
|
+
`buttonGroup` controls grouping only. It does not select children: `buttonGroup: true, button: false` projects no ordinary action without explicit selection. `backButton` controls back navigation independently, including inside an `ion-buttons` container. See [all settings](configuration.md) for the complete selection matrix and [toolbar grouping](native-ui.md#toolbar-selection-and-grouping) for local overrides.
|
|
197
181
|
|
|
198
182
|
## Web layout ownership
|
|
199
183
|
|
|
200
184
|
Import `setVerticalBarsLayout` and `applyFoldStateClasses` from `@rdlabo/ionic-theme-ios27` for theme CSS. Replace `setVerticalControlAreaPlacement({ edge, nativeEdge, inset })` with `setVerticalBarsLayout({ edge, inset })`. Native UI now reads availability from its own device metrics; `nativeEdge` is ignored by the deprecated compatibility helper. Normal startup, disabled rails and teardown do not remove theme classes or alter reserved Web spacing. An unavailable native rail keeps the application’s Web rail layout; applications wanting a horizontal layout must select it themselves. Native-only applications can continue to use their own layout CSS.
|
|
201
|
-
|
|
202
|
-
## Automatic Ionic controls
|
|
203
|
-
|
|
204
|
-
Use `ionic.auto` for new configuration. It accepts `true` (default), `false`, or `{ buttons, tabs, segment, fab }`. Unlike legacy `controls`, it affects only automatic Ionic projection; explicit `data-native-ui` sources and registered extensions remain enabled. `verticalBars` independently controls rail projection. See [selective projection](configuration.md#select-controls-explicitly-in-a-customized-ionic-app) for an existing Ionic app that opts in individual buttons.
|
|
205
|
-
|
|
206
|
-
The legacy `controls` option is marked `@deprecated` and remains available. When `ionic.auto` is omitted, legacy kind settings are used, but omitted kinds now default to `true`; expand partial Preview configurations as shown above. If both are supplied, `ionic.auto` takes precedence for automatic kinds. Move the legacy `popover` option to `verticalBars.popover`.
|