@rdlabo/capacitor-native-ui 0.0.0-stage → 1.2.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/LICENSE +21 -0
- package/Package.swift +23 -0
- package/README.md +53 -2
- package/RdlaboCapacitorNativeUi.podspec +17 -0
- package/android/build.gradle +69 -0
- package/android/proguard-rules.pro +0 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/java/dev/rdlabo/capacitor/nativeui/NativeUI.kt +51 -0
- package/android/src/main/java/dev/rdlabo/capacitor/nativeui/NativeUIPlugin.kt +192 -0
- package/android/src/main/java/dev/rdlabo/capacitor/nativeui/NativeUISnapshot.kt +57 -0
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/core.d.ts +4 -0
- package/dist/core.js +3 -0
- package/dist/native/activation.d.ts +14 -0
- package/dist/native/activation.d.ts.map +1 -0
- package/dist/native/activation.js +305 -0
- package/dist/native/activation.js.map +1 -0
- package/dist/native/components/index.d.ts +19 -0
- package/dist/native/components/index.d.ts.map +1 -0
- package/dist/native/components/index.js +38 -0
- package/dist/native/components/index.js.map +1 -0
- package/dist/native/components/ion-back-button.d.ts +10 -0
- package/dist/native/components/ion-back-button.d.ts.map +1 -0
- package/dist/native/components/ion-back-button.js +21 -0
- package/dist/native/components/ion-back-button.js.map +1 -0
- package/dist/native/components/ion-button.d.ts +10 -0
- package/dist/native/components/ion-button.d.ts.map +1 -0
- package/dist/native/components/ion-button.js +25 -0
- package/dist/native/components/ion-button.js.map +1 -0
- package/dist/native/components/ion-buttons.d.ts +11 -0
- package/dist/native/components/ion-buttons.d.ts.map +1 -0
- package/dist/native/components/ion-buttons.js +30 -0
- package/dist/native/components/ion-buttons.js.map +1 -0
- package/dist/native/components/ion-fab.d.ts +10 -0
- package/dist/native/components/ion-fab.d.ts.map +1 -0
- package/dist/native/components/ion-fab.js +132 -0
- package/dist/native/components/ion-fab.js.map +1 -0
- package/dist/native/components/ion-menu-button.d.ts +13 -0
- package/dist/native/components/ion-menu-button.d.ts.map +1 -0
- package/dist/native/components/ion-menu-button.js +44 -0
- package/dist/native/components/ion-menu-button.js.map +1 -0
- package/dist/native/components/ion-segment.d.ts +11 -0
- package/dist/native/components/ion-segment.d.ts.map +1 -0
- package/dist/native/components/ion-segment.js +30 -0
- package/dist/native/components/ion-segment.js.map +1 -0
- package/dist/native/components/ion-tab-bar.d.ts +11 -0
- package/dist/native/components/ion-tab-bar.d.ts.map +1 -0
- package/dist/native/components/ion-tab-bar.js +50 -0
- package/dist/native/components/ion-tab-bar.js.map +1 -0
- package/dist/native/components/searchable-tabs.d.ts +20 -0
- package/dist/native/components/searchable-tabs.d.ts.map +1 -0
- package/dist/native/components/searchable-tabs.js +413 -0
- package/dist/native/components/searchable-tabs.js.map +1 -0
- package/dist/native/definitions.d.ts +255 -0
- package/dist/native/definitions.d.ts.map +1 -0
- package/dist/native/definitions.js +0 -0
- package/dist/native/extensions.d.ts +31 -0
- package/dist/native/extensions.d.ts.map +1 -0
- package/dist/native/extensions.js +122 -0
- package/dist/native/extensions.js.map +1 -0
- 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 +15 -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/html.d.ts +9 -0
- package/dist/native/html.d.ts.map +1 -0
- package/dist/native/html.js +188 -0
- package/dist/native/html.js.map +1 -0
- package/dist/native/index.d.ts +10 -0
- package/dist/native/index.d.ts.map +1 -0
- package/dist/native/index.js +28 -0
- package/dist/native/index.js.map +1 -0
- package/dist/native/legacy-layout.d.ts +5 -0
- package/dist/native/legacy-layout.d.ts.map +1 -0
- package/dist/native/legacy-layout.js +27 -0
- package/dist/native/legacy-layout.js.map +1 -0
- package/dist/native/overlays/content.d.ts +4 -0
- package/dist/native/overlays/content.d.ts.map +1 -0
- package/dist/native/overlays/content.js +51 -0
- package/dist/native/overlays/content.js.map +1 -0
- package/dist/native/overlays/controller.d.ts +8 -0
- package/dist/native/overlays/controller.d.ts.map +1 -0
- package/dist/native/overlays/controller.js +285 -0
- package/dist/native/overlays/controller.js.map +1 -0
- package/dist/native/overlays/dialog-animation.d.ts +9 -0
- package/dist/native/overlays/dialog-animation.d.ts.map +1 -0
- package/dist/native/overlays/dialog-animation.js +53 -0
- package/dist/native/overlays/dialog-animation.js.map +1 -0
- package/dist/native/overlays/dismiss-animation.d.ts +4 -0
- package/dist/native/overlays/dismiss-animation.d.ts.map +1 -0
- package/dist/native/overlays/dismiss-animation.js +18 -0
- package/dist/native/overlays/dismiss-animation.js.map +1 -0
- package/dist/native/overlays/focus.d.ts +5 -0
- package/dist/native/overlays/focus.d.ts.map +1 -0
- package/dist/native/overlays/focus.js +59 -0
- package/dist/native/overlays/focus.js.map +1 -0
- package/dist/native/overlays/popover.d.ts +12 -0
- package/dist/native/overlays/popover.d.ts.map +1 -0
- package/dist/native/overlays/popover.js +110 -0
- package/dist/native/overlays/popover.js.map +1 -0
- package/dist/native/overlays/styles.d.ts +11 -0
- package/dist/native/overlays/styles.d.ts.map +1 -0
- package/dist/native/overlays/styles.js +167 -0
- package/dist/native/overlays/styles.js.map +1 -0
- package/dist/native/prehide.d.ts +8 -0
- package/dist/native/prehide.d.ts.map +1 -0
- package/dist/native/prehide.js +238 -0
- package/dist/native/prehide.js.map +1 -0
- package/dist/native/runtime.d.ts +7 -0
- package/dist/native/runtime.d.ts.map +1 -0
- package/dist/native/runtime.js +788 -0
- package/dist/native/runtime.js.map +1 -0
- package/dist/native/shared/bridge.d.ts +6 -0
- package/dist/native/shared/bridge.d.ts.map +1 -0
- package/dist/native/shared/bridge.js +18 -0
- package/dist/native/shared/bridge.js.map +1 -0
- package/dist/native/shared/candidate.d.ts +25 -0
- package/dist/native/shared/candidate.d.ts.map +1 -0
- package/dist/native/shared/candidate.js +106 -0
- package/dist/native/shared/candidate.js.map +1 -0
- package/dist/native/shared/clipping.d.ts +5 -0
- package/dist/native/shared/clipping.d.ts.map +1 -0
- package/dist/native/shared/clipping.js +26 -0
- package/dist/native/shared/clipping.js.map +1 -0
- package/dist/native/shared/crossfade.d.ts +12 -0
- package/dist/native/shared/crossfade.d.ts.map +1 -0
- package/dist/native/shared/crossfade.js +67 -0
- package/dist/native/shared/crossfade.js.map +1 -0
- package/dist/native/shared/diagnostics.d.ts +4 -0
- package/dist/native/shared/diagnostics.d.ts.map +1 -0
- package/dist/native/shared/diagnostics.js +18 -0
- package/dist/native/shared/diagnostics.js.map +1 -0
- package/dist/native/shared/dom.d.ts +46 -0
- package/dist/native/shared/dom.d.ts.map +1 -0
- package/dist/native/shared/dom.js +180 -0
- package/dist/native/shared/dom.js.map +1 -0
- package/dist/native/shared/events.d.ts +15 -0
- package/dist/native/shared/events.d.ts.map +1 -0
- package/dist/native/shared/events.js +17 -0
- package/dist/native/shared/events.js.map +1 -0
- package/dist/native/shared/icons.d.ts +8 -0
- package/dist/native/shared/icons.d.ts.map +1 -0
- package/dist/native/shared/icons.js +61 -0
- package/dist/native/shared/icons.js.map +1 -0
- package/dist/native/shared/modal.d.ts +10 -0
- package/dist/native/shared/modal.d.ts.map +1 -0
- package/dist/native/shared/modal.js +160 -0
- package/dist/native/shared/modal.js.map +1 -0
- package/dist/native/shared/projection-id.d.ts +4 -0
- package/dist/native/shared/projection-id.d.ts.map +1 -0
- package/dist/native/shared/projection-id.js +7 -0
- package/dist/native/shared/projection-id.js.map +1 -0
- package/dist/native/shared/toolbar-options.d.ts +9 -0
- package/dist/native/shared/toolbar-options.d.ts.map +1 -0
- package/dist/native/shared/toolbar-options.js +36 -0
- package/dist/native/shared/toolbar-options.js.map +1 -0
- package/dist/native/shared/vertical-bars-geometry.d.ts +10 -0
- package/dist/native/shared/vertical-bars-geometry.d.ts.map +1 -0
- package/dist/native/shared/vertical-bars-geometry.js +85 -0
- package/dist/native/shared/vertical-bars-geometry.js.map +1 -0
- package/dist/native/startup.d.ts +8 -0
- package/dist/native/startup.d.ts.map +1 -0
- package/dist/native/startup.js +86 -0
- package/dist/native/startup.js.map +1 -0
- package/dist/native/vertical-bars-web-search.d.ts +10 -0
- package/dist/native/vertical-bars-web-search.d.ts.map +1 -0
- package/dist/native/vertical-bars-web-search.js +90 -0
- package/dist/native/vertical-bars-web-search.js.map +1 -0
- package/dist/native/vertical-bars-web.d.ts +5 -0
- package/dist/native/vertical-bars-web.d.ts.map +1 -0
- package/dist/native/vertical-bars-web.js +421 -0
- package/dist/native/vertical-bars-web.js.map +1 -0
- package/dist/native-integration/index.d.ts +25 -0
- package/dist/native-integration/index.d.ts.map +1 -0
- package/dist/native-integration/index.js +33 -0
- package/dist/native-integration/index.js.map +1 -0
- package/dist/vertical-bars.d.ts +6 -0
- package/dist/vertical-bars.js +5 -0
- package/docs/configuration.md +187 -0
- package/docs/framework-independent.md +82 -0
- package/docs/migration.md +206 -0
- package/docs/native-mini-player.md +47 -0
- package/docs/native-ui-extensions.md +365 -0
- package/docs/native-ui.md +409 -0
- package/docs/setup.md +205 -0
- package/docs/vertical-bars.md +379 -0
- package/ios/Sources/NativeUIPlugin/Components/NativeUIButton.swift +71 -0
- package/ios/Sources/NativeUIPlugin/Components/NativeUIButtons.swift +24 -0
- package/ios/Sources/NativeUIPlugin/Components/NativeUIComponents.swift +19 -0
- package/ios/Sources/NativeUIPlugin/Components/NativeUIFab.swift +80 -0
- package/ios/Sources/NativeUIPlugin/Components/NativeUISearchController.swift +439 -0
- package/ios/Sources/NativeUIPlugin/Components/NativeUISegment.swift +91 -0
- package/ios/Sources/NativeUIPlugin/Components/NativeUITabBar.swift +218 -0
- package/ios/Sources/NativeUIPlugin/Components/NativeUIVerticalBars.swift +590 -0
- package/ios/Sources/NativeUIPlugin/Components/NativeUIVerticalSearch.swift +118 -0
- package/ios/Sources/NativeUIPlugin/Extensions/NativeUI.swift +178 -0
- package/ios/Sources/NativeUIPlugin/Extensions/NativeUIRendering.swift +38 -0
- package/ios/Sources/NativeUIPlugin/NativeUIPlugin.swift +615 -0
- package/ios/Sources/NativeUIPlugin/Overlays/NativeUIOverlayController.swift +119 -0
- package/ios/Sources/NativeUIPlugin/Overlays/NativeUIOverlayHost.swift +75 -0
- package/ios/Sources/NativeUIPlugin/Shared/NativeUIControlRendering.swift +21 -0
- package/ios/Sources/NativeUIPlugin/Shared/NativeUICrossfade.swift +35 -0
- package/ios/Sources/NativeUIPlugin/Shared/NativeUIHost.swift +8 -0
- package/ios/Sources/NativeUIPlugin/Shared/NativeUISnapshot.swift +161 -0
- package/ios/Sources/NativeUIPlugin/Shared/NativeUIVerticalBarsGeometry.swift +52 -0
- package/ios/Tests/NativeUIPluginTests/NativeUIExtensionTests.swift +165 -0
- package/ios/Tests/NativeUIPluginTests/NativeUISnapshotTests.swift +805 -0
- package/package.json +89 -4
- package/src/core.ts +15 -0
- package/src/native/activation.ts +394 -0
- package/src/native/components/index.ts +45 -0
- package/src/native/components/ion-back-button.ts +22 -0
- package/src/native/components/ion-button.ts +25 -0
- package/src/native/components/ion-buttons.ts +37 -0
- package/src/native/components/ion-fab.ts +151 -0
- package/src/native/components/ion-menu-button.ts +37 -0
- package/src/native/components/ion-segment.ts +27 -0
- package/src/native/components/ion-tab-bar.ts +50 -0
- package/src/native/components/searchable-tabs.ts +499 -0
- package/src/native/definitions.ts +324 -0
- package/src/native/extensions.ts +176 -0
- package/src/native/foldable/fold-state.ts +10 -0
- package/src/native/foldable/types.ts +4 -0
- package/src/native/html.ts +193 -0
- package/src/native/index.ts +41 -0
- package/src/native/legacy-layout.ts +21 -0
- package/src/native/overlays/content.ts +51 -0
- package/src/native/overlays/controller.ts +349 -0
- package/src/native/overlays/dialog-animation.ts +53 -0
- package/src/native/overlays/dismiss-animation.ts +15 -0
- package/src/native/overlays/focus.ts +64 -0
- package/src/native/overlays/popover.ts +120 -0
- package/src/native/overlays/styles.ts +181 -0
- package/src/native/prehide.ts +285 -0
- package/src/native/runtime.ts +988 -0
- package/src/native/shared/bridge.ts +18 -0
- package/src/native/shared/candidate.ts +162 -0
- package/src/native/shared/clipping.ts +24 -0
- package/src/native/shared/crossfade.ts +67 -0
- package/src/native/shared/diagnostics.ts +13 -0
- package/src/native/shared/dom.ts +304 -0
- package/src/native/shared/events.ts +14 -0
- package/src/native/shared/icons.ts +57 -0
- package/src/native/shared/modal.ts +157 -0
- package/src/native/shared/projection-id.ts +2 -0
- package/src/native/shared/toolbar-options.ts +53 -0
- package/src/native/shared/vertical-bars-geometry.ts +80 -0
- package/src/native/startup.ts +84 -0
- package/src/native/vertical-bars-web-search.ts +86 -0
- package/src/native/vertical-bars-web.ts +498 -0
- package/src/native-integration/index.ts +49 -0
- package/src/vertical-bars.ts +11 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { NativeUIExtension } from "./extensions.js";
|
|
2
|
+
import { PluginListenerHandle } from "@capacitor/core";
|
|
3
|
+
//#region src/native/definitions.d.ts
|
|
4
|
+
export type NativeUIComponent = 'ion-button' | 'ion-buttons' | 'ion-back-button' | 'ion-menu-button' | 'ion-tab-bar' | 'ion-segment' | 'ion-fab';
|
|
5
|
+
export interface NativeUIStatus {
|
|
6
|
+
state: 'web' | 'native' | 'stopped';
|
|
7
|
+
projected: number;
|
|
8
|
+
updates: number;
|
|
9
|
+
reason?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ToolbarProjectionOptions {
|
|
12
|
+
buttons?: boolean;
|
|
13
|
+
button?: boolean;
|
|
14
|
+
backButton?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface VerticalControlAreaOptions {
|
|
17
|
+
extensions?: readonly NativeUIExtension[];
|
|
18
|
+
controls?: Pick<NativeUIControls, 'popover'>;
|
|
19
|
+
horizontal?: boolean | ToolbarProjectionOptions;
|
|
20
|
+
vertical?: boolean | ToolbarProjectionOptions;
|
|
21
|
+
buttonProjection?: 'source' | 'system';
|
|
22
|
+
buttonDefaultFill?: 'solid' | null;
|
|
23
|
+
}
|
|
24
|
+
export interface NativeUIOptions extends VerticalControlAreaOptions {
|
|
25
|
+
debug?: boolean;
|
|
26
|
+
verticalBars?: NativeUIVerticalBarsOptions;
|
|
27
|
+
ionic?: IonicProjectionOptions;
|
|
28
|
+
root?: HTMLElement;
|
|
29
|
+
enabled?: boolean;
|
|
30
|
+
controls?: NativeUIControls;
|
|
31
|
+
verticalBarsOnly?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface NativeUIRuntimeOptions extends NativeUIOptions {
|
|
34
|
+
source?: 'ionic' | 'html' | 'auto' | 'extensions';
|
|
35
|
+
explicitControls?: boolean;
|
|
36
|
+
nativeState?: {
|
|
37
|
+
edge?: 'left' | 'right';
|
|
38
|
+
};
|
|
39
|
+
unavailableExtensions?: ReadonlyMap<string, string>;
|
|
40
|
+
rail?: {
|
|
41
|
+
host: HTMLElement;
|
|
42
|
+
edge: 'left' | 'right';
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export interface IonicProjectionOptions {
|
|
46
|
+
auto?: boolean | AutoIonicControls;
|
|
47
|
+
}
|
|
48
|
+
export interface AutoIonicControls {
|
|
49
|
+
buttons?: boolean;
|
|
50
|
+
tabs?: boolean;
|
|
51
|
+
segment?: boolean;
|
|
52
|
+
fab?: boolean;
|
|
53
|
+
}
|
|
54
|
+
export interface NativeUIControls {
|
|
55
|
+
buttons?: boolean;
|
|
56
|
+
tabs?: boolean;
|
|
57
|
+
toolbar?: boolean;
|
|
58
|
+
segment?: boolean;
|
|
59
|
+
fab?: boolean;
|
|
60
|
+
popover?: boolean;
|
|
61
|
+
}
|
|
62
|
+
export interface NativeUIHandle extends NativeUIRuntimeHandle {
|
|
63
|
+
enableVerticalControlArea(): Promise<void>;
|
|
64
|
+
disableVerticalControlArea(): Promise<void>;
|
|
65
|
+
}
|
|
66
|
+
export interface NativeUIVerticalBarsOptions {
|
|
67
|
+
enabled?: boolean;
|
|
68
|
+
only?: boolean;
|
|
69
|
+
buttonProjection?: 'system' | 'source';
|
|
70
|
+
buttonDefaultFill?: 'glass' | 'solid';
|
|
71
|
+
popover?: boolean;
|
|
72
|
+
placement?: {
|
|
73
|
+
edge: Exclude<VerticalBarEdge, null>;
|
|
74
|
+
webHost?: HTMLElement;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export interface NativeUIRuntimeHandle {
|
|
78
|
+
markForCheck(): void;
|
|
79
|
+
getStatus(): NativeUIStatus;
|
|
80
|
+
suspend(): Promise<NativeUISuspension>;
|
|
81
|
+
destroy(): Promise<void>;
|
|
82
|
+
}
|
|
83
|
+
export type VerticalBarEdge = 'leading' | 'trailing' | null;
|
|
84
|
+
export interface VerticalBarPlacement {
|
|
85
|
+
edge: VerticalBarEdge;
|
|
86
|
+
inset?: number;
|
|
87
|
+
nativeEdge?: VerticalBarEdge;
|
|
88
|
+
}
|
|
89
|
+
export interface VerticalControlAreaHandle extends NativeUIHandle {
|
|
90
|
+
setPlacement(placement: VerticalBarEdge | VerticalBarPlacement, rtl?: boolean): void;
|
|
91
|
+
}
|
|
92
|
+
export interface NativeUISuspension {
|
|
93
|
+
resume(): Promise<void>;
|
|
94
|
+
}
|
|
95
|
+
export interface Frame {
|
|
96
|
+
x: number;
|
|
97
|
+
y: number;
|
|
98
|
+
width: number;
|
|
99
|
+
height: number;
|
|
100
|
+
}
|
|
101
|
+
export interface NativeUIBadge {
|
|
102
|
+
value: string;
|
|
103
|
+
color: string;
|
|
104
|
+
textColor: string;
|
|
105
|
+
}
|
|
106
|
+
export interface NativeUIItem extends Frame {
|
|
107
|
+
id: string;
|
|
108
|
+
label: string;
|
|
109
|
+
accessibilityLabel: string;
|
|
110
|
+
disabled: boolean;
|
|
111
|
+
selected: boolean;
|
|
112
|
+
fontSize: number;
|
|
113
|
+
fontWeight: number;
|
|
114
|
+
color: string;
|
|
115
|
+
buttonFill?: 'clear' | 'solid' | 'outline';
|
|
116
|
+
backgroundColor?: string;
|
|
117
|
+
borderColor?: string;
|
|
118
|
+
borderWidth?: number;
|
|
119
|
+
badge?: NativeUIBadge;
|
|
120
|
+
icon?: string;
|
|
121
|
+
iconWidth?: number;
|
|
122
|
+
iconHeight?: number;
|
|
123
|
+
iconPosition?: 'leading' | 'trailing' | 'top';
|
|
124
|
+
imagePadding?: number;
|
|
125
|
+
contentInsetLeading?: number;
|
|
126
|
+
contentInsetTrailing?: number;
|
|
127
|
+
iconTemplate?: boolean;
|
|
128
|
+
visible?: boolean;
|
|
129
|
+
closeIcon?: string;
|
|
130
|
+
closeIconWidth?: number;
|
|
131
|
+
closeIconHeight?: number;
|
|
132
|
+
iconTransition?: number;
|
|
133
|
+
}
|
|
134
|
+
export type NativeUIControlKind = 'button' | 'button-group' | 'back-button' | 'menu-button' | 'tab-bar' | 'segment' | 'floating-action-button';
|
|
135
|
+
export interface NativeUIControl extends Frame {
|
|
136
|
+
id: string;
|
|
137
|
+
kind: NativeUIControlKind | 'extension';
|
|
138
|
+
extension?: {
|
|
139
|
+
name: string;
|
|
140
|
+
props: string;
|
|
141
|
+
actions: Record<string, string>;
|
|
142
|
+
tabBarId?: string;
|
|
143
|
+
};
|
|
144
|
+
placement?: 'vertical-bars';
|
|
145
|
+
toolbarSlot?: 'start' | 'end';
|
|
146
|
+
items: NativeUIItem[];
|
|
147
|
+
dark: boolean;
|
|
148
|
+
rtl: boolean;
|
|
149
|
+
tabBarAnchor?: {
|
|
150
|
+
x: 0 | 0.5 | 1;
|
|
151
|
+
y: 0 | 1;
|
|
152
|
+
};
|
|
153
|
+
search?: NativeUISearch;
|
|
154
|
+
}
|
|
155
|
+
export interface NativeUISearch {
|
|
156
|
+
id: string;
|
|
157
|
+
field: NativeUIItem;
|
|
158
|
+
trigger: NativeUIItem;
|
|
159
|
+
closeId: string;
|
|
160
|
+
active: boolean;
|
|
161
|
+
available: boolean;
|
|
162
|
+
focused: boolean;
|
|
163
|
+
value: string;
|
|
164
|
+
placeholder: string;
|
|
165
|
+
disabled: boolean;
|
|
166
|
+
editSequence: number;
|
|
167
|
+
valueVersion: number;
|
|
168
|
+
}
|
|
169
|
+
export interface NativeUISearchEvent extends NativeUIActivation {
|
|
170
|
+
valueVersion: number;
|
|
171
|
+
phase: 'input' | 'focus' | 'blur' | 'clear' | 'commit';
|
|
172
|
+
value: string;
|
|
173
|
+
composing: boolean;
|
|
174
|
+
}
|
|
175
|
+
export interface NativeUISnapshot {
|
|
176
|
+
revision: number;
|
|
177
|
+
transitionDuration?: number;
|
|
178
|
+
viewportWidth: number;
|
|
179
|
+
verticalBarEdge?: 'left' | 'right';
|
|
180
|
+
verticalBarFrame?: Frame;
|
|
181
|
+
controls: NativeUIControl[];
|
|
182
|
+
}
|
|
183
|
+
export interface NativeUIActivation {
|
|
184
|
+
revision: number;
|
|
185
|
+
id: string;
|
|
186
|
+
sequence: number;
|
|
187
|
+
requestId?: string;
|
|
188
|
+
}
|
|
189
|
+
export interface WebViewMetrics {
|
|
190
|
+
radius: number;
|
|
191
|
+
verticalBarEdge?: VerticalBarEdge;
|
|
192
|
+
}
|
|
193
|
+
export interface NativeUIPlugin {
|
|
194
|
+
configure(options?: {
|
|
195
|
+
verticalBarsOnly?: boolean;
|
|
196
|
+
}): Promise<{
|
|
197
|
+
supported: boolean;
|
|
198
|
+
extensions?: string[];
|
|
199
|
+
}>;
|
|
200
|
+
completeExtensionAction(options: {
|
|
201
|
+
requestId: string;
|
|
202
|
+
accepted: boolean;
|
|
203
|
+
}): Promise<void>;
|
|
204
|
+
getWebViewMetrics(): Promise<WebViewMetrics>;
|
|
205
|
+
getVerticalBarsGeometry(options: {
|
|
206
|
+
viewportWidth: number;
|
|
207
|
+
ids: string[];
|
|
208
|
+
}): Promise<{
|
|
209
|
+
revision?: number;
|
|
210
|
+
items: Record<string, Frame>;
|
|
211
|
+
}>;
|
|
212
|
+
prepareOverlay(options: {
|
|
213
|
+
id: string;
|
|
214
|
+
}): Promise<void>;
|
|
215
|
+
presentOverlay(options: {
|
|
216
|
+
id: string;
|
|
217
|
+
presentation?: NativeUIPopoverPresentation;
|
|
218
|
+
}): Promise<void>;
|
|
219
|
+
dismissOverlay(options: {
|
|
220
|
+
id: string;
|
|
221
|
+
animated: boolean;
|
|
222
|
+
}): Promise<void>;
|
|
223
|
+
closeOverlay(options: {
|
|
224
|
+
id: string;
|
|
225
|
+
}): Promise<void>;
|
|
226
|
+
stopOverlays(): Promise<void>;
|
|
227
|
+
update(snapshot: NativeUISnapshot): Promise<{
|
|
228
|
+
revision: number;
|
|
229
|
+
rejectedSearches?: string[];
|
|
230
|
+
rejectedControls?: string[];
|
|
231
|
+
}>;
|
|
232
|
+
clear(options: {
|
|
233
|
+
revision: number;
|
|
234
|
+
}): Promise<void>;
|
|
235
|
+
addListener(name: 'activate', listener: (event: NativeUIActivation) => void): Promise<PluginListenerHandle>;
|
|
236
|
+
addListener(name: 'search', listener: (event: NativeUISearchEvent) => void): Promise<PluginListenerHandle>;
|
|
237
|
+
addListener(name: 'webViewMetricsChange', listener: (event: WebViewMetrics) => void): Promise<PluginListenerHandle>;
|
|
238
|
+
addListener(name: 'overlay', listener: (event: NativeUIOverlayEvent) => void): Promise<PluginListenerHandle>;
|
|
239
|
+
}
|
|
240
|
+
export interface NativeUIPopoverPresentation {
|
|
241
|
+
kind: 'popover';
|
|
242
|
+
animated: boolean;
|
|
243
|
+
dark: boolean;
|
|
244
|
+
anchorId: string;
|
|
245
|
+
width: number;
|
|
246
|
+
height: number;
|
|
247
|
+
backgroundColor: string;
|
|
248
|
+
backdropDismiss: boolean;
|
|
249
|
+
}
|
|
250
|
+
export interface NativeUIOverlayEvent {
|
|
251
|
+
id: string;
|
|
252
|
+
action: 'dismiss';
|
|
253
|
+
}
|
|
254
|
+
//#endregion
|
|
255
|
+
//# sourceMappingURL=definitions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definitions.d.ts","names":[],"sources":["../../src/native/definitions.ts"],"mappings":";;;YAGY;iBASK;EACf;EACA;EACA;EACA;;iBAGe;EAEf;EAEA;EAEA;;iBAGe;EAIf,sBAAsB;EAEtB,WAAW,KAAK;EAKhB,uBAAuB;EAKvB,qBAAqB;EASrB;EAOA;;iBAGe,wBAAwB;EAEvC;EACA,eAAe;EAEf,QAAQ;EAER,OAAO;EAEP;EAEA,WAAW;EAEX;;iBAIe,+BAA+B;EAC9C;EAEA;EACA;IAAgB;;EAEhB,wBAAwB;EACxB;IAAS,MAAM;IAAa;;;iBAGb;EAEf,iBAAiB;;iBAGF;EACf;EACA;EACA;EACA;;iBAGe;EAEf;EAEA;EAEA;EAEA;EAEA;EAEA;;iBAIe,uBAAuB;EAEtC,6BAA6B;EAE7B,8BAA8B;;iBAGf;EAEf;EAEA;EACA;EAEA;EAEA;EAEA;IAAc,MAAM,QAAQ;IAAwB,UAAU;;;iBAG/C;EAEf;EAEA,aAAa;EAEb,WAAW,QAAQ;EAEnB,WAAW;;YAID;iBAEK;EACf,MAAM;EAEN;EAIA,aAAa;;iBAGE,kCAAkC;EAIjD,aAAa,WAAW,kBAAkB,sBAAsB;;iBAGjD;EAEf,UAAU;;iBAGK;EACf;EACA;EACA;EACA;;iBAGe;EACf;EACA;EACA;;iBAGe,qBAAqB;EACpC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA,QAAQ;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;YAIU;iBASK,wBAAwB;EACvC;EACA,MAAM;EACN;IAAc;IAAc;IAAe,SAAS;IAAwB;;EAE5E;EAEA;EACA,OAAO;EACP;EACA;EACA;IAAiB;IAAgB;;EACjC,SAAS;;iBAGM;EACf;EACA,OAAO;EACP,SAAS;EACT;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;iBAGe,4BAA4B;EAC3C;EACA;EACA;EACA;;iBAGe;EACf;EACA;EACA;EAEA;EAEA,mBAAmB;EACnB,UAAU;;iBAGK;EACf;EACA;EACA;EAEA;;iBAGe;EAEf;EAEA,kBAAkB;;iBAGH;EACf,UAAU;IAAY;MAA+B;IAAU;IAAoB;;EACnF,wBAAwB;IAAW;IAAmB;MAAsB;EAC5E,qBAAqB,QAAQ;EAC7B,wBAAwB;IAAW;IAAuB;MAAkB;IAAU;IAAmB,OAAO,eAAe;;EAC/H,eAAe;IAAW;MAAe;EACzC,eAAe;IAAW;IAAY,eAAe;MAAgC;EACrF,eAAe;IAAW;IAAY;MAAsB;EAC5D,aAAa;IAAW;MAAe;EACvC,gBAAgB;EAChB,OAAO,UAAU,mBAAmB;IAAU;IAAkB;IAA6B;;EAC7F,MAAM;IAAW;MAAqB;EACtC,YAAY,kBAAkB,WAAW,OAAO,8BAA8B,QAAQ;EACtF,YAAY,gBAAgB,WAAW,OAAO,+BAA+B,QAAQ;EACrF,YAAY,8BAA8B,WAAW,OAAO,0BAA0B,QAAQ;EAC9F,YAAY,iBAAiB,WAAW,OAAO,gCAAgC,QAAQ;;iBAGxE;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;iBAGe;EACf;EACA"}
|
|
File without changes
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { projectionAncestors } from "./shared/clipping.js";
|
|
2
|
+
import { Candidate, Identify } from "./shared/candidate.js";
|
|
3
|
+
//#region src/native/extensions.d.ts
|
|
4
|
+
export type NativeUIValue = string | number | boolean | null | NativeUIValue[] | {
|
|
5
|
+
[key: string]: NativeUIValue;
|
|
6
|
+
};
|
|
7
|
+
export type NativeUIImageReference = {
|
|
8
|
+
readonly $nativeUIImage: string;
|
|
9
|
+
};
|
|
10
|
+
export interface NativeUIReadContext {
|
|
11
|
+
image(element: SVGElement | HTMLElement | null, options?: {
|
|
12
|
+
template?: boolean;
|
|
13
|
+
}): NativeUIImageReference | null;
|
|
14
|
+
}
|
|
15
|
+
export interface NativeUIExtension {
|
|
16
|
+
readonly name: string;
|
|
17
|
+
readonly selector: string;
|
|
18
|
+
readonly placement?: 'element' | 'tab-accessory';
|
|
19
|
+
readonly read: (element: HTMLElement, context: NativeUIReadContext) => {
|
|
20
|
+
props: {
|
|
21
|
+
[key: string]: NativeUIValue;
|
|
22
|
+
};
|
|
23
|
+
actions?: Record<string, HTMLElement | null>;
|
|
24
|
+
} | null;
|
|
25
|
+
}
|
|
26
|
+
export declare const defineNativeUI: <T extends NativeUIExtension>(extension: T) => Readonly<T>;
|
|
27
|
+
export declare const validateExtensions: (extensions: readonly NativeUIExtension[], doc: Document) => void;
|
|
28
|
+
export declare const readExtension: (element: HTMLElement, extensions: readonly NativeUIExtension[], id: Identify, diagnose?: (reason: string) => void) => Candidate | undefined;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { projectionAncestors as extensionAncestors };
|
|
31
|
+
//# sourceMappingURL=extensions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensions.d.ts","names":[],"sources":["../../src/native/extensions.ts"],"mappings":";;;YAMY,mDAAmD;GAAqB,cAAc;;YAGtF;WAAoC;;iBAG/B;EAEf,MAAM,SAAS,aAAa,oBAAoB;IAAY;MAAuB;;iBAMpE;WACN;WACA;WAEA;WAEA,OACP,SAAS,aACT,SAAS;IAET;OAAU,cAAc;;IAExB,UAAU,eAAe;;;qBAOhB,iBAAkB,UAAU,mBAAmB,WAAW,MAAI,SAAS;qBAEvE,qBAAsB,qBAAqB,qBAAqB,KAAK;qBAoCrE,gBACX,SAAS,aACT,qBAAqB,qBACrB,IAAI,UACJ,YAAW,4BACV"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { frame, isDark, visible } from "./shared/dom.js";
|
|
2
|
+
import { fitsClip, projectionAncestors } from "./shared/clipping.js";
|
|
3
|
+
import { iconSource } from "./shared/icons.js";
|
|
4
|
+
//#region src/native/extensions.ts
|
|
5
|
+
/** Defines a projection locally; it does not start native work or register a Capacitor plugin.
|
|
6
|
+
* @experimental API and behavior may change in future releases.
|
|
7
|
+
*/
|
|
8
|
+
const defineNativeUI = (extension) => Object.freeze({ ...extension });
|
|
9
|
+
const validateExtensions = (extensions, doc) => {
|
|
10
|
+
const names = /* @__PURE__ */ new Set();
|
|
11
|
+
for (const extension of extensions) {
|
|
12
|
+
if (!extension.name.trim() || names.has(extension.name)) throw new Error("Native UI extension names must be nonempty and unique");
|
|
13
|
+
names.add(extension.name);
|
|
14
|
+
if (!extension.selector.trim()) throw new Error("Native UI extensions require a selector");
|
|
15
|
+
doc.querySelector(extension.selector);
|
|
16
|
+
if (extension.placement && !["element", "tab-accessory"].includes(extension.placement)) throw new Error("Invalid native UI placement");
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const json = (value, images) => {
|
|
20
|
+
if (!value || typeof value !== "object" || Object.getPrototypeOf(value) !== Object.prototype) throw new Error("Native UI props must be a JSON object");
|
|
21
|
+
const result = JSON.stringify(value, (_key, item) => {
|
|
22
|
+
if (item === void 0 || typeof item === "function" || typeof item === "symbol" || typeof item === "number" && !Number.isFinite(item) || item !== null && typeof item === "object" && !Array.isArray(item) && Object.getPrototypeOf(item) !== Object.prototype) throw new Error("Native UI props must contain only JSON values");
|
|
23
|
+
if (item && typeof item === "object" && "$nativeUIImage" in item) {
|
|
24
|
+
const image = images.get(item.$nativeUIImage);
|
|
25
|
+
if (!image || Object.keys(item).length !== 1) throw new Error("Invalid native image reference");
|
|
26
|
+
return image;
|
|
27
|
+
}
|
|
28
|
+
return item;
|
|
29
|
+
});
|
|
30
|
+
if (!result || result.length > 65536) throw new Error("Native UI props exceed 64K characters");
|
|
31
|
+
return result;
|
|
32
|
+
};
|
|
33
|
+
/** Follow slot assignment too: Ionic scroll containers live inside shadow roots. */
|
|
34
|
+
const readExtension = (element, extensions, id, diagnose = () => {}) => {
|
|
35
|
+
const skip = (reason) => {
|
|
36
|
+
diagnose(reason);
|
|
37
|
+
};
|
|
38
|
+
const matches = extensions.filter((extension) => element.matches(extension.selector));
|
|
39
|
+
if (matches.length !== 1) return skip("overlapping-selectors: exactly one extension must own this source.");
|
|
40
|
+
if (!visible(element)) return skip("source-hidden: the source must be visible and inside the viewport.");
|
|
41
|
+
if (element.closest("ion-modal, ion-popover, ion-menu")) return skip("unsupported-overlay: extension sources inside Web overlays stay on the Web.");
|
|
42
|
+
if (element.contains(element.ownerDocument.activeElement)) return skip("source-focused: keep the focused Web source until focus leaves.");
|
|
43
|
+
const extension = matches[0];
|
|
44
|
+
if (extension.placement !== "tab-accessory" && !fitsClip(element)) return skip("source-clipped: the source must fit its clipping ancestors without transformed ancestors.");
|
|
45
|
+
try {
|
|
46
|
+
const images = [];
|
|
47
|
+
const imageValues = /* @__PURE__ */ new Map();
|
|
48
|
+
let state;
|
|
49
|
+
try {
|
|
50
|
+
state = extension.read(element, { image(owner, options) {
|
|
51
|
+
if (!owner || !(element.contains(owner) || element.shadowRoot?.contains(owner))) return null;
|
|
52
|
+
const svg = owner.matches("svg") ? owner : owner.shadowRoot?.querySelector("svg");
|
|
53
|
+
if (!svg) return null;
|
|
54
|
+
const source = iconSource(svg);
|
|
55
|
+
const { width, height } = owner.getBoundingClientRect();
|
|
56
|
+
if (!source || !Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) return null;
|
|
57
|
+
const value = {
|
|
58
|
+
data: "",
|
|
59
|
+
width,
|
|
60
|
+
height,
|
|
61
|
+
template: options?.template ?? false
|
|
62
|
+
};
|
|
63
|
+
const key = String(images.length);
|
|
64
|
+
images.push({
|
|
65
|
+
value,
|
|
66
|
+
source
|
|
67
|
+
});
|
|
68
|
+
imageValues.set(key, value);
|
|
69
|
+
return { $nativeUIImage: key };
|
|
70
|
+
} });
|
|
71
|
+
} catch {
|
|
72
|
+
return skip("reader-error: the extension reader threw; inspect its implementation.");
|
|
73
|
+
}
|
|
74
|
+
if (!state) return skip("reader-opt-out: the reader returned null.");
|
|
75
|
+
const props = json(state.props, imageValues);
|
|
76
|
+
const actions = /* @__PURE__ */ new Map();
|
|
77
|
+
const targets = {};
|
|
78
|
+
for (const [name, target] of Object.entries(state.actions ?? {})) {
|
|
79
|
+
if (!name || target && !element.contains(target)) return skip("invalid-actions: use named targets inside the source element.");
|
|
80
|
+
if (!target || !visible(target) || target.disabled || target.matches(":disabled, [disabled]") || target.closest("[aria-disabled=\"true\"]") || getComputedStyle(target).pointerEvents === "none") continue;
|
|
81
|
+
targets[name] = id(target);
|
|
82
|
+
actions.set(id(target), target);
|
|
83
|
+
}
|
|
84
|
+
if (Object.keys(targets).length > 30) return skip("invalid-actions: a source can expose at most 30 actions.");
|
|
85
|
+
const tabBar = extension.placement === "tab-accessory" ? Array.from(element.closest("ion-tabs")?.querySelectorAll("ion-tab-bar") ?? []).find((bar) => bar.closest("ion-tabs") === element.closest("ion-tabs")) : void 0;
|
|
86
|
+
if (extension.placement === "tab-accessory" && !tabBar) return skip("missing-tab-owner: a tab accessory needs an owning ion-tabs with ion-tab-bar.");
|
|
87
|
+
const style = getComputedStyle(element);
|
|
88
|
+
const control = {
|
|
89
|
+
id: id(element),
|
|
90
|
+
kind: "extension",
|
|
91
|
+
...frame(element.getBoundingClientRect()),
|
|
92
|
+
items: [],
|
|
93
|
+
dark: isDark(style),
|
|
94
|
+
rtl: style.direction === "rtl",
|
|
95
|
+
extension: {
|
|
96
|
+
name: extension.name,
|
|
97
|
+
props,
|
|
98
|
+
actions: targets,
|
|
99
|
+
tabBarId: tabBar ? id(tabBar) : void 0
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
return {
|
|
103
|
+
element,
|
|
104
|
+
actions,
|
|
105
|
+
icons: [],
|
|
106
|
+
control,
|
|
107
|
+
assets: images.length ? {
|
|
108
|
+
signature: JSON.stringify(images),
|
|
109
|
+
async render(renderer) {
|
|
110
|
+
for (const { value, source } of images) value.data = await renderer.render(source, value.width, value.height);
|
|
111
|
+
control.extension.props = json(state.props, imageValues);
|
|
112
|
+
}
|
|
113
|
+
} : void 0
|
|
114
|
+
};
|
|
115
|
+
} catch {
|
|
116
|
+
return skip("invalid-props: return a JSON object with finite values, valid image references, and at most 64K characters.");
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
//#endregion
|
|
120
|
+
export { defineNativeUI, projectionAncestors as extensionAncestors, readExtension, validateExtensions };
|
|
121
|
+
|
|
122
|
+
//# sourceMappingURL=extensions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensions.js","names":[],"sources":["../../src/native/extensions.ts"],"sourcesContent":["import { fitsClip } from './shared/clipping';\nexport { projectionAncestors as extensionAncestors } from './shared/clipping';\nimport type { Candidate, Identify } from './shared/candidate';\nimport { frame, isDark, visible } from './shared/dom';\nimport { iconSource, type createIconRenderer } from './shared/icons';\n\nexport type NativeUIValue = string | number | boolean | null | NativeUIValue[] | { [key: string]: NativeUIValue };\n\n/** Opaque image reference. Return it in props; the shell replaces it with NativeUIImage data before transmission. */\nexport type NativeUIImageReference = { readonly $nativeUIImage: string };\ntype NativeUIImage = { data: string; width: number; height: number; template: boolean };\n\nexport interface NativeUIReadContext {\n /** Capture a local SVG or resolved ion-icon using the standard renderer. Unsupported artwork returns null. */\n image(element: SVGElement | HTMLElement | null, options?: { template?: boolean }): NativeUIImageReference | null;\n}\n\n/** An app-local DOM projection. Swift or Kotlin registers its native content under the same name.\n * @experimental API and behavior may change in future releases.\n */\nexport interface NativeUIExtension {\n readonly name: string;\n readonly selector: string;\n /** Defaults to the source element's frame. Unsupported hosts keep the Web source visible. */\n readonly placement?: 'element' | 'tab-accessory';\n /** Return null to keep this instance on the Web. Read current source state without side effects. Notify property-only changes with shell.markForCheck(). */\n readonly read: (\n element: HTMLElement,\n context: NativeUIReadContext,\n ) => {\n props: { [key: string]: NativeUIValue };\n /** Click targets must belong to the source element. Null targets are unavailable. */\n actions?: Record<string, HTMLElement | null>;\n } | null;\n}\n\n/** Defines a projection locally; it does not start native work or register a Capacitor plugin.\n * @experimental API and behavior may change in future releases.\n */\nexport const defineNativeUI = <T extends NativeUIExtension>(extension: T): Readonly<T> => Object.freeze({ ...extension });\n\nexport const validateExtensions = (extensions: readonly NativeUIExtension[], doc: Document): void => {\n const names = new Set<string>();\n for (const extension of extensions) {\n if (!extension.name.trim() || names.has(extension.name)) throw new Error('Native UI extension names must be nonempty and unique');\n names.add(extension.name);\n if (!extension.selector.trim()) throw new Error('Native UI extensions require a selector');\n doc.querySelector(extension.selector);\n if (extension.placement && !['element', 'tab-accessory'].includes(extension.placement)) throw new Error('Invalid native UI placement');\n }\n};\n\nconst json = (value: unknown, images: Map<string, NativeUIImage>): string => {\n if (!value || typeof value !== 'object' || Object.getPrototypeOf(value) !== Object.prototype)\n throw new Error('Native UI props must be a JSON object');\n const result = JSON.stringify(value, (_key, item: unknown) => {\n if (\n item === undefined ||\n typeof item === 'function' ||\n typeof item === 'symbol' ||\n (typeof item === 'number' && !Number.isFinite(item)) ||\n (item !== null && typeof item === 'object' && !Array.isArray(item) && Object.getPrototypeOf(item) !== Object.prototype)\n )\n throw new Error('Native UI props must contain only JSON values');\n if (item && typeof item === 'object' && '$nativeUIImage' in item) {\n const image = images.get(item.$nativeUIImage as string);\n if (!image || Object.keys(item).length !== 1) throw new Error('Invalid native image reference');\n return image;\n }\n return item;\n });\n if (!result || result.length > 65536) throw new Error('Native UI props exceed 64K characters');\n return result;\n};\n\n/** Follow slot assignment too: Ionic scroll containers live inside shadow roots. */\n\nexport const readExtension = (\n element: HTMLElement,\n extensions: readonly NativeUIExtension[],\n id: Identify,\n diagnose: (reason: string) => void = () => {},\n): Candidate | undefined => {\n const skip = (reason: string): undefined => {\n diagnose(reason);\n return undefined;\n };\n const matches = extensions.filter((extension) => element.matches(extension.selector));\n if (matches.length !== 1) return skip('overlapping-selectors: exactly one extension must own this source.');\n if (!visible(element)) return skip('source-hidden: the source must be visible and inside the viewport.');\n if (element.closest('ion-modal, ion-popover, ion-menu'))\n return skip('unsupported-overlay: extension sources inside Web overlays stay on the Web.');\n if (element.contains(element.ownerDocument.activeElement)) return skip('source-focused: keep the focused Web source until focus leaves.');\n const extension = matches[0];\n if (extension.placement !== 'tab-accessory' && !fitsClip(element))\n return skip('source-clipped: the source must fit its clipping ancestors without transformed ancestors.');\n try {\n const images: { value: NativeUIImage; source: string }[] = [];\n const imageValues = new Map<string, NativeUIImage>();\n let state: ReturnType<NativeUIExtension['read']>;\n try {\n state = extension.read(element, {\n image(owner, options) {\n if (!owner || !(element.contains(owner) || element.shadowRoot?.contains(owner))) return null;\n const svg = owner.matches('svg') ? (owner as SVGElement) : owner.shadowRoot?.querySelector<SVGElement>('svg');\n if (!svg) return null;\n const source = iconSource(svg);\n const { width, height } = owner.getBoundingClientRect();\n if (!source || !Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) return null;\n const value: NativeUIImage = { data: '', width, height, template: options?.template ?? false };\n const key = String(images.length);\n images.push({ value, source });\n imageValues.set(key, value);\n return { $nativeUIImage: key };\n },\n });\n } catch {\n return skip('reader-error: the extension reader threw; inspect its implementation.');\n }\n if (!state) return skip('reader-opt-out: the reader returned null.');\n const props = json(state.props, imageValues);\n const actions = new Map<string, HTMLElement>();\n const targets: Record<string, string> = {};\n for (const [name, target] of Object.entries(state.actions ?? {})) {\n if (!name || (target && !element.contains(target))) return skip('invalid-actions: use named targets inside the source element.');\n if (\n !target ||\n !visible(target) ||\n (target as HTMLElement & { disabled?: boolean }).disabled ||\n target.matches(':disabled, [disabled]') ||\n target.closest('[aria-disabled=\"true\"]') ||\n getComputedStyle(target).pointerEvents === 'none'\n )\n continue;\n targets[name] = id(target);\n actions.set(id(target), target);\n }\n if (Object.keys(targets).length > 30) return skip('invalid-actions: a source can expose at most 30 actions.');\n const tabBar =\n extension.placement === 'tab-accessory'\n ? Array.from(element.closest('ion-tabs')?.querySelectorAll<HTMLElement>('ion-tab-bar') ?? []).find(\n (bar) => bar.closest('ion-tabs') === element.closest('ion-tabs'),\n )\n : undefined;\n if (extension.placement === 'tab-accessory' && !tabBar)\n return skip('missing-tab-owner: a tab accessory needs an owning ion-tabs with ion-tab-bar.');\n const style = getComputedStyle(element);\n const control = {\n id: id(element),\n kind: 'extension' as const,\n ...frame(element.getBoundingClientRect()),\n items: [],\n dark: isDark(style),\n rtl: style.direction === 'rtl',\n extension: { name: extension.name, props, actions: targets, tabBarId: tabBar ? id(tabBar) : undefined },\n };\n return {\n element,\n actions,\n icons: [],\n control,\n assets: images.length\n ? {\n signature: JSON.stringify(images),\n async render(renderer: ReturnType<typeof createIconRenderer>) {\n for (const { value, source } of images) value.data = await renderer.render(source, value.width, value.height);\n control.extension.props = json(state.props, imageValues);\n },\n }\n : undefined,\n };\n } catch {\n // Keep the source usable without exposing props or application exception data.\n return skip('invalid-props: return a JSON object with finite values, valid image references, and at most 64K characters.');\n }\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fold-state.d.ts","names":[],"sources":["../../../src/native/foldable/fold-state.ts"],"mappings":";;wBAIgB,sBAAsB,MAAM,aAAa,MAAM"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/native/foldable/fold-state.ts
|
|
2
|
+
/** @deprecated Import applyFoldStateClasses from @rdlabo/ionic-theme-ios27 instead.
|
|
3
|
+
* Keep posture on ion-app so descendants can follow it through CSS. */
|
|
4
|
+
function applyFoldStateClasses(root, fold) {
|
|
5
|
+
for (const state of [
|
|
6
|
+
"flat",
|
|
7
|
+
"half-opened",
|
|
8
|
+
"closed"
|
|
9
|
+
]) root.classList.toggle(`ios-theme-fold-${state}`, fold.state === state);
|
|
10
|
+
root.classList.toggle("ios-theme-fold-expanded", fold.state === "half-opened" || fold.state === "flat" && !!fold.hingeBounds);
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { applyFoldStateClasses };
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=fold-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fold-state.js","names":[],"sources":["../../../src/native/foldable/fold-state.ts"],"sourcesContent":["import type { FoldState } from './types';\n\n/** @deprecated Import applyFoldStateClasses from @rdlabo/ionic-theme-ios27 instead.\n * Keep posture on ion-app so descendants can follow it through CSS. */\nexport function applyFoldStateClasses(root: HTMLElement, fold: FoldState): void {\n for (const state of ['flat', 'half-opened', 'closed']) {\n root.classList.toggle(`ios-theme-fold-${state}`, fold.state === state);\n }\n root.classList.toggle('ios-theme-fold-expanded', fold.state === 'half-opened' || (fold.state === 'flat' && !!fold.hingeBounds));\n}\n"],"mappings":";;;AAIA,SAAgB,sBAAsB,MAAmB,MAAuB;CAC9E,KAAK,MAAM,SAAS;EAAC;EAAQ;EAAe;CAAQ,GAClD,KAAK,UAAU,OAAO,kBAAkB,SAAS,KAAK,UAAU,KAAK;CAEvE,KAAK,UAAU,OAAO,2BAA2B,KAAK,UAAU,iBAAkB,KAAK,UAAU,UAAU,CAAC,CAAC,KAAK,WAAY;AAChI"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/native/foldable/types.d.ts
|
|
2
|
+
export interface FoldState {
|
|
3
|
+
state: 'flat' | 'half-opened' | 'closed';
|
|
4
|
+
hingeBounds?: {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/native/foldable/types.ts"],"mappings":";iBAAiB;EACf;EACA;IAAgB;IAAW;IAAW;IAAe"}
|
|
File without changes
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Candidate, Identify } from "./shared/candidate.js";
|
|
2
|
+
import { NativeUIRuntimeHandle, NativeUIRuntimeOptions } from "./definitions.js";
|
|
3
|
+
//#region src/native/html.d.ts
|
|
4
|
+
export declare const htmlSelector = "[data-native-ui=\"button\"], [data-native-ui=\"back-button\"]";
|
|
5
|
+
export declare const htmlRailSource: (element: Element) => boolean;
|
|
6
|
+
export declare const readHTMLControl: (element: HTMLElement, id: Identify, options: NativeUIRuntimeOptions) => Candidate | undefined;
|
|
7
|
+
export declare const createHTMLWebProjection: (doc: Document, options: NativeUIRuntimeOptions) => NativeUIRuntimeHandle;
|
|
8
|
+
//#endregion
|
|
9
|
+
//# sourceMappingURL=html.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.d.ts","names":[],"sources":["../../src/native/html.ts"],"mappings":";;;qBAMa;qBACA,iBAAkB,SAAS;qBAG3B,kBAAmB,SAAS,aAAa,IAAI,UAAU,SAAS,2BAAyB;qBAoCzF,0BAA2B,KAAK,UAAU,SAAS,2BAAyB"}
|