Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,22 @@ The same Library screen with Native UI off and on, captured while dragging the s

## Choose what your app needs

| Your goal | Start here |
| ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| Style your Ionic Web UI | [Set up the theme](packages/theme-ios27/docs/setup.md) |
| Render Ionic controls natively with your existing Web appearance | [Set up Native UI](packages/capacitor-native-ui/docs/setup.md) |
| Use native buttons without Ionic | [HTML setup](packages/capacitor-native-ui/docs/framework-independent.md) |
| Add a vertical rail to Ionic while keeping your theme | [Ionic rail setup](packages/theme-ios27/docs/iphone-duo-with-original-theme.md#try-it-in-your-existing-ionic-app) |
| Add a vertical rail without Ionic | [HTML rail setup](packages/capacitor-native-ui/docs/framework-independent.md) |
| Add custom SwiftUI or Compose content | [App-local extensions (experimental)](packages/capacitor-native-ui/docs/native-ui-extensions.md) |
| Your goal | Start here |
| ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| Style your Ionic Web UI | [Set up the theme](packages/theme-ios27/docs/setup.md) |
| Render Ionic controls natively with your existing Web appearance | [Set up Native UI](packages/capacitor-native-ui/docs/setup.md) |
| Use native buttons without Ionic | [HTML setup](packages/capacitor-native-ui/docs/framework-independent.md) |
| Add a vertical rail to Ionic while keeping your theme | [Ionic rail setup](packages/capacitor-native-ui/docs/ionic-vertical-bars.md#try-it-in-your-existing-ionic-app) |
| Add a vertical rail without Ionic | [HTML rail setup](packages/capacitor-native-ui/docs/framework-independent.md) |
| Add custom SwiftUI or Compose content | [App-local extensions (experimental)](packages/capacitor-native-ui/docs/native-ui-extensions.md) |

Already using the iOS theme? [Add Native UI to your theme](packages/theme-ios27/docs/add-native-ui.md) as your next step.

Both packages support Ionic 8.8.1 or later within Ionic 8 or 9. Native UI requires Capacitor 8; see its setup guide for supported iOS environments.

## Explore further

- [iPhone Duo layout](packages/theme-ios27/docs/iphone-duo.md) · [Vertical Bars with an existing theme](packages/theme-ios27/docs/iphone-duo-with-original-theme.md).
- [iPhone Duo layout](packages/theme-ios27/docs/iphone-duo.md) · [Vertical Bars with an existing theme](packages/capacitor-native-ui/docs/ionic-vertical-bars.md).
- [Theme migration](packages/theme-ios27/docs/migration.md) · [Native UI migration](packages/capacitor-native-ui/docs/migration.md).

Use standard native buttons without Ionic through the [plain HTML adapter](packages/capacitor-native-ui/docs/framework-independent.md), or keep Ionic markup and enable only [Vertical Bars](packages/capacitor-native-ui/docs/configuration.md). Both use the same native renderers.
Expand Down
2 changes: 1 addition & 1 deletion demo/src/app/docs/docs-content.generated.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion demo/src/app/docs/docs-page.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ <h2 id="docs-start-title">What would you like to build?</h2>
>
</li>
<li>
<a href="https://github.com/rdlabo-dev/ionic-theme-ios27/blob/main/packages/theme-ios27/docs/iphone-duo-with-original-theme.md"
<a href="https://github.com/rdlabo-dev/ionic-theme-ios27/blob/main/packages/capacitor-native-ui/docs/ionic-vertical-bars.md"
>Add a side rail to Ionic with your existing theme</a
>
</li>
Expand Down
34 changes: 34 additions & 0 deletions demo/src/native-ui-html.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,40 @@ test('Web rail forwards source form behavior, updates state, rejects stale click
expect(options.rail!.host.children.length).toBe(0);
});

test('Web rail follows source order without replacing proxies or application-owned host content', async () => {
const { root, options } = mount(
'<button data-native-ui="button" data-native-ui-placement="rail">A</button>' +
'<button data-native-ui="button" data-native-ui-placement="rail">B</button>',
);
const host = options.rail!.host;
const heading = document.createElement('h2');
heading.textContent = 'Actions';
host.append(heading);
const handle = createHTMLWebProjection(document, options);
handles.push(handle);
const proxies = () => Array.from(host.querySelectorAll<HTMLButtonElement>('button'));
const [a, b] = proxies();
const sourceB = root.lastElementChild as HTMLButtonElement;
const click = vi.fn();
sourceB.addEventListener('click', click);
b.focus();
root.prepend(sourceB);
await vi.waitFor(() => expect(proxies()).toEqual([b, a]));
expect(document.activeElement).toBe(b);
b.click();
expect(click).toHaveBeenCalledTimes(1);

const sourceC = sourceB.cloneNode(true) as HTMLButtonElement;
sourceC.removeAttribute('data-native-ui-web-source');
sourceC.textContent = 'C';
sourceC.getBoundingClientRect = sourceB.getBoundingClientRect;
root.prepend(sourceC);
await vi.waitFor(() => expect(proxies().map((proxy) => proxy.textContent)).toEqual(['C', 'B', 'A']));
expect(proxies().slice(1)).toEqual([b, a]);
expect(host.firstElementChild).toBe(heading);
expect(document.activeElement).toBe(b);
});

test('routerless back delegates to the source and suspension returns ownership to the Web', async () => {
const { source, options } = mount('<button type="button" data-native-ui="back-button" data-native-ui-placement="rail">Back</button>');
const back = vi.fn();
Expand Down
16 changes: 8 additions & 8 deletions packages/capacitor-native-ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ Projection changes presentation; it does not translate arbitrary HTML or CSS int

## Choose what to build

| Goal | Start here |
| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| Render existing Ionic controls natively | [Ionic setup](docs/setup.md) |
| Use native buttons without Ionic | [HTML setup](docs/framework-independent.md) |
| Add a side rail to Ionic while keeping your theme | [Vertical Bars step by step](https://github.com/rdlabo-dev/ionic-theme-ios27/blob/main/packages/theme-ios27/docs/iphone-duo-with-original-theme.md) |
| Add a side rail without Ionic | [HTML rail setup](docs/framework-independent.md) |
| Add native controls to an existing iOS 27 theme app | [Add Native UI to your theme](https://github.com/rdlabo-dev/ionic-theme-ios27/blob/main/packages/theme-ios27/docs/add-native-ui.md) |
| Render custom SwiftUI or Android Compose content | [App-local extensions (experimental)](docs/native-ui-extensions.md) |
| Goal | Start here |
| --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| Render existing Ionic controls natively | [Ionic setup](docs/setup.md) |
| Use native buttons without Ionic | [HTML setup](docs/framework-independent.md) |
| Add a side rail to Ionic while keeping your theme | [Vertical Bars step by step](docs/ionic-vertical-bars.md) |
| Add a side rail without Ionic | [HTML rail setup](docs/framework-independent.md) |
| Add native controls to an existing iOS 27 theme app | [Add Native UI to your theme](https://github.com/rdlabo-dev/ionic-theme-ios27/blob/main/packages/theme-ios27/docs/add-native-ui.md) |
| Render custom SwiftUI or Android Compose content | [App-local extensions (experimental)](docs/native-ui-extensions.md) |

## Install from npm

Expand Down
2 changes: 1 addition & 1 deletion packages/capacitor-native-ui/docs/framework-independent.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Start with [how projection works](../README.md#how-projection-works): the HTML e

**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`.

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](../../theme-ios27/docs/iphone-duo-with-original-theme.md#try-it-in-your-existing-ionic-app) instead. The framework (Angular, React or Vue) alone does not determine which adapter to use.
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.

## 1. Install the plugin

Expand Down
Loading
Loading