@rdlabo/ionic-theme-ios27 1.2.0-3 → 1.2.0-4
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 +15 -2
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/css/ionic-theme-ios27.css +1 -1
- package/dist/css/vertical-bars.css +1 -1
- package/dist/focus-controller/index.d.ts +4 -2
- package/dist/focus-controller/index.d.ts.map +1 -1
- package/dist/focus-controller/index.js +100 -57
- package/dist/focus-controller/index.js.map +1 -0
- package/dist/index.d.ts +10 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +54 -60
- package/dist/index.js.map +1 -0
- package/dist/native/components/index.d.ts +13 -10
- package/dist/native/components/index.d.ts.map +1 -1
- package/dist/native/components/index.js +39 -41
- package/dist/native/components/index.js.map +1 -0
- package/dist/native/components/ion-back-button.d.ts +6 -1
- package/dist/native/components/ion-back-button.d.ts.map +1 -1
- package/dist/native/components/ion-back-button.js +19 -13
- package/dist/native/components/ion-back-button.js.map +1 -0
- package/dist/native/components/ion-button.d.ts +8 -2
- package/dist/native/components/ion-button.d.ts.map +1 -1
- package/dist/native/components/ion-button.js +22 -17
- package/dist/native/components/ion-button.js.map +1 -0
- package/dist/native/components/ion-buttons.d.ts +8 -2
- package/dist/native/components/ion-buttons.d.ts.map +1 -1
- package/dist/native/components/ion-buttons.js +29 -33
- package/dist/native/components/ion-buttons.js.map +1 -0
- package/dist/native/components/ion-fab.d.ts +6 -1
- package/dist/native/components/ion-fab.d.ts.map +1 -1
- package/dist/native/components/ion-fab.js +131 -151
- package/dist/native/components/ion-fab.js.map +1 -0
- package/dist/native/components/ion-menu-button.d.ts +8 -2
- package/dist/native/components/ion-menu-button.d.ts.map +1 -1
- package/dist/native/components/ion-menu-button.js +29 -19
- package/dist/native/components/ion-menu-button.js.map +1 -0
- package/dist/native/components/ion-segment.d.ts +6 -1
- package/dist/native/components/ion-segment.d.ts.map +1 -1
- package/dist/native/components/ion-segment.js +29 -23
- package/dist/native/components/ion-segment.js.map +1 -0
- package/dist/native/components/ion-tab-bar.d.ts +6 -1
- package/dist/native/components/ion-tab-bar.d.ts.map +1 -1
- package/dist/native/components/ion-tab-bar.js +49 -40
- package/dist/native/components/ion-tab-bar.js.map +1 -0
- package/dist/native/components/searchable-tabs.d.ts +17 -15
- package/dist/native/components/searchable-tabs.d.ts.map +1 -1
- package/dist/native/components/searchable-tabs.js +382 -434
- package/dist/native/components/searchable-tabs.js.map +1 -0
- package/dist/native/definitions.d.ts +118 -111
- package/dist/native/definitions.d.ts.map +1 -1
- package/dist/native/definitions.js +0 -1
- package/dist/native/foldable/fold-state.d.ts +5 -0
- package/dist/native/foldable/fold-state.d.ts.map +1 -0
- package/dist/native/foldable/fold-state.js +14 -0
- package/dist/native/foldable/fold-state.js.map +1 -0
- package/dist/native/foldable/types.d.ts +12 -0
- package/dist/native/foldable/types.d.ts.map +1 -0
- package/dist/native/foldable/types.js +0 -0
- package/dist/native/index.d.ts +6 -3
- package/dist/native/index.d.ts.map +1 -1
- package/dist/native/index.js +228 -204
- package/dist/native/index.js.map +1 -0
- package/dist/native/prehide.d.ts +4 -2
- package/dist/native/prehide.d.ts.map +1 -1
- package/dist/native/prehide.js +220 -242
- package/dist/native/prehide.js.map +1 -0
- package/dist/native/runtime.d.ts +3 -1
- package/dist/native/runtime.d.ts.map +1 -1
- package/dist/native/runtime.js +626 -730
- package/dist/native/runtime.js.map +1 -0
- package/dist/native/shared/candidate.d.ts +16 -11
- package/dist/native/shared/candidate.d.ts.map +1 -1
- package/dist/native/shared/candidate.js +96 -95
- package/dist/native/shared/candidate.js.map +1 -0
- package/dist/native/shared/crossfade.d.ts +6 -4
- package/dist/native/shared/crossfade.d.ts.map +1 -1
- package/dist/native/shared/crossfade.js +49 -45
- package/dist/native/shared/crossfade.js.map +1 -0
- package/dist/native/shared/dom.d.ts +7 -5
- package/dist/native/shared/dom.d.ts.map +1 -1
- package/dist/native/shared/dom.js +163 -211
- package/dist/native/shared/dom.js.map +1 -0
- package/dist/native/shared/events.d.ts +8 -6
- package/dist/native/shared/events.d.ts.map +1 -1
- package/dist/native/shared/events.js +12 -7
- package/dist/native/shared/events.js.map +1 -0
- package/dist/native/shared/icons.d.ts +4 -2
- package/dist/native/shared/icons.d.ts.map +1 -1
- package/dist/native/shared/icons.js +59 -53
- package/dist/native/shared/icons.js.map +1 -0
- package/dist/native/shared/modal.d.ts +3 -1
- package/dist/native/shared/modal.d.ts.map +1 -1
- package/dist/native/shared/modal.js +156 -139
- package/dist/native/shared/modal.js.map +1 -0
- package/dist/native/vertical-bars-web.d.ts +3 -1
- package/dist/native/vertical-bars-web.d.ts.map +1 -1
- package/dist/native/vertical-bars-web.js +332 -346
- package/dist/native/vertical-bars-web.js.map +1 -0
- package/dist/native-integration/index.d.ts +10 -8
- package/dist/native-integration/index.d.ts.map +1 -1
- package/dist/native-integration/index.js +102 -100
- package/dist/native-integration/index.js.map +1 -0
- package/dist/native-integration/transition.d.ts +3 -1
- package/dist/native-integration/transition.d.ts.map +1 -1
- package/dist/native-integration/transition.js +15 -6
- package/dist/native-integration/transition.js.map +1 -0
- package/dist/searchbar/index.d.ts +4 -2
- package/dist/searchbar/index.d.ts.map +1 -1
- package/dist/searchbar/index.js +64 -56
- package/dist/searchbar/index.js.map +1 -0
- package/dist/segment/index.d.ts +3 -1
- package/dist/segment/index.d.ts.map +1 -1
- package/dist/segment/index.js +465 -324
- package/dist/segment/index.js.map +1 -0
- package/dist/sheets-of-glass/animations.d.ts +13 -12
- package/dist/sheets-of-glass/animations.d.ts.map +1 -1
- package/dist/sheets-of-glass/animations.js +496 -306
- package/dist/sheets-of-glass/animations.js.map +1 -0
- package/dist/sheets-of-glass/index.d.ts +3 -1
- package/dist/sheets-of-glass/index.d.ts.map +1 -1
- package/dist/sheets-of-glass/index.js +294 -357
- package/dist/sheets-of-glass/index.js.map +1 -0
- package/dist/sheets-of-glass/interfaces.d.ts +11 -9
- package/dist/sheets-of-glass/interfaces.d.ts.map +1 -1
- package/dist/sheets-of-glass/interfaces.js +0 -1
- package/dist/tab-bar-searchable/animations/enter.d.ts +4 -2
- package/dist/tab-bar-searchable/animations/enter.d.ts.map +1 -1
- package/dist/tab-bar-searchable/animations/enter.js +50 -69
- package/dist/tab-bar-searchable/animations/enter.js.map +1 -0
- package/dist/tab-bar-searchable/animations/leave.d.ts +4 -2
- package/dist/tab-bar-searchable/animations/leave.d.ts.map +1 -1
- package/dist/tab-bar-searchable/animations/leave.js +48 -62
- package/dist/tab-bar-searchable/animations/leave.js.map +1 -0
- package/dist/tab-bar-searchable/index.d.ts +5 -3
- package/dist/tab-bar-searchable/index.d.ts.map +1 -1
- package/dist/tab-bar-searchable/index.js +123 -135
- package/dist/tab-bar-searchable/index.js.map +1 -0
- package/dist/transition/index.d.ts +9 -8
- package/dist/transition/index.d.ts.map +1 -1
- package/dist/transition/index.js +203 -192
- package/dist/transition/index.js.map +1 -0
- package/dist/transition/ios.transition.d.ts +7 -5
- package/dist/transition/ios.transition.d.ts.map +1 -1
- package/dist/transition/ios.transition.js +15 -11
- package/dist/transition/ios.transition.js.map +1 -0
- package/dist/utils.d.ts +10 -8
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +58 -66
- package/dist/utils.js.map +1 -0
- package/dist/vertical-bars.d.ts +5 -4
- package/dist/vertical-bars.js +4 -2
- package/docs/iphone-duo-with-original-theme.md +18 -29
- package/docs/iphone-duo.md +44 -204
- package/docs/native-ui-shell.md +10 -8
- package/docs/special-markup.md +2 -0
- package/docs/vertical-bars.md +283 -0
- package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellVerticalBars.swift +34 -14
- package/ios/Sources/IonicNativeUIShellPlugin/Shared/ShellSnapshot.swift +2 -0
- package/ios/Tests/IonicNativeUIShellPluginTests/ShellSnapshotTests.swift +3 -0
- package/package.json +9 -6
- package/src/native/components/index.ts +3 -2
- package/src/native/components/ion-button.ts +3 -2
- package/src/native/components/ion-buttons.ts +4 -3
- package/src/native/components/ion-menu-button.ts +3 -2
- package/src/native/definitions.ts +22 -1
- package/src/native/foldable/fold-state.ts +9 -0
- package/src/native/foldable/types.ts +4 -0
- package/src/native/index.ts +17 -3
- package/src/native/prehide.ts +3 -1
- package/src/native/runtime.ts +2 -2
- package/src/native/shared/candidate.ts +39 -10
- package/src/native/shared/dom.ts +4 -4
- package/src/styles/vertical-bars.scss +4 -2
- package/src/vertical-bars.ts +9 -1
- package/dist/vertical-bars.d.ts.map +0 -1
package/dist/utils.js
CHANGED
|
@@ -1,71 +1,63 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/utils.ts
|
|
2
|
+
const getElementRoot = (el, fallback = el) => {
|
|
3
|
+
return el.shadowRoot || fallback;
|
|
3
4
|
};
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if (typeof requestAnimationFrame === 'function') {
|
|
9
|
-
return requestAnimationFrame(h);
|
|
10
|
-
}
|
|
11
|
-
return setTimeout(h);
|
|
5
|
+
const raf = (h) => {
|
|
6
|
+
if (typeof __zone_symbol__requestAnimationFrame === "function") return __zone_symbol__requestAnimationFrame(h);
|
|
7
|
+
if (typeof requestAnimationFrame === "function") return requestAnimationFrame(h);
|
|
8
|
+
return setTimeout(h);
|
|
12
9
|
};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
document.body.appendChild(clonedEl);
|
|
24
|
-
return clonedEl;
|
|
10
|
+
const cloneElement = (tagName, useCache = true) => {
|
|
11
|
+
if (useCache) {
|
|
12
|
+
const cachedElement = document.querySelector(`${tagName}.ion-cloned-element`);
|
|
13
|
+
if (cachedElement !== null) return cachedElement;
|
|
14
|
+
}
|
|
15
|
+
const clonedEl = document.createElement(tagName);
|
|
16
|
+
clonedEl.classList.add("ion-cloned-element");
|
|
17
|
+
clonedEl.style.setProperty("display", "none");
|
|
18
|
+
document.body.appendChild(clonedEl);
|
|
19
|
+
return clonedEl;
|
|
25
20
|
};
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
let progress = (currentX - animationPosition.minPositionX) / (animationPosition.maxPositionX - animationPosition.minPositionX);
|
|
32
|
-
progress = Math.max(0, Math.min(1, progress));
|
|
33
|
-
return progress;
|
|
21
|
+
const getStep = (targetX, animationPosition) => {
|
|
22
|
+
if (animationPosition === void 0) return 0;
|
|
23
|
+
let progress = (targetX - animationPosition.width / 2 - animationPosition.minPositionX) / (animationPosition.maxPositionX - animationPosition.minPositionX);
|
|
24
|
+
progress = Math.max(0, Math.min(1, progress));
|
|
25
|
+
return progress;
|
|
34
26
|
};
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
27
|
+
const changeSelectedElement = (targetElement, selectedElement, effectTagName, selectedClassName) => {
|
|
28
|
+
targetElement.querySelectorAll(effectTagName).forEach((element) => {
|
|
29
|
+
element.classList.remove(selectedClassName);
|
|
30
|
+
element.classList.remove("ion-activated");
|
|
31
|
+
});
|
|
32
|
+
selectedElement.classList.add("ion-activated");
|
|
41
33
|
};
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
34
|
+
var Config = class {
|
|
35
|
+
constructor() {
|
|
36
|
+
this.m = /* @__PURE__ */ new Map();
|
|
37
|
+
}
|
|
38
|
+
reset(configObj) {
|
|
39
|
+
this.m = new Map(Object.entries(configObj));
|
|
40
|
+
}
|
|
41
|
+
get(key, fallback) {
|
|
42
|
+
const value = this.m.get(key);
|
|
43
|
+
return value !== void 0 ? value : fallback;
|
|
44
|
+
}
|
|
45
|
+
getBoolean(key, fallback = false) {
|
|
46
|
+
const val = this.m.get(key);
|
|
47
|
+
if (val === void 0) return fallback;
|
|
48
|
+
if (typeof val === "string") return val === "true";
|
|
49
|
+
return !!val;
|
|
50
|
+
}
|
|
51
|
+
getNumber(key, fallback) {
|
|
52
|
+
const val = parseFloat(String(this.m.get(key)));
|
|
53
|
+
return isNaN(val) ? fallback !== void 0 ? fallback : NaN : val;
|
|
54
|
+
}
|
|
55
|
+
set(key, value) {
|
|
56
|
+
this.m.set(key, value);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const config = /*@__PURE__*/ new Config();
|
|
60
|
+
//#endregion
|
|
61
|
+
export { Config, changeSelectedElement, cloneElement, config, getElementRoot, getStep, raf };
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import { AnimationPosition } from './sheets-of-glass/interfaces';\nimport { IonicConfig } from '@ionic/core';\n\ndeclare const __zone_symbol__requestAnimationFrame: ((callback: FrameRequestCallback) => number) | undefined;\ndeclare const requestAnimationFrame: ((callback: FrameRequestCallback) => number) | undefined;\n\nexport const getElementRoot = (el: HTMLElement, fallback: HTMLElement = el) => {\n return el.shadowRoot || fallback;\n};\n\nexport const raf = (h: FrameRequestCallback) => {\n if (typeof __zone_symbol__requestAnimationFrame === 'function') {\n return __zone_symbol__requestAnimationFrame(h);\n }\n if (typeof requestAnimationFrame === 'function') {\n return requestAnimationFrame(h);\n }\n return setTimeout(h);\n};\n\nexport const cloneElement = (tagName: string, useCache: boolean = true): HTMLElement => {\n if (useCache) {\n const cachedElement = document.querySelector(`${tagName}.ion-cloned-element`);\n if (cachedElement !== null) {\n return cachedElement as HTMLElement;\n }\n }\n\n const clonedEl = document.createElement(tagName) as HTMLElement;\n clonedEl.classList.add('ion-cloned-element');\n clonedEl.style.setProperty('display', 'none');\n document.body.appendChild(clonedEl);\n\n return clonedEl;\n};\n\nexport const getStep = (targetX: number, animationPosition: AnimationPosition) => {\n if (animationPosition === undefined) {\n return 0;\n }\n const currentX = targetX - animationPosition.width / 2;\n let progress = (currentX - animationPosition.minPositionX) / (animationPosition.maxPositionX - animationPosition.minPositionX);\n progress = Math.max(0, Math.min(1, progress)); // clamp 0〜1\n return progress;\n};\n\nexport const changeSelectedElement = (\n targetElement: HTMLElement,\n selectedElement: HTMLElement,\n effectTagName: string,\n selectedClassName: string,\n): void => {\n targetElement.querySelectorAll(effectTagName).forEach((element) => {\n element.classList.remove(selectedClassName);\n element.classList.remove('ion-activated');\n });\n selectedElement.classList.add('ion-activated');\n};\n\nexport class Config {\n private m = new Map<keyof IonicConfig, unknown>();\n\n reset(configObj: IonicConfig) {\n this.m = new Map<keyof IonicConfig, unknown>(Object.entries(configObj) as [keyof IonicConfig, unknown][]);\n }\n\n get<T>(key: keyof IonicConfig, fallback?: T): T {\n const value = this.m.get(key);\n return value !== undefined ? (value as T) : (fallback as T);\n }\n\n getBoolean(key: keyof IonicConfig, fallback = false): boolean {\n const val = this.m.get(key);\n if (val === undefined) {\n return fallback;\n }\n if (typeof val === 'string') {\n return val === 'true';\n }\n return !!val;\n }\n\n getNumber(key: keyof IonicConfig, fallback?: number): number {\n const val = parseFloat(String(this.m.get(key)));\n return isNaN(val) ? (fallback !== undefined ? fallback : NaN) : val;\n }\n\n set(key: keyof IonicConfig, value: unknown) {\n this.m.set(key, value);\n }\n}\n\nexport const config = /*@__PURE__*/ new Config();\n"],"mappings":";AAMA,MAAa,kBAAkB,IAAiB,WAAwB,OAAO;CAC7E,OAAO,GAAG,cAAc;AAC1B;AAEA,MAAa,OAAO,MAA4B;CAC9C,IAAI,OAAO,yCAAyC,YAClD,OAAO,qCAAqC,CAAC;CAE/C,IAAI,OAAO,0BAA0B,YACnC,OAAO,sBAAsB,CAAC;CAEhC,OAAO,WAAW,CAAC;AACrB;AAEA,MAAa,gBAAgB,SAAiB,WAAoB,SAAsB;CACtF,IAAI,UAAU;EACZ,MAAM,gBAAgB,SAAS,cAAc,GAAG,QAAQ,oBAAoB;EAC5E,IAAI,kBAAkB,MACpB,OAAO;CAEX;CAEA,MAAM,WAAW,SAAS,cAAc,OAAO;CAC/C,SAAS,UAAU,IAAI,oBAAoB;CAC3C,SAAS,MAAM,YAAY,WAAW,MAAM;CAC5C,SAAS,KAAK,YAAY,QAAQ;CAElC,OAAO;AACT;AAEA,MAAa,WAAW,SAAiB,sBAAyC;CAChF,IAAI,sBAAsB,KAAA,GACxB,OAAO;CAGT,IAAI,YADa,UAAU,kBAAkB,QAAQ,IAC1B,kBAAkB,iBAAiB,kBAAkB,eAAe,kBAAkB;CACjH,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,QAAQ,CAAC;CAC5C,OAAO;AACT;AAEA,MAAa,yBACX,eACA,iBACA,eACA,sBACS;CACT,cAAc,iBAAiB,aAAa,CAAC,CAAC,SAAS,YAAY;EACjE,QAAQ,UAAU,OAAO,iBAAiB;EAC1C,QAAQ,UAAU,OAAO,eAAe;CAC1C,CAAC;CACD,gBAAgB,UAAU,IAAI,eAAe;AAC/C;AAEA,IAAa,SAAb,MAAoB;;EAClB,KAAQ,oBAAI,IAAI,IAAgC;;CAEhD,MAAM,WAAwB;EAC5B,KAAK,IAAI,IAAI,IAAgC,OAAO,QAAQ,SAAS,CAAmC;CAC1G;CAEA,IAAO,KAAwB,UAAiB;EAC9C,MAAM,QAAQ,KAAK,EAAE,IAAI,GAAG;EAC5B,OAAO,UAAU,KAAA,IAAa,QAAe;CAC/C;CAEA,WAAW,KAAwB,WAAW,OAAgB;EAC5D,MAAM,MAAM,KAAK,EAAE,IAAI,GAAG;EAC1B,IAAI,QAAQ,KAAA,GACV,OAAO;EAET,IAAI,OAAO,QAAQ,UACjB,OAAO,QAAQ;EAEjB,OAAO,CAAC,CAAC;CACX;CAEA,UAAU,KAAwB,UAA2B;EAC3D,MAAM,MAAM,WAAW,OAAO,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC;EAC9C,OAAO,MAAM,GAAG,IAAK,aAAa,KAAA,IAAY,WAAW,MAAO;CAClE;CAEA,IAAI,KAAwB,OAAgB;EAC1C,KAAK,EAAE,IAAI,KAAK,KAAK;CACvB;AACF;AAEA,MAAa,uBAAuB,IAAI,OAAO"}
|
package/dist/vertical-bars.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { withNativeUIShellTransition } from "./native-integration/transition.js";
|
|
2
|
+
import { NativeUIShellStatus, NativeUIShellSuspension, VerticalBarEdge, VerticalControlAreaHandle, VerticalControlAreaOptions } from "./native/definitions.js";
|
|
3
|
+
import { applyFoldStateClasses } from "./native/foldable/fold-state.js";
|
|
4
|
+
import { IonicNativeUIShell, enableVerticalControlArea, setVerticalControlAreaPlacement } from "./native/index.js";
|
|
5
|
+
export { IonicNativeUIShell, type NativeUIShellStatus, type NativeUIShellSuspension, type VerticalBarEdge, type VerticalControlAreaHandle, type VerticalControlAreaOptions, applyFoldStateClasses, enableVerticalControlArea, setVerticalControlAreaPlacement, withNativeUIShellTransition };
|
package/dist/vertical-bars.js
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { withNativeUIShellTransition } from "./native-integration/transition.js";
|
|
2
|
+
import { IonicNativeUIShell, enableVerticalControlArea, setVerticalControlAreaPlacement } from "./native/index.js";
|
|
3
|
+
import { applyFoldStateClasses } from "./native/foldable/fold-state.js";
|
|
4
|
+
export { IonicNativeUIShell, applyFoldStateClasses, enableVerticalControlArea, setVerticalControlAreaPlacement, withNativeUIShellTransition };
|
|
@@ -112,13 +112,25 @@ Use your existing Ionic click handlers, routing, and form associations. All butt
|
|
|
112
112
|
|
|
113
113
|
When the application owner is disposed, call `await rail.destroy()` to restore the original controls and release the runtime. If you already use `enableNativeUIShell()`, keep that runtime and follow the [shared placement guide](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/iphone-duo#project-controls-into-the-rail).
|
|
114
114
|
|
|
115
|
+
### Optional: choose native button appearance (unreleased)
|
|
116
|
+
|
|
117
|
+
The next release adds `buttonProjection` and local projection settings. These options are not available in the `1.2.0-1` installation above. See [Choose button appearance](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/vertical-bars#choose-button-appearance) for availability and migration details.
|
|
118
|
+
|
|
119
|
+
The new default is `system`: SwiftUI styles vertical buttons and tints their icons. If your existing theme should supply their fill and colors, use:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
const rail = await enableVerticalControlArea({ buttonProjection: 'source', buttonDefaultFill: 'solid' });
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
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](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/vertical-bars#override-individual-buttons-or-groups). These settings affect native vertical buttons only; Web clones keep their existing appearance.
|
|
126
|
+
|
|
115
127
|
### If the preview does not appear
|
|
116
128
|
|
|
117
129
|
| What you see | What to check |
|
|
118
130
|
| --- | --- |
|
|
119
131
|
| No space at the side | Load `vertical-bars.css` and put the class on `ion-app`. |
|
|
120
132
|
| Space appears, but controls stay horizontal | Start `enableVerticalControlArea()` after mounting the app root. Use existing tabs or `slot="icon-only"` actions in a fixed header/footer toolbar. |
|
|
121
|
-
| 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](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/
|
|
133
|
+
| 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](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/vertical-bars#toolbar-actions). |
|
|
122
134
|
|
|
123
135
|
## Connect an iPhone Duo
|
|
124
136
|
|
|
@@ -131,41 +143,18 @@ npx cap sync ios
|
|
|
131
143
|
|
|
132
144
|
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. Native UI Shell uses Swift Package Manager; existing CocoaPods apps can follow [Native UI Shell setup](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/native-ui-shell#enable-the-shell). Keep this package's `vertical-bars.css`; the device plugin's `ionic-tabs.css` is not needed with our rail projection.
|
|
133
145
|
|
|
134
|
-
Replace the browser-only startup
|
|
135
|
-
|
|
136
|
-
```ts
|
|
137
|
-
import { Capacitor, type PluginListenerHandle } from '@capacitor/core';
|
|
138
|
-
import { enableVerticalControlArea } from '@rdlabo/ionic-theme-ios27/vertical-bars';
|
|
139
|
-
import { Foldable } from '@erkamyaman/capacitor-foldable';
|
|
140
|
-
|
|
141
|
-
const rail = await enableVerticalControlArea();
|
|
142
|
-
let layoutListener: PluginListenerHandle | undefined;
|
|
143
|
-
|
|
144
|
-
if (Capacitor.getPlatform() === 'ios') {
|
|
145
|
-
layoutListener = await Foldable.addListener('barPlacementChange', ({ verticalBarEdge, inset }) =>
|
|
146
|
-
rail.setPlacement({ edge: verticalBarEdge, nativeEdge: verticalBarEdge, inset }),
|
|
147
|
-
);
|
|
148
|
-
const { verticalBarEdge, inset } = await Foldable.getBarPlacement();
|
|
149
|
-
rail.setPlacement({ edge: verticalBarEdge, nativeEdge: verticalBarEdge, inset });
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Call when the application owner is disposed.
|
|
153
|
-
const stopVerticalArea = async () => {
|
|
154
|
-
await layoutListener?.remove();
|
|
155
|
-
await rail.destroy();
|
|
156
|
-
};
|
|
157
|
-
```
|
|
146
|
+
Replace the browser-only startup with the [device placement setup](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/iphone-duo#project-controls-into-the-rail). That setup sends initial values and `barPlacementChange` events to `setVerticalControlAreaPlacement({ edge: verticalBarEdge, nativeEdge: verticalBarEdge, inset })`, with subscriptions and cleanup kept in your application.
|
|
158
147
|
|
|
159
|
-
|
|
148
|
+
Pass both the requested and native edge with Foldable's measured inset. The placement API resolves RTL. A null edge restores the ordinary layout.
|
|
160
149
|
|
|
161
|
-
On supported iOS, controls in the rail use
|
|
150
|
+
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.
|
|
162
151
|
|
|
163
152
|
## Use hinge posture without projecting controls
|
|
164
153
|
|
|
165
|
-
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`.
|
|
154
|
+
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.
|
|
166
155
|
|
|
167
156
|
See [Read the device layout](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/iphone-duo#read-the-device-layout) for the subscription example, null values, and monitoring lifetime. See [Adapt the split pane](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/iphone-duo#adapt-the-split-pane) for the opt-in width rules and half-open state.
|
|
168
157
|
|
|
169
158
|
## Shared layout rules and API
|
|
170
159
|
|
|
171
|
-
Safe-area handling, overlays, RTL, control eligibility, Web simulation, and the handle API are documented in [
|
|
160
|
+
Safe-area handling, overlays, RTL, control eligibility, Web simulation, and the handle API are documented in [Vertical Bars](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/vertical-bars). Those rules apply to this standalone setup too.
|
package/docs/iphone-duo.md
CHANGED
|
@@ -6,7 +6,7 @@ title: iPhone Duo support (experimental)
|
|
|
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](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/iphone-duo-with-original-theme) to preview the side layout in Chrome. This page explains device events, placement
|
|
9
|
+
**New here?** Start with [iPhone Duo with your existing theme](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/iphone-duo-with-original-theme) to preview the side layout in Chrome. This page explains device events, placement and split panes. [Vertical Bars](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/vertical-bars) documents control projection and the runtime API.
|
|
10
10
|
|
|
11
11
|
Available in `1.2.0-0` as an **experimental** feature alongside [Native UI Shell](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/native-ui-shell). APIs and supported behavior may change. 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
|
|
|
@@ -19,7 +19,7 @@ Device state belongs to [`@erkamyaman/capacitor-foldable`](https://github.com/er
|
|
|
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](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/iphone-duo-with-original-theme). This page covers the shared device-layout rules
|
|
22
|
+
To keep your existing theme and add only the standalone support, follow [iPhone Duo with your existing theme](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/iphone-duo-with-original-theme). This page covers the shared device-layout rules.
|
|
23
23
|
|
|
24
24
|
| Goal | Stylesheet | Runtime |
|
|
25
25
|
| ------------------------------------------------ | ------------------- | ------------------------------------------------------------------ |
|
|
@@ -47,128 +47,73 @@ npx cap sync
|
|
|
47
47
|
|
|
48
48
|
Use Capacitor 8.5 or later and build with Xcode 27.1 or newer for iPhone Duo's iOS 27.1 APIs. The dependency is needed for device-driven layout, not for the theme's CSS, browser simulation, or native control projection alone. Do not import the plugin's `ionic-tabs.css` alongside this package's rail projection; both would reposition the same tabs.
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
After `ion-app` is mounted, pass device state to `applyFoldStateClasses`. The application owns subscriptions and cleanup. No projection runtime is needed for posture-driven layout.
|
|
51
51
|
|
|
52
52
|
```ts
|
|
53
|
-
import { Foldable
|
|
54
|
-
|
|
55
|
-
const applyFold = (fold: FoldState) => {
|
|
56
|
-
const pane = document.querySelector('ion-split-pane');
|
|
57
|
-
pane?.classList.toggle('ios-theme-split-pane-half-open', fold.state === 'half-opened');
|
|
58
|
-
const expanded = fold.state === 'half-opened' || (fold.state === 'flat' && !!fold.hingeBounds);
|
|
59
|
-
pane?.setAttribute('when', expanded ? '(min-width: 900px)' : '(min-width: 992px)');
|
|
60
|
-
};
|
|
61
|
-
let receivedEvent = false;
|
|
62
|
-
let disposed = false;
|
|
63
|
-
const listener = await Foldable.addListener('foldStateChange', (fold) => {
|
|
64
|
-
receivedEvent = true;
|
|
65
|
-
if (!disposed) applyFold(fold);
|
|
66
|
-
});
|
|
67
|
-
const initialFold = await Foldable.getFoldState();
|
|
68
|
-
if (!disposed && !receivedEvent) applyFold(initialFold);
|
|
69
|
-
|
|
70
|
-
// When the consumer goes away:
|
|
71
|
-
// disposed = true;
|
|
72
|
-
// await listener.remove();
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
`getFoldState()` and `foldStateChange` report `state` (`'flat'`, `'half-opened'`, or `'closed'`), `posture`, and optional hinge geometry. Without fold information, the plugin returns a flat state without `hingeBounds`; restore the ordinary split-pane breakpoint in that case. The Web implementation also returns a flat state. A half-opened state uses the 900px breakpoint even without hinge geometry; a flat state with hinge geometry also uses 900px. A closed state restores the ordinary 992px breakpoint. Events received during initialization take precedence over the initial read.
|
|
53
|
+
import { Foldable } from '@erkamyaman/capacitor-foldable';
|
|
54
|
+
import { applyFoldStateClasses } from '@rdlabo/ionic-theme-ios27/vertical-bars';
|
|
76
55
|
|
|
77
|
-
|
|
56
|
+
const root = document.querySelector('ion-app')!;
|
|
57
|
+
const listener = await Foldable.addListener('foldStateChange', (fold) => applyFoldStateClasses(root, fold));
|
|
58
|
+
applyFoldStateClasses(root, await Foldable.getFoldState());
|
|
59
|
+
```
|
|
78
60
|
|
|
79
|
-
|
|
61
|
+
When the application owner is disposed:
|
|
80
62
|
|
|
81
|
-
|
|
63
|
+
```ts
|
|
64
|
+
await listener.remove();
|
|
65
|
+
```
|
|
82
66
|
|
|
83
|
-
|
|
67
|
+
Subscribe to changes, then read the current state. The same helper handles initial values and events.
|
|
84
68
|
|
|
85
|
-
|
|
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.
|
|
86
70
|
|
|
87
|
-
|
|
71
|
+
For rail placement, use `setVerticalControlAreaPlacement` as shown below. Pass the reported logical edge as both `edge` and `nativeEdge`, together with the measured `inset`. 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.
|
|
88
72
|
|
|
89
|
-
|
|
90
|
-
<ion-app class="ios-theme-vertical-bars">...</ion-app>
|
|
91
|
-
```
|
|
73
|
+
WebView corner radius remains a rendering concern: `configureNativeTransition()` uses the shell's `getWebViewMetrics()` API, independently of `Foldable`.
|
|
92
74
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
For Chrome development, no native plugin is needed — the class alone reserves `80px` to simulate iPhone Duo. When `setPlacement` receives an explicit `{ edge, inset }`, that 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.
|
|
96
|
-
|
|
97
|
-
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.
|
|
75
|
+
**Migration:** the theme's former `DeviceLayout`, `HingeStatus`, `getDeviceLayout()`, `deviceLayoutChange`, and start/stop device-layout monitoring APIs have been removed. Replace device subscriptions with the `Foldable` APIs above; use `getWebViewMetrics()` for one-shot radius reads. Foldable can infer Duo bar placement from safe-area insets when the app is built without the iOS 27.1 SDK. Hinge data still requires the newer SDK. Apps can also request a fixed rail placement independently of the reported edge.
|
|
98
76
|
|
|
99
|
-
|
|
77
|
+
## Reserve the vertical rail
|
|
100
78
|
|
|
101
|
-
|
|
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](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/vertical-bars#reserve-the-vertical-rail). On device, the placement helper below applies the layout classes and measured inset.
|
|
102
80
|
|
|
103
81
|
## Project controls into the rail
|
|
104
82
|
|
|
105
|
-
Start the standalone runtime once
|
|
83
|
+
Start the standalone runtime once after `ion-app` is mounted, and apply the plugin's placement with `setVerticalControlAreaPlacement`:
|
|
106
84
|
|
|
107
85
|
```ts
|
|
108
|
-
import { Capacitor, type PluginListenerHandle } from '@capacitor/core';
|
|
109
|
-
import { enableVerticalControlArea } from '@rdlabo/ionic-theme-ios27/vertical-bars';
|
|
110
86
|
import { Foldable } from '@erkamyaman/capacitor-foldable';
|
|
87
|
+
import { setVerticalControlAreaPlacement, enableVerticalControlArea } from '@rdlabo/ionic-theme-ios27/vertical-bars';
|
|
111
88
|
|
|
112
|
-
// Start on Chrome too; the Web projection stays idle until the class is present.
|
|
113
89
|
const rail = await enableVerticalControlArea();
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
);
|
|
120
|
-
const { verticalBarEdge, inset } = await Foldable.getBarPlacement();
|
|
121
|
-
rail.setPlacement({ edge: verticalBarEdge, nativeEdge: verticalBarEdge, inset });
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Call when the application owner is disposed.
|
|
125
|
-
const stopVerticalArea = async () => {
|
|
126
|
-
await layoutListener?.remove();
|
|
127
|
-
await rail.destroy();
|
|
128
|
-
};
|
|
90
|
+
const listener = await Foldable.addListener('barPlacementChange', ({ verticalBarEdge, inset }) =>
|
|
91
|
+
setVerticalControlAreaPlacement({ edge: verticalBarEdge, nativeEdge: verticalBarEdge, inset }),
|
|
92
|
+
);
|
|
93
|
+
const { verticalBarEdge, inset } = await Foldable.getBarPlacement();
|
|
94
|
+
setVerticalControlAreaPlacement({ edge: verticalBarEdge, nativeEdge: verticalBarEdge, inset });
|
|
129
95
|
```
|
|
130
96
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
- Pass `{ edge, nativeEdge }`: `edge` is the application's chosen logical edge; `nativeEdge` is `verticalBarEdge` from `Foldable.getBarPlacement()`/`barPlacementChange`. They resolve through the nearest `dir` attribute, or the explicit `rtl` argument.
|
|
134
|
-
- Pass `null` to restore the ordinary layout.
|
|
135
|
-
- The device-layout listener reports what iOS chose; the application decides whether to apply it. The theme compares the application's chosen edge with its supplied `nativeEdge`; a mismatch uses the Web rail until the edges match again. For a fixed right-in-LTR rail, pass `{ edge: 'trailing', nativeEdge: verticalBarEdge }` on each `Foldable` update.
|
|
136
|
-
|
|
137
|
-
Start either `enableVerticalControlArea()` or the full `enableNativeUIShell()` — not both. Repeating the same configuration returns the shared runtime; starting a different configuration while it is active throws an error. The application should have one owner responsible for destroying that runtime. If the app already uses `enableNativeUIShell()`, keep that single runtime and call `setVerticalControlAreaPlacement({ edge: verticalBarEdge, nativeEdge: verticalBarEdge, inset })` from its listener.
|
|
138
|
-
|
|
139
|
-
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. Back navigation can come from outside a fixed toolbar; menu buttons and other toolbar actions still require one.
|
|
97
|
+
When the application owner is disposed:
|
|
140
98
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
99
|
+
```ts
|
|
100
|
+
await listener.remove();
|
|
101
|
+
await rail.destroy();
|
|
102
|
+
```
|
|
144
103
|
|
|
145
|
-
|
|
146
|
-
| --- | --- |
|
|
147
|
-
| `slot="icon-only"` | Vertical rail |
|
|
148
|
-
| `slot="start"`, `slot="end"`, or no slot | Original horizontal toolbar |
|
|
149
|
-
| No icon | Original horizontal toolbar |
|
|
104
|
+
Supply `nativeEdge` on both the initial read and each event so the renderer knows which rail the system actually provides. 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](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/vertical-bars#reserve-the-vertical-rail) without connecting device placement.
|
|
150
105
|
|
|
151
|
-
|
|
106
|
+
Start either `enableVerticalControlArea()` or the full `enableNativeUIShell()` — not both. If the app already uses Native UI Shell, keep that runtime and use the same `setVerticalControlAreaPlacement` callback. The application owner removes its listeners and destroys its runtime on teardown.
|
|
152
107
|
|
|
153
|
-
|
|
154
|
-
<ion-header>
|
|
155
|
-
<ion-toolbar>
|
|
156
|
-
<ion-buttons slot="end">
|
|
157
|
-
<ion-button type="button" fill="outline" color="primary" aria-label="Done">
|
|
158
|
-
<ion-icon name="checkmark-outline" slot="icon-only"></ion-icon>
|
|
159
|
-
</ion-button>
|
|
160
|
-
</ion-buttons>
|
|
161
|
-
</ion-toolbar>
|
|
162
|
-
</ion-header>
|
|
163
|
-
```
|
|
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](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/vertical-bars#toolbar-actions) for control eligibility.
|
|
164
109
|
|
|
165
|
-
|
|
110
|
+
### Toolbar actions
|
|
166
111
|
|
|
167
|
-
|
|
112
|
+
See [Vertical Bars: Toolbar actions](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/vertical-bars#toolbar-actions) for eligible markup, placement, button appearance and local overrides.
|
|
168
113
|
|
|
169
114
|
### Tab bar
|
|
170
115
|
|
|
171
|
-
|
|
116
|
+
See [Vertical Bars: Tab bar](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/vertical-bars#tab-bar) for navigation, labels and Web fallback behavior.
|
|
172
117
|
|
|
173
118
|
## Adapt the split pane
|
|
174
119
|
|
|
@@ -176,7 +121,7 @@ For a side-by-side menu on iPhone Duo, opt the `ion-split-pane` into the separat
|
|
|
176
121
|
|
|
177
122
|
```html
|
|
178
123
|
<ion-split-pane
|
|
179
|
-
|
|
124
|
+
class="split-pane-fold-layout"
|
|
180
125
|
contentId="main-content"
|
|
181
126
|
when="(min-width: 900px)"
|
|
182
127
|
>
|
|
@@ -188,7 +133,7 @@ For a side-by-side menu on iPhone Duo, opt the `ion-split-pane` into the separat
|
|
|
188
133
|
Set the ordinary split-pane width to 320pt in the application's stylesheet, and let the half-open class change only the width value:
|
|
189
134
|
|
|
190
135
|
```css
|
|
191
|
-
ion-split-pane {
|
|
136
|
+
ion-split-pane.split-pane-fold-layout {
|
|
192
137
|
--ios-theme-menu-width: var(--ios-theme-split-pane-width);
|
|
193
138
|
--side-width: var(--ios-theme-menu-width);
|
|
194
139
|
--side-max-width: var(--ios-theme-menu-width);
|
|
@@ -196,115 +141,10 @@ ion-split-pane {
|
|
|
196
141
|
}
|
|
197
142
|
```
|
|
198
143
|
|
|
199
|
-
The registered `--ios-theme-split-pane-width` defaults to `320px
|
|
200
|
-
|
|
201
|
-
## Vertical Control Area API
|
|
202
|
-
|
|
203
|
-
The generated reference below documents the handle returned by `enableVerticalControlArea()`.
|
|
204
|
-
|
|
205
|
-
<docgen-index>
|
|
206
|
-
|
|
207
|
-
* [`setPlacement(...)`](#setplacement)
|
|
208
|
-
* [`getStatus()`](#getstatus)
|
|
209
|
-
* [`suspend()`](#suspend)
|
|
210
|
-
* [`destroy()`](#destroy)
|
|
211
|
-
* [Interfaces](#interfaces)
|
|
212
|
-
* [Type Aliases](#type-aliases)
|
|
213
|
-
|
|
214
|
-
</docgen-index>
|
|
215
|
-
|
|
216
|
-
<docgen-api>
|
|
217
|
-
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
|
|
218
|
-
|
|
219
|
-
### setPlacement(...)
|
|
220
|
-
|
|
221
|
-
```typescript
|
|
222
|
-
setPlacement(placement: VerticalBarEdge | VerticalBarPlacement, rtl?: boolean | undefined) => void
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
Applies the application's chosen placement to both Web and native controls.
|
|
226
|
-
|
|
227
|
-
| Param | Type |
|
|
228
|
-
| --------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
229
|
-
| **`placement`** | <code><a href="#verticalbaredge">VerticalBarEdge</a> \| <a href="#verticalbarplacement">VerticalBarPlacement</a></code> |
|
|
230
|
-
| **`rtl`** | <code>boolean</code> |
|
|
144
|
+
The registered `--ios-theme-split-pane-width` defaults to `320px`. `applyFoldStateClasses` sets `ios-theme-fold-half-opened` on `ion-app`; the stylesheet then sets only descendant split panes with `split-pane-fold-layout` to `50vw`. Add this opt-in class once; no state-dependent class binding is needed. Other split panes retain their existing width.
|
|
231
145
|
|
|
232
|
-
|
|
146
|
+
Ionic's `when` still controls whether the menu is persistent. The example chooses a fixed 900px breakpoint. If your app needs different breakpoints for folded and ordinary displays, use the `ios-theme-fold-expanded` class applied by the helper to select that policy in your application's layout code. The helper only updates state classes, not `when`. This layout does not enable Vertical Bars or move an overlay menu.
|
|
233
147
|
|
|
148
|
+
## Vertical Control Area API
|
|
234
149
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
```typescript
|
|
238
|
-
getStatus() => NativeUIShellStatus
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
Returns the current Web/native projection state.
|
|
242
|
-
|
|
243
|
-
**Returns:** <code><a href="#nativeuishellstatus">NativeUIShellStatus</a></code>
|
|
244
|
-
|
|
245
|
-
--------------------
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
### suspend()
|
|
249
|
-
|
|
250
|
-
```typescript
|
|
251
|
-
suspend() => Promise<NativeUIShellSuspension>
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
Restores projected controls to the Web until the returned lease is resumed.
|
|
255
|
-
|
|
256
|
-
**Returns:** <code>Promise<<a href="#nativeuishellsuspension">NativeUIShellSuspension</a>></code>
|
|
257
|
-
|
|
258
|
-
--------------------
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
### destroy()
|
|
262
|
-
|
|
263
|
-
```typescript
|
|
264
|
-
destroy() => Promise<void>
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
Stops synchronization, restores Web controls and releases native resources.
|
|
268
|
-
|
|
269
|
-
--------------------
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
### Interfaces
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
#### VerticalBarPlacement
|
|
276
|
-
|
|
277
|
-
| Prop | Type | Description |
|
|
278
|
-
| ---------------- | ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
279
|
-
| **`edge`** | <code><a href="#verticalbaredge">VerticalBarEdge</a></code> | |
|
|
280
|
-
| **`inset`** | <code>number</code> | Explicit rail width in CSS pixels; omitted to use the stylesheet's safe-area rules. |
|
|
281
|
-
| **`nativeEdge`** | <code><a href="#verticalbaredge">VerticalBarEdge</a></code> | Native logical edge reported by the application's device plugin. Null or an unregistered edge uses a Web rail in verticalBarsOnly mode, or the ordinary Native UI Shell layout otherwise. Omission keeps the last supplied value. |
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
#### NativeUIShellStatus
|
|
285
|
-
|
|
286
|
-
| Prop | Type |
|
|
287
|
-
| --------------- | ------------------------------------------- |
|
|
288
|
-
| **`state`** | <code>'native' \| 'stopped' \| 'web'</code> |
|
|
289
|
-
| **`projected`** | <code>number</code> |
|
|
290
|
-
| **`updates`** | <code>number</code> |
|
|
291
|
-
| **`reason`** | <code>string</code> |
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
#### NativeUIShellSuspension
|
|
295
|
-
|
|
296
|
-
| Method | Signature | Description |
|
|
297
|
-
| ---------- | ---------------------------- | ---------------------------------------------------------------------------------------------- |
|
|
298
|
-
| **resume** | () => Promise<void> | Releases this suspension. Native projection resumes after all active suspensions are released. |
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
### Type Aliases
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
#### VerticalBarEdge
|
|
305
|
-
|
|
306
|
-
Logical edge in the reading direction, matching UIVerticalBarEdge and capacitor-foldable.
|
|
307
|
-
|
|
308
|
-
<code>'leading' | 'trailing' | null</code>
|
|
309
|
-
|
|
310
|
-
</docgen-api>
|
|
150
|
+
The runtime handle reference is maintained in [Vertical Bars](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/vertical-bars#vertical-control-area-api).
|