craft-native 0.0.122 → 0.0.124
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 +3 -0
- package/dist/android/src/index.d.ts +3 -0
- package/dist/android/src/index.js +17 -0
- package/dist/android/templates/AndroidManifest.xml.template +1 -1
- package/dist/android/templates/CraftNativeFlatList.kt.template +113 -6
- package/dist/android/templates/MainActivity.kt.template +17 -0
- package/dist/android/templates/MainActivityNative.kt.template +826 -68
- package/dist/api/mobile.d.ts +251 -0
- package/dist/cli.js +1 -1
- package/dist/index.cjs +22 -1
- package/dist/index.js +22 -1
- package/dist/ios/src/index.d.ts +90 -2
- package/dist/ios/src/index.js +177 -44
- package/dist/ios/templates/CraftApp.swift +1341 -51
- package/dist/ios/templates/CraftNativeActions.swift +97 -9
- package/dist/ios/templates/CraftNativeFlatList.swift +92 -12
- package/dist/ios/templates/CraftNativeScreen.swift +876 -64
- package/dist/ios/templates/CraftNativeUI.swift +562 -0
- package/dist/ios/templates/Info.plist.template +3 -3
- package/dist/mobile.js +187 -0
- package/package.json +1 -1
package/dist/api/mobile.d.ts
CHANGED
|
@@ -203,6 +203,14 @@ export declare const haptics: {
|
|
|
203
203
|
* Use when a selection changes (e.g., picker value change).
|
|
204
204
|
*/
|
|
205
205
|
selection(): Promise<void>;
|
|
206
|
+
/**
|
|
207
|
+
* Warm the haptic engine ahead of a haptic the page knows is coming (the
|
|
208
|
+
* start of a drag, a long press about to complete), so it plays on the frame
|
|
209
|
+
* it is asked for. `impact`, `notification` or `selection` for one kind, an
|
|
210
|
+
* impact style or notification type for that one, nothing for all. iOS keeps
|
|
211
|
+
* a prepared engine awake for a few seconds. A no-op elsewhere.
|
|
212
|
+
*/
|
|
213
|
+
prepare(kind?: HapticStyle | HapticNotificationType | 'impact' | 'notification' | 'selection'): Promise<void>;
|
|
206
214
|
/**
|
|
207
215
|
* Vibrate with a custom pattern.
|
|
208
216
|
*
|
|
@@ -608,6 +616,18 @@ export declare const lifecycle: {
|
|
|
608
616
|
* @returns Function to remove listener
|
|
609
617
|
*/
|
|
610
618
|
onStateChange(callback: (state: AppState) => void): () => void;
|
|
619
|
+
/**
|
|
620
|
+
* The app came back to the foreground (`craftResume`), with how long it was
|
|
621
|
+
* away. A page can refresh what may have gone stale. iOS shell only.
|
|
622
|
+
*/
|
|
623
|
+
onResume(callback: (event: {
|
|
624
|
+
backgroundedMs: number;
|
|
625
|
+
}) => void): () => void;
|
|
626
|
+
/**
|
|
627
|
+
* iOS is short of memory (`craftMemoryWarning`): drop caches, or the page's
|
|
628
|
+
* content process may be ended. iOS shell only.
|
|
629
|
+
*/
|
|
630
|
+
onMemoryWarning(callback: () => void): () => void;
|
|
611
631
|
};
|
|
612
632
|
/**
|
|
613
633
|
* Notification options.
|
|
@@ -754,6 +774,226 @@ export declare const network: {
|
|
|
754
774
|
getStatus(): Promise<NetworkStatus>;
|
|
755
775
|
onChange(callback: (status: NetworkStatus) => void): () => void;
|
|
756
776
|
};
|
|
777
|
+
/** A tab the native tab bar shows. */
|
|
778
|
+
export interface NativeTab {
|
|
779
|
+
/** Comes back in `onSelect` when the tab is tapped. */
|
|
780
|
+
id: string;
|
|
781
|
+
title: string;
|
|
782
|
+
/** An SF Symbol name, such as `calendar`; the current tab draws its `.fill` variant when there is one. */
|
|
783
|
+
symbol: string;
|
|
784
|
+
/** A count on the icon; empty draws none. */
|
|
785
|
+
badge?: string;
|
|
786
|
+
}
|
|
787
|
+
export interface NativeTabBarOptions {
|
|
788
|
+
/** The current tab's id. */
|
|
789
|
+
selected?: string;
|
|
790
|
+
/** The current tab's colour, as `#rrggbb`; the system's label colour if unset. */
|
|
791
|
+
tint?: string;
|
|
792
|
+
tintDark?: string;
|
|
793
|
+
}
|
|
794
|
+
/**
|
|
795
|
+
* The phone's own tab bar, floating over the page: Liquid Glass on iOS 26 and
|
|
796
|
+
* later. The page describes it and keeps it on the current tab; a tap comes
|
|
797
|
+
* back through `onSelect` for the page to navigate. Where there is no native
|
|
798
|
+
* bar (a browser, Android for now), `isAvailable()` is false and every call is
|
|
799
|
+
* a no-op answering false, so the page draws its own.
|
|
800
|
+
*
|
|
801
|
+
* While the bar shows, `--craft-tab-bar-height` on the root element says how
|
|
802
|
+
* much of the screen's bottom it covers.
|
|
803
|
+
*/
|
|
804
|
+
export declare const tabBar: {
|
|
805
|
+
isAvailable(): boolean;
|
|
806
|
+
set(tabs: NativeTab[], options?: NativeTabBarOptions): boolean;
|
|
807
|
+
select(id: string): boolean;
|
|
808
|
+
hide(): boolean;
|
|
809
|
+
onSelect(callback: (id: string) => void): () => void;
|
|
810
|
+
};
|
|
811
|
+
/**
|
|
812
|
+
* The launch splash, which the shell holds over the page until the page says
|
|
813
|
+
* it is ready, so the app goes from its launch screen to content with no blank
|
|
814
|
+
* page in between. Call `hide()` once the first screen has painted. The shell
|
|
815
|
+
* hides it anyway once the page's first contentful paint is on screen, and
|
|
816
|
+
* after `splashMaxSeconds` (three by default) at most.
|
|
817
|
+
*/
|
|
818
|
+
export declare const splash: {
|
|
819
|
+
hide(): boolean;
|
|
820
|
+
};
|
|
821
|
+
/** A rect in the viewport's CSS pixels. */
|
|
822
|
+
export interface NativeRect {
|
|
823
|
+
x: number;
|
|
824
|
+
y: number;
|
|
825
|
+
width: number;
|
|
826
|
+
height: number;
|
|
827
|
+
}
|
|
828
|
+
/** Where a popover, sheet or menu points: a rect, or an element to point at. */
|
|
829
|
+
export type NativeAnchor = NativeRect | {
|
|
830
|
+
getBoundingClientRect(): {
|
|
831
|
+
left: number;
|
|
832
|
+
top: number;
|
|
833
|
+
width: number;
|
|
834
|
+
height: number;
|
|
835
|
+
};
|
|
836
|
+
};
|
|
837
|
+
export interface DialogAlertOptions {
|
|
838
|
+
title: string;
|
|
839
|
+
message?: string;
|
|
840
|
+
/** The button. The system's own "OK" if unset. */
|
|
841
|
+
okLabel?: string;
|
|
842
|
+
}
|
|
843
|
+
export interface DialogConfirmOptions {
|
|
844
|
+
title: string;
|
|
845
|
+
message?: string;
|
|
846
|
+
/** The confirming button. The system's own "OK" if unset. */
|
|
847
|
+
confirmLabel?: string;
|
|
848
|
+
/** The system's own "Cancel" if unset. */
|
|
849
|
+
cancelLabel?: string;
|
|
850
|
+
/** Paints the confirming button red, as iOS does for a delete. */
|
|
851
|
+
destructive?: boolean;
|
|
852
|
+
}
|
|
853
|
+
export interface ActionSheetAction {
|
|
854
|
+
id: string;
|
|
855
|
+
title: string;
|
|
856
|
+
/** `cancel` answers `null` whatever its id. */
|
|
857
|
+
style?: 'default' | 'destructive' | 'cancel';
|
|
858
|
+
}
|
|
859
|
+
export interface ActionSheetOptions {
|
|
860
|
+
title?: string;
|
|
861
|
+
message?: string;
|
|
862
|
+
actions: ActionSheetAction[];
|
|
863
|
+
/** Where the sheet points on iPad (and, from iOS 26, on iPhone). */
|
|
864
|
+
anchor?: NativeAnchor;
|
|
865
|
+
}
|
|
866
|
+
export interface ContextMenuItem {
|
|
867
|
+
id: string;
|
|
868
|
+
title: string;
|
|
869
|
+
/** An SF Symbol name, such as `trash`. */
|
|
870
|
+
symbol?: string;
|
|
871
|
+
destructive?: boolean;
|
|
872
|
+
disabled?: boolean;
|
|
873
|
+
}
|
|
874
|
+
export interface ContextMenuOptions {
|
|
875
|
+
items: ContextMenuItem[];
|
|
876
|
+
anchor: NativeAnchor;
|
|
877
|
+
title?: string;
|
|
878
|
+
}
|
|
879
|
+
export interface BrowserOpenOptions {
|
|
880
|
+
/** `safari`: SFSafariViewController in the app. `auth`: the system's web sign-in sheet. */
|
|
881
|
+
mode?: 'safari' | 'auth';
|
|
882
|
+
/** For `auth`: the URL scheme the provider redirects back to. */
|
|
883
|
+
callbackScheme?: string;
|
|
884
|
+
}
|
|
885
|
+
export interface BrowserOpenResult {
|
|
886
|
+
/** For `auth`: the callback URL the provider redirected to. */
|
|
887
|
+
url?: string;
|
|
888
|
+
cancelled: boolean;
|
|
889
|
+
error?: string;
|
|
890
|
+
}
|
|
891
|
+
export type SymbolWeight = 'ultraLight' | 'thin' | 'light' | 'regular' | 'medium' | 'semibold' | 'bold' | 'heavy' | 'black';
|
|
892
|
+
export interface SymbolImageOptions {
|
|
893
|
+
/** Default 17. */
|
|
894
|
+
pointSize?: number;
|
|
895
|
+
weight?: SymbolWeight;
|
|
896
|
+
/** A CSS colour. The label colour if unset. */
|
|
897
|
+
color?: string;
|
|
898
|
+
scale?: 'small' | 'medium' | 'large';
|
|
899
|
+
}
|
|
900
|
+
export type StatusBarStyle = 'default' | 'light' | 'dark';
|
|
901
|
+
/** The reading and motion settings the page should match. */
|
|
902
|
+
export interface NativeAppearance {
|
|
903
|
+
/** The Dynamic Type size, as UIKit names it: `large` is the default. */
|
|
904
|
+
contentSizeCategory: string;
|
|
905
|
+
/** Body text's scale from its default size; also `--craft-font-scale` on the root element. */
|
|
906
|
+
fontScale: number;
|
|
907
|
+
reduceMotion: boolean;
|
|
908
|
+
reduceTransparency: boolean;
|
|
909
|
+
colorScheme: 'light' | 'dark';
|
|
910
|
+
}
|
|
911
|
+
/** A `craftSilentPush` or `craftBackgroundRefresh`. */
|
|
912
|
+
export interface BackgroundWorkEvent {
|
|
913
|
+
/** Pass to `background.complete` to answer this one. */
|
|
914
|
+
id?: string;
|
|
915
|
+
/** The push's payload, for a silent push. */
|
|
916
|
+
payload?: Record<string, unknown>;
|
|
917
|
+
}
|
|
918
|
+
/**
|
|
919
|
+
* The system's alert, confirmation and action sheet. Off the iOS shell every
|
|
920
|
+
* call resolves without showing anything (`confirm` with false, `actionSheet`
|
|
921
|
+
* with null), so check `isAvailable()` to draw a web fallback.
|
|
922
|
+
*/
|
|
923
|
+
export declare const dialog: {
|
|
924
|
+
isAvailable(): boolean;
|
|
925
|
+
alert(options: DialogAlertOptions | string): Promise<void>;
|
|
926
|
+
confirm(options: DialogConfirmOptions | string): Promise<boolean>;
|
|
927
|
+
/** The chosen action's id, or null when dismissed. */
|
|
928
|
+
actionSheet(options: ActionSheetOptions): Promise<string | null>;
|
|
929
|
+
};
|
|
930
|
+
/**
|
|
931
|
+
* The system's context menu, anchored at a rect or element: the list with SF
|
|
932
|
+
* Symbols a long press shows (iOS 17.4 and later; the edit menu, then an
|
|
933
|
+
* action sheet, before). The chosen item's id, or null when dismissed.
|
|
934
|
+
*/
|
|
935
|
+
export declare const contextMenu: {
|
|
936
|
+
isAvailable(): boolean;
|
|
937
|
+
show(options: ContextMenuOptions): Promise<string | null>;
|
|
938
|
+
};
|
|
939
|
+
/**
|
|
940
|
+
* A page elsewhere without leaving the app: SFSafariViewController, or for
|
|
941
|
+
* `mode: 'auth'` the system's web sign-in sheet, which answers with the
|
|
942
|
+
* callback URL. On the web, `safari` opens a new tab and `auth` cannot catch
|
|
943
|
+
* the callback, so it answers cancelled.
|
|
944
|
+
*/
|
|
945
|
+
export declare const browser: {
|
|
946
|
+
isAvailable(): boolean;
|
|
947
|
+
open(url: string, options?: BrowserOpenOptions): Promise<BrowserOpenResult>;
|
|
948
|
+
};
|
|
949
|
+
/** An SF Symbol rasterised to a PNG data URL, or null where there are none. */
|
|
950
|
+
export declare const symbols: {
|
|
951
|
+
image(name: string, options?: SymbolImageOptions): Promise<string | null>;
|
|
952
|
+
};
|
|
953
|
+
/** The status bar's text: light, dark, or the system's choice for the app's appearance. */
|
|
954
|
+
export declare const statusBar: {
|
|
955
|
+
setStyle(style: StatusBarStyle): Promise<boolean>;
|
|
956
|
+
};
|
|
957
|
+
/** The shell's chrome around the page. */
|
|
958
|
+
export declare const chrome: {
|
|
959
|
+
/** What shows past the page's edges when it rubber-bands (iOS 15). */
|
|
960
|
+
setUnderPageColor(color: string): Promise<boolean>;
|
|
961
|
+
/** WebKit's bar above the keyboard (previous, next, Done). Hidden by default. */
|
|
962
|
+
setKeyboardAccessory(visible: boolean): Promise<boolean>;
|
|
963
|
+
};
|
|
964
|
+
/**
|
|
965
|
+
* The system's pull-to-refresh on the page's scroll view. A pull fires
|
|
966
|
+
* `onRefresh`; call `end()` once the new content is in. It is removed when the
|
|
967
|
+
* document changes, so a page enables it for itself.
|
|
968
|
+
*/
|
|
969
|
+
export declare const refresh: {
|
|
970
|
+
isAvailable(): boolean;
|
|
971
|
+
enable(options?: {
|
|
972
|
+
tintColor?: string;
|
|
973
|
+
}): Promise<boolean>;
|
|
974
|
+
disable(): Promise<boolean>;
|
|
975
|
+
end(): Promise<boolean>;
|
|
976
|
+
onRefresh(callback: () => void): () => void;
|
|
977
|
+
};
|
|
978
|
+
/**
|
|
979
|
+
* Background time on iOS: a silent push (`content-available`) and the
|
|
980
|
+
* scheduled refresh (`backgroundRefresh.enabled` in the Craft config). Each
|
|
981
|
+
* waits for `complete(ok)` from the page, or 25 seconds.
|
|
982
|
+
*/
|
|
983
|
+
export declare const background: {
|
|
984
|
+
complete(ok?: boolean, id?: string): Promise<boolean>;
|
|
985
|
+
onRefresh(callback: (event: BackgroundWorkEvent) => void): () => void;
|
|
986
|
+
onSilentPush(callback: (event: BackgroundWorkEvent) => void): () => void;
|
|
987
|
+
};
|
|
988
|
+
/**
|
|
989
|
+
* Text size, Reduce Motion, Reduce Transparency and Light or Dark. In the iOS
|
|
990
|
+
* shell from the native settings (Dynamic Type included, which a web page
|
|
991
|
+
* cannot otherwise see); elsewhere from the media queries a browser has.
|
|
992
|
+
*/
|
|
993
|
+
export declare const appearance: {
|
|
994
|
+
get(): NativeAppearance | null;
|
|
995
|
+
onChange(callback: (appearance: NativeAppearance) => void): () => void;
|
|
996
|
+
};
|
|
757
997
|
export declare const appReview: {
|
|
758
998
|
request(): Promise<boolean>;
|
|
759
999
|
};
|
|
@@ -911,5 +1151,16 @@ declare const mobile: {
|
|
|
911
1151
|
health: typeof health;
|
|
912
1152
|
liveActivities: typeof liveActivities;
|
|
913
1153
|
watchConnectivity: typeof watchConnectivity;
|
|
1154
|
+
tabBar: typeof tabBar;
|
|
1155
|
+
splash: typeof splash;
|
|
1156
|
+
dialog: typeof dialog;
|
|
1157
|
+
contextMenu: typeof contextMenu;
|
|
1158
|
+
browser: typeof browser;
|
|
1159
|
+
symbols: typeof symbols;
|
|
1160
|
+
statusBar: typeof statusBar;
|
|
1161
|
+
chrome: typeof chrome;
|
|
1162
|
+
refresh: typeof refresh;
|
|
1163
|
+
background: typeof background;
|
|
1164
|
+
appearance: typeof appearance;
|
|
914
1165
|
};
|
|
915
1166
|
export default mobile;
|
package/dist/cli.js
CHANGED
|
@@ -3303,7 +3303,7 @@ function pinCraftNativeDependency(packagePath, craftVersion) {
|
|
|
3303
3303
|
`);
|
|
3304
3304
|
}
|
|
3305
3305
|
// package.json
|
|
3306
|
-
var version = "0.0.
|
|
3306
|
+
var version = "0.0.124";
|
|
3307
3307
|
|
|
3308
3308
|
// bin/cli.ts
|
|
3309
3309
|
var spawnedFrom = process6.env[CRAFT_CLI_SPAWN_MARKER];
|
package/dist/index.cjs
CHANGED
|
@@ -310,7 +310,7 @@ function craftBinaryNotFoundMessage(triedPath) {
|
|
|
310
310
|
`);
|
|
311
311
|
}
|
|
312
312
|
// package.json
|
|
313
|
-
var version = "0.0.
|
|
313
|
+
var version = "0.0.124";
|
|
314
314
|
|
|
315
315
|
// src/sdk-version.ts
|
|
316
316
|
var SDK_VERSION = version;
|
|
@@ -4885,6 +4885,14 @@ var haptics = {
|
|
|
4885
4885
|
navigator.vibrate(5);
|
|
4886
4886
|
}
|
|
4887
4887
|
},
|
|
4888
|
+
async prepare(kind) {
|
|
4889
|
+
const craft = getCraftMobile();
|
|
4890
|
+
if (typeof window !== "undefined" && craft?.haptics?.prepare) {
|
|
4891
|
+
try {
|
|
4892
|
+
await craft.haptics.prepare(kind);
|
|
4893
|
+
} catch {}
|
|
4894
|
+
}
|
|
4895
|
+
},
|
|
4888
4896
|
async vibrate(pattern) {
|
|
4889
4897
|
const craft = getCraftMobile();
|
|
4890
4898
|
if (typeof window !== "undefined" && craft?.haptics) {
|
|
@@ -5256,6 +5264,12 @@ var lifecycle = {
|
|
|
5256
5264
|
};
|
|
5257
5265
|
document.addEventListener("visibilitychange", handler);
|
|
5258
5266
|
return () => document.removeEventListener("visibilitychange", handler);
|
|
5267
|
+
},
|
|
5268
|
+
onResume(callback) {
|
|
5269
|
+
return onCraftEvent("craftResume", (detail) => callback({ backgroundedMs: Number(detail.backgroundedMs) || 0 }));
|
|
5270
|
+
},
|
|
5271
|
+
onMemoryWarning(callback) {
|
|
5272
|
+
return onCraftEvent("craftMemoryWarning", () => callback());
|
|
5259
5273
|
}
|
|
5260
5274
|
};
|
|
5261
5275
|
function bridgeNotification(options, now = Date.now()) {
|
|
@@ -5310,6 +5324,13 @@ var notifications = {
|
|
|
5310
5324
|
}
|
|
5311
5325
|
};
|
|
5312
5326
|
var speakingOnTheWeb = new Set;
|
|
5327
|
+
function onCraftEvent(eventName, callback) {
|
|
5328
|
+
if (typeof globalThis === "undefined")
|
|
5329
|
+
return () => {};
|
|
5330
|
+
const listener = (event) => callback(event.detail ?? {});
|
|
5331
|
+
globalThis.addEventListener(eventName, listener);
|
|
5332
|
+
return () => globalThis.removeEventListener(eventName, listener);
|
|
5333
|
+
}
|
|
5313
5334
|
function detectPlatform2() {
|
|
5314
5335
|
if (typeof window === "undefined")
|
|
5315
5336
|
return "linux";
|
package/dist/index.js
CHANGED
|
@@ -58,7 +58,7 @@ function craftBinaryNotFoundMessage(triedPath) {
|
|
|
58
58
|
`);
|
|
59
59
|
}
|
|
60
60
|
// package.json
|
|
61
|
-
var version = "0.0.
|
|
61
|
+
var version = "0.0.124";
|
|
62
62
|
|
|
63
63
|
// src/sdk-version.ts
|
|
64
64
|
var SDK_VERSION = version;
|
|
@@ -4645,6 +4645,14 @@ var haptics = {
|
|
|
4645
4645
|
navigator.vibrate(5);
|
|
4646
4646
|
}
|
|
4647
4647
|
},
|
|
4648
|
+
async prepare(kind) {
|
|
4649
|
+
const craft = getCraftMobile();
|
|
4650
|
+
if (typeof window !== "undefined" && craft?.haptics?.prepare) {
|
|
4651
|
+
try {
|
|
4652
|
+
await craft.haptics.prepare(kind);
|
|
4653
|
+
} catch {}
|
|
4654
|
+
}
|
|
4655
|
+
},
|
|
4648
4656
|
async vibrate(pattern) {
|
|
4649
4657
|
const craft = getCraftMobile();
|
|
4650
4658
|
if (typeof window !== "undefined" && craft?.haptics) {
|
|
@@ -5016,6 +5024,12 @@ var lifecycle = {
|
|
|
5016
5024
|
};
|
|
5017
5025
|
document.addEventListener("visibilitychange", handler);
|
|
5018
5026
|
return () => document.removeEventListener("visibilitychange", handler);
|
|
5027
|
+
},
|
|
5028
|
+
onResume(callback) {
|
|
5029
|
+
return onCraftEvent("craftResume", (detail) => callback({ backgroundedMs: Number(detail.backgroundedMs) || 0 }));
|
|
5030
|
+
},
|
|
5031
|
+
onMemoryWarning(callback) {
|
|
5032
|
+
return onCraftEvent("craftMemoryWarning", () => callback());
|
|
5019
5033
|
}
|
|
5020
5034
|
};
|
|
5021
5035
|
function bridgeNotification(options, now = Date.now()) {
|
|
@@ -5070,6 +5084,13 @@ var notifications = {
|
|
|
5070
5084
|
}
|
|
5071
5085
|
};
|
|
5072
5086
|
var speakingOnTheWeb = new Set;
|
|
5087
|
+
function onCraftEvent(eventName, callback) {
|
|
5088
|
+
if (typeof globalThis === "undefined")
|
|
5089
|
+
return () => {};
|
|
5090
|
+
const listener = (event) => callback(event.detail ?? {});
|
|
5091
|
+
globalThis.addEventListener(eventName, listener);
|
|
5092
|
+
return () => globalThis.removeEventListener(eventName, listener);
|
|
5093
|
+
}
|
|
5073
5094
|
function detectPlatform2() {
|
|
5074
5095
|
if (typeof window === "undefined")
|
|
5075
5096
|
return "linux";
|
package/dist/ios/src/index.d.ts
CHANGED
|
@@ -78,13 +78,42 @@ export interface CraftConfig {
|
|
|
78
78
|
/**
|
|
79
79
|
* Also refuse to load anything but the app-bound domains in the web view
|
|
80
80
|
* (WKWebViewConfiguration.limitsNavigationsToAppBoundDomains). Off by
|
|
81
|
-
* default: links elsewhere already open in Safari
|
|
82
|
-
* maps in
|
|
81
|
+
* default: links elsewhere already open in Safari. WebKit applies the limit
|
|
82
|
+
* to the main frame only, so embedded players and maps in cross-origin
|
|
83
|
+
* iframes (YouTube, Vimeo) keep loading with it on (checked in the iOS 26
|
|
84
|
+
* simulator); WebKit only declines to inject user scripts into them, which
|
|
85
|
+
* the bridge never does.
|
|
83
86
|
*/
|
|
84
87
|
limitNavigationsToAppBoundDomains?: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Universal links and shared web credentials
|
|
90
|
+
* (`com.apple.developer.associated-domains`). A bare host such as
|
|
91
|
+
* `hq.training` is written as `applinks:hq.training`; an entry with its own
|
|
92
|
+
* service (`webcredentials:`, `applinks:…?mode=developer`) is kept as given.
|
|
93
|
+
* A universal link reaches the page the way a custom-scheme link does, as
|
|
94
|
+
* `craftDeepLink`.
|
|
95
|
+
*/
|
|
85
96
|
associatedDomains?: string[];
|
|
97
|
+
/**
|
|
98
|
+
* iOS's scheduled background refresh (BGAppRefreshTask). When enabled the
|
|
99
|
+
* page gets `craftBackgroundRefresh` and answers with
|
|
100
|
+
* `craft.background.complete(ok)`. The identifier defaults to
|
|
101
|
+
* `<bundleId>.refresh` and is declared in BGTaskSchedulerPermittedIdentifiers,
|
|
102
|
+
* with the `fetch` background mode.
|
|
103
|
+
*/
|
|
104
|
+
backgroundRefresh?: CraftBackgroundRefresh;
|
|
86
105
|
appGroups?: string[];
|
|
87
106
|
appIconPath?: string;
|
|
107
|
+
/**
|
|
108
|
+
* The logo the launch screen shows on `backgroundColor`, and that stays on
|
|
109
|
+
* screen until the page says it is ready (`splash.hide()`), so the app goes
|
|
110
|
+
* from launch to content without a blank web view in between. PNG, PDF or
|
|
111
|
+
* SVG, drawn at its own size in points: give an SVG the width and height it
|
|
112
|
+
* should have on screen.
|
|
113
|
+
*/
|
|
114
|
+
splashImagePath?: string;
|
|
115
|
+
/** The splash logo in Dark Mode, on `backgroundColorDark`. The light one if unset. */
|
|
116
|
+
splashImagePathDark?: string;
|
|
88
117
|
/**
|
|
89
118
|
* Whether the app uses encryption beyond the exempt kinds (HTTPS, the
|
|
90
119
|
* system's own). Written as `ITSAppUsesNonExemptEncryption`, so App Store
|
|
@@ -93,9 +122,36 @@ export interface CraftConfig {
|
|
|
93
122
|
*/
|
|
94
123
|
usesNonExemptEncryption?: boolean;
|
|
95
124
|
privacy?: CraftPrivacyManifest;
|
|
125
|
+
/** Press-and-hold link previews, as in Safari. Default false. */
|
|
126
|
+
allowsLinkPreview?: boolean;
|
|
127
|
+
/**
|
|
128
|
+
* WebKit's bar above the keyboard for a form field (previous, next, Done),
|
|
129
|
+
* which no native app's keyboard has. Default false: hidden. A page can
|
|
130
|
+
* change it with `craft.chrome.setKeyboardAccessory()`.
|
|
131
|
+
*/
|
|
132
|
+
keyboardAccessory?: boolean;
|
|
133
|
+
/** Pinch and double-tap zoom off, and the page's viewport pinned at scale 1. Default true. */
|
|
134
|
+
disableZoom?: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* The longest the launch splash stays up, in seconds, when the page neither
|
|
137
|
+
* hides it (`splash.hide()`) nor paints. Default 3.
|
|
138
|
+
*/
|
|
139
|
+
splashMaxSeconds?: number;
|
|
140
|
+
/**
|
|
141
|
+
* How long the app's own page may take to answer, in seconds, before the
|
|
142
|
+
* load counts as unreachable and the bundled page stands in. Default 10.
|
|
143
|
+
*/
|
|
144
|
+
requestTimeoutSeconds?: number;
|
|
96
145
|
orientations?: Array<'portrait' | 'landscape-left' | 'landscape-right' | 'portrait-upside-down'>;
|
|
97
146
|
deviceFamilies?: Array<'iphone' | 'ipad'>;
|
|
98
147
|
}
|
|
148
|
+
export interface CraftBackgroundRefresh {
|
|
149
|
+
enabled: boolean;
|
|
150
|
+
/** The BGTaskScheduler identifier. Default `<bundleId>.refresh`. */
|
|
151
|
+
identifier?: string;
|
|
152
|
+
/** The soonest iOS may run it again, in minutes. Default 15. */
|
|
153
|
+
minimumIntervalMinutes?: number;
|
|
154
|
+
}
|
|
99
155
|
export interface CraftPrivacyDataType {
|
|
100
156
|
type: string;
|
|
101
157
|
linked?: boolean;
|
|
@@ -175,6 +231,16 @@ export declare function renderOrientations(config: CraftConfig): string;
|
|
|
175
231
|
export declare function renderAppBoundDomains(config: CraftConfig): string;
|
|
176
232
|
export declare function renderUrlTypes(config: CraftConfig): string;
|
|
177
233
|
export declare function renderBackgroundModes(config: CraftConfig): string;
|
|
234
|
+
/** The background refresh task's identifier, or null when it is off. */
|
|
235
|
+
export declare function backgroundRefreshIdentifier(config: Pick<CraftConfig, 'backgroundRefresh' | 'bundleId'>): string | null;
|
|
236
|
+
/** BGTaskSchedulerPermittedIdentifiers: iOS runs no task it does not list. */
|
|
237
|
+
export declare function renderBackgroundTaskIdentifiers(config: Pick<CraftConfig, 'backgroundRefresh' | 'bundleId'>): string;
|
|
238
|
+
/**
|
|
239
|
+
* The associated-domains entitlement's entries. Each needs a service prefix,
|
|
240
|
+
* and a bare host (the easy thing to write) used to be signed as it was and
|
|
241
|
+
* then matched nothing, so universal links silently never opened the app.
|
|
242
|
+
*/
|
|
243
|
+
export declare function associatedDomainEntries(domains: string[] | undefined): string[];
|
|
178
244
|
export declare function renderEntitlements(config: CraftConfig): string;
|
|
179
245
|
export declare function renderWatchEntitlements(config: CraftConfig): string;
|
|
180
246
|
/**
|
|
@@ -205,6 +271,28 @@ export declare function renderPrivacyManifest(config: CraftConfig): string;
|
|
|
205
271
|
* (grey + alpha) or 6 (RGB + alpha), or a tRNS chunk before the image data.
|
|
206
272
|
*/
|
|
207
273
|
export declare function pngHasAlpha(bytes: Uint8Array): boolean;
|
|
274
|
+
/** The asset the launch screen and the splash both draw, so one hands over to the other unseen. */
|
|
275
|
+
export declare const LAUNCH_LOGO = "LaunchLogo";
|
|
276
|
+
/** The launch screen: the background colour, and the splash logo on it when there is one. */
|
|
277
|
+
export declare function renderLaunchScreen(config: Pick<CraftConfig, 'splashImagePath'>): string;
|
|
278
|
+
/** Near-black or near-white, whichever reads on `background` (WCAG relative luminance). */
|
|
279
|
+
export declare function readableTextOn(background: string | undefined): string;
|
|
280
|
+
/**
|
|
281
|
+
* The page the app shows when its own page cannot be reached: the generated
|
|
282
|
+
* `dist/index.html` until the app's web assets replace it.
|
|
283
|
+
*
|
|
284
|
+
* An app whose page has a service worker normally opens from it offline, so
|
|
285
|
+
* this only shows on a first launch without one, or when the remote fails
|
|
286
|
+
* hard. It used to be a placeholder that said "Built with Craft iOS" in white
|
|
287
|
+
* on whatever the background was (invisible on a light one) with a bridge
|
|
288
|
+
* status line under it: debug output, in front of the person using the app.
|
|
289
|
+
*
|
|
290
|
+
* Now it says what happened in the app's own colours, light and dark, sized
|
|
291
|
+
* with Dynamic Type, and Retry asks the shell to load the app's page again.
|
|
292
|
+
* The shell also goes back to the app's page by itself when the connection
|
|
293
|
+
* returns, so the page does not retry on `online` as well.
|
|
294
|
+
*/
|
|
295
|
+
export declare function renderOfflinePage(config: Pick<CraftConfig, 'appName' | 'backgroundColor' | 'backgroundColorDark'>): string;
|
|
208
296
|
/** Replace the bundled web application atomically so removed assets cannot linger. */
|
|
209
297
|
export declare function syncWebAssets(source: string, output: string): void;
|
|
210
298
|
/**
|