@ng-native/expo 0.13.0 → 0.15.0
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/android/build.gradle +4 -0
- package/android/src/main/java/dev/ngnative/expo/SearchFieldModule.kt +172 -0
- package/dist/app-info.d.ts +18 -15
- package/dist/app-info.js +17 -5
- package/dist/app-info.js.map +1 -1
- package/dist/apple-sign-in.js +5 -4
- package/dist/apple-sign-in.js.map +1 -1
- package/dist/assets.js +2 -2
- package/dist/assets.js.map +1 -1
- package/dist/async-storage.js +4 -1
- package/dist/async-storage.js.map +1 -1
- package/dist/audio.js +2 -2
- package/dist/audio.js.map +1 -1
- package/dist/battery.js +4 -1
- package/dist/battery.js.map +1 -1
- package/dist/biometrics.js +5 -4
- package/dist/biometrics.js.map +1 -1
- package/dist/brightness.js +7 -2
- package/dist/brightness.js.map +1 -1
- package/dist/camera.d.ts +28 -2
- package/dist/camera.js +30 -3
- package/dist/camera.js.map +1 -1
- package/dist/clipboard.js +5 -2
- package/dist/clipboard.js.map +1 -1
- package/dist/database.js +2 -2
- package/dist/database.js.map +1 -1
- package/dist/expo-ui-components.d.ts +127 -12
- package/dist/expo-ui-components.js +354 -48
- package/dist/expo-ui-components.js.map +1 -1
- package/dist/expo-ui.js +7 -1
- package/dist/expo-ui.js.map +1 -1
- package/dist/foldable.d.ts +2 -0
- package/dist/foldable.js +15 -5
- package/dist/foldable.js.map +1 -1
- package/dist/fonts.d.ts +2 -0
- package/dist/fonts.js +12 -14
- package/dist/fonts.js.map +1 -1
- package/dist/haptics.js +2 -2
- package/dist/haptics.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/language-model.js +7 -3
- package/dist/language-model.js.map +1 -1
- package/dist/native.d.ts +17 -2
- package/dist/native.js +61 -3
- package/dist/native.js.map +1 -1
- package/dist/network.js +4 -1
- package/dist/network.js.map +1 -1
- package/dist/notifications.js +35 -8
- package/dist/notifications.js.map +1 -1
- package/dist/observed.js +5 -1
- package/dist/observed.js.map +1 -1
- package/dist/orientation.js +4 -1
- package/dist/orientation.js.map +1 -1
- package/dist/player.d.ts +9 -2
- package/dist/player.js +3 -2
- package/dist/player.js.map +1 -1
- package/dist/register-expo-view.d.ts +25 -2
- package/dist/register-expo-view.js +28 -7
- package/dist/register-expo-view.js.map +1 -1
- package/dist/screen-capture.js +2 -2
- package/dist/screen-capture.js.map +1 -1
- package/dist/search-field.d.ts +85 -0
- package/dist/search-field.js +160 -0
- package/dist/search-field.js.map +1 -0
- package/dist/secure-store.js +4 -1
- package/dist/secure-store.js.map +1 -1
- package/dist/sensors.js +6 -3
- package/dist/sensors.js.map +1 -1
- package/dist/splash-screen.js +2 -2
- package/dist/splash-screen.js.map +1 -1
- package/dist/store.js +4 -0
- package/dist/store.js.map +1 -1
- package/dist/tracking.js +2 -2
- package/dist/tracking.js.map +1 -1
- package/dist/ui-bottom-sheet-view.d.ts +3 -1
- package/dist/ui-bottom-sheet-view.js +6 -2
- package/dist/ui-bottom-sheet-view.js.map +1 -1
- package/dist/ui-font-names.d.ts +16 -0
- package/dist/ui-font-names.js +71 -0
- package/dist/ui-font-names.js.map +1 -0
- package/dist/updates.js +4 -1
- package/dist/updates.js.map +1 -1
- package/dist/video.js +3 -3
- package/dist/video.js.map +1 -1
- package/dist/watch.js +6 -5
- package/dist/watch.js.map +1 -1
- package/expo-module.config.json +5 -2
- package/ios/ExpoUIModifiersModule.swift +25 -0
- package/ios/InlineNavigationTitle.swift +12 -0
- package/ios/NgNativeExpo.podspec +3 -0
- package/ios/SearchField.swift +200 -0
- package/ios/SegmentedFont.swift +113 -0
- package/package.json +6 -2
package/dist/brightness.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brightness.js","sourceRoot":"","sources":["../src/brightness.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAe,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;;
|
|
1
|
+
{"version":3,"file":"brightness.js","sourceRoot":"","sources":["../src/brightness.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `Brightness`, bound to `expo-brightness`.\n *\n * For the screens that have a reason to change it: a boarding pass, a QR code.\n *\n * The app's own brightness only. The system one is a global setting an app can leave changed\n * after it is gone, and needs a permission on Android - a decision to make deliberately against\n * Expo's own API rather than to reach through a convenience here.\n */\nimport { InjectionToken, Service, inject, signal, type Signal } from '@angular/core';\nimport { expoModule, present } from './native.ts';\n\nexport interface NativeBrightness {\n get(): Promise<number>;\n set(level: number): Promise<void>;\n restore(): Promise<void>;\n}\n\n@Service()\nexport class Brightness {\n /** Overridden in a test to watch the level without changing a screen. */\n static readonly SOURCE = new InjectionToken<NativeBrightness | null>(\n 'angular-native.brightnessSource',\n {\n factory: () => {\n const expo = expoModule(\n 'expo-brightness',\n () => require('expo-brightness') as typeof import('expo-brightness'),\n );\n if (!expo) return null;\n // Missing from the build: the stand-in, to say so when it is used.\n if (!present(expo)) return expo as never;\n return {\n get: () => expo.getBrightnessAsync(),\n set: (level) => expo.setBrightnessAsync(level),\n restore: () => expo.restoreSystemBrightnessAsync(),\n };\n },\n },\n );\n\n private readonly native = inject(Brightness.SOURCE);\n private readonly current = signal(1);\n\n /** Nought to one. One until the platform answers, since that is what a screen already shows. */\n readonly level: Signal<number> = this.current.asReadonly();\n\n constructor() {\n void present(this.native)\n ?.get()\n .then(\n (level) => this.current.set(level),\n () => {},\n );\n }\n\n /**\n * Set it, and return the function that puts it back.\n *\n * Always paired, because the alternative is an app that leaves the screen at full brightness\n * after the boarding pass has been shown - which the user experiences as a battery fault.\n */\n set(level: number): () => void {\n const clamped = Math.min(1, Math.max(0, level));\n // A stack, as the status bar's is: a screen pushed over one that set a level of its own puts\n // back the level beneath it, not the system's, when it goes.\n const entry = { level: clamped };\n this.levels.push(entry);\n this.apply(clamped);\n return () => {\n const at = this.levels.indexOf(entry);\n if (at === -1) return;\n this.levels.splice(at, 1);\n if (at < this.levels.length) return;\n const below = this.levels.at(-1);\n if (below) this.apply(below.level);\n else this.restore();\n };\n }\n\n /** Every level set and not yet put back, the one in force last. */\n private readonly levels: { readonly level: number }[] = [];\n\n private apply(level: number): void {\n this.current.set(level);\n void this.native?.set(level);\n }\n\n restore(): void {\n // Everything set so far is put back, so a release still to come has nothing left to undo.\n this.levels.length = 0;\n void this.native\n ?.restore()\n .then(() => this.native?.get().then((level) => this.current.set(level)));\n }\n}\n"]}
|
package/dist/camera.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `Camera`: a picture taken from the `<expo-camera>` view on screen.
|
|
2
|
+
* `Camera`: a picture taken, or a video recorded, from the `<expo-camera>` view on screen.
|
|
3
3
|
*
|
|
4
4
|
* ```ts
|
|
5
5
|
* registerExpoViews('expo-camera'); // once, at startup
|
|
@@ -14,11 +14,15 @@
|
|
|
14
14
|
* }
|
|
15
15
|
* ```
|
|
16
16
|
*
|
|
17
|
+
* A video is `record()`, which resolves once it stops - `stopRecording()`, or a `maxDuration` or
|
|
18
|
+
* `maxFileSize` reached - on a view with `mode="video"`.
|
|
19
|
+
*
|
|
17
20
|
* Importing it is all it takes: it applies to every `<expo-camera>` in the template. The view is
|
|
18
21
|
* what takes the picture, so this is a directive on the view rather than a service.
|
|
19
22
|
*
|
|
20
23
|
* In React, `takePictureAsync` is a method on the component's ref. Underneath, it is one of the
|
|
21
|
-
* functions Expo defines on the view (`AsyncFunction("takePicture")` in the module
|
|
24
|
+
* functions Expo defines on the view (`AsyncFunction("takePicture")` in the module, and `record`
|
|
25
|
+
* and `stopRecording` beside it), which native
|
|
22
26
|
* finds by reading `nativeTag` off whatever it is called on. So this calls the same function with
|
|
23
27
|
* the tag the engine committed the view under, and no ref is needed.
|
|
24
28
|
*/
|
|
@@ -26,11 +30,23 @@ import { InjectionToken } from '@angular/core';
|
|
|
26
30
|
import * as i0 from "@angular/core";
|
|
27
31
|
export type PictureOptions = Omit<import('expo-camera').CameraPictureOptions, 'onPictureSaved' | 'pictureRef'>;
|
|
28
32
|
export type CameraPicture = import('expo-camera').CameraCapturedPicture;
|
|
33
|
+
/** `expo-camera`'s own, less `mirror`, which it has deprecated for the view's `mirror` prop. */
|
|
34
|
+
export type RecordingOptions = Omit<import('expo-camera').CameraRecordingOptions, 'mirror'>;
|
|
35
|
+
/** A recorded video: a file in the cache directory. */
|
|
36
|
+
export interface CameraRecording {
|
|
37
|
+
readonly uri: string;
|
|
38
|
+
}
|
|
29
39
|
/** The functions `expo-camera` defines on its view, called with the view's tag as `this`. */
|
|
30
40
|
export interface CameraViewFunctions {
|
|
31
41
|
takePicture(this: {
|
|
32
42
|
nativeTag: number;
|
|
33
43
|
}, options: PictureOptions): Promise<CameraPicture>;
|
|
44
|
+
record(this: {
|
|
45
|
+
nativeTag: number;
|
|
46
|
+
}, options: RecordingOptions): Promise<CameraRecording>;
|
|
47
|
+
stopRecording(this: {
|
|
48
|
+
nativeTag: number;
|
|
49
|
+
}): Promise<void> | void;
|
|
34
50
|
}
|
|
35
51
|
export declare class Camera {
|
|
36
52
|
/** Overridden in a test to take pictures without a camera. */
|
|
@@ -43,6 +59,16 @@ export declare class Camera {
|
|
|
43
59
|
* no camera to take it with yet.
|
|
44
60
|
*/
|
|
45
61
|
takePicture(options?: PictureOptions): Promise<CameraPicture | null>;
|
|
62
|
+
/**
|
|
63
|
+
* Record a video, resolving once the recording stops: `stopRecording()`, a `maxDuration` (in
|
|
64
|
+
* seconds) or `maxFileSize` (in bytes) reached, or the preview stopping. The view needs
|
|
65
|
+
* `mode="video"`, and the microphone permission unless it has `mute`: without it, Android rejects
|
|
66
|
+
* and iOS records without sound. Null without the module, or before the view has reached the
|
|
67
|
+
* screen.
|
|
68
|
+
*/
|
|
69
|
+
record(options?: RecordingOptions): Promise<CameraRecording | null>;
|
|
70
|
+
/** Stop the recording in progress, if there is one: `record()` then resolves with the video. */
|
|
71
|
+
stopRecording(): Promise<void>;
|
|
46
72
|
static ɵfac: i0.ɵɵFactoryDeclaration<Camera, never>;
|
|
47
73
|
static ɵdir: i0.ɵɵDirectiveDeclaration<Camera, "expo-camera", ["camera"], {}, {}, never, never, true, never>;
|
|
48
74
|
}
|
package/dist/camera.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `Camera`: a picture taken from the `<expo-camera>` view on screen.
|
|
2
|
+
* `Camera`: a picture taken, or a video recorded, from the `<expo-camera>` view on screen.
|
|
3
3
|
*
|
|
4
4
|
* ```ts
|
|
5
5
|
* registerExpoViews('expo-camera'); // once, at startup
|
|
@@ -14,17 +14,21 @@
|
|
|
14
14
|
* }
|
|
15
15
|
* ```
|
|
16
16
|
*
|
|
17
|
+
* A video is `record()`, which resolves once it stops - `stopRecording()`, or a `maxDuration` or
|
|
18
|
+
* `maxFileSize` reached - on a view with `mode="video"`.
|
|
19
|
+
*
|
|
17
20
|
* Importing it is all it takes: it applies to every `<expo-camera>` in the template. The view is
|
|
18
21
|
* what takes the picture, so this is a directive on the view rather than a service.
|
|
19
22
|
*
|
|
20
23
|
* In React, `takePictureAsync` is a method on the component's ref. Underneath, it is one of the
|
|
21
|
-
* functions Expo defines on the view (`AsyncFunction("takePicture")` in the module
|
|
24
|
+
* functions Expo defines on the view (`AsyncFunction("takePicture")` in the module, and `record`
|
|
25
|
+
* and `stopRecording` beside it), which native
|
|
22
26
|
* finds by reading `nativeTag` off whatever it is called on. So this calls the same function with
|
|
23
27
|
* the tag the engine committed the view under, and no ref is needed.
|
|
24
28
|
*/
|
|
25
29
|
import { Directive, ElementRef, InjectionToken, inject } from '@angular/core';
|
|
26
30
|
import { Engine } from '@ng-native/fabric';
|
|
27
|
-
import { expoModule, optional } from "./native.js";
|
|
31
|
+
import { expoModule, optional, present } from "./native.js";
|
|
28
32
|
import * as i0 from "@angular/core";
|
|
29
33
|
export class Camera {
|
|
30
34
|
/** Overridden in a test to take pictures without a camera. */
|
|
@@ -32,6 +36,9 @@ export class Camera {
|
|
|
32
36
|
factory: () => {
|
|
33
37
|
const core = optional(() => require('expo-modules-core'));
|
|
34
38
|
const module = expoModule('expo-camera', () => core?.requireOptionalNativeModule('ExpoCamera'));
|
|
39
|
+
// Missing, the stand-in is the functions: taking a picture says what to install.
|
|
40
|
+
if (module && !present(module))
|
|
41
|
+
return module;
|
|
35
42
|
// The camera is the module's first view, so its functions are under the module's name.
|
|
36
43
|
return module?.ViewPrototypes?.['ExpoCamera'] ?? null;
|
|
37
44
|
},
|
|
@@ -49,6 +56,26 @@ export class Camera {
|
|
|
49
56
|
return null;
|
|
50
57
|
return this.functions.takePicture.call({ nativeTag }, options);
|
|
51
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Record a video, resolving once the recording stops: `stopRecording()`, a `maxDuration` (in
|
|
61
|
+
* seconds) or `maxFileSize` (in bytes) reached, or the preview stopping. The view needs
|
|
62
|
+
* `mode="video"`, and the microphone permission unless it has `mute`: without it, Android rejects
|
|
63
|
+
* and iOS records without sound. Null without the module, or before the view has reached the
|
|
64
|
+
* screen.
|
|
65
|
+
*/
|
|
66
|
+
async record(options = {}) {
|
|
67
|
+
const nativeTag = this.engine.tagOf(this.node);
|
|
68
|
+
if (!this.functions || nativeTag === null)
|
|
69
|
+
return null;
|
|
70
|
+
return this.functions.record.call({ nativeTag }, options);
|
|
71
|
+
}
|
|
72
|
+
/** Stop the recording in progress, if there is one: `record()` then resolves with the video. */
|
|
73
|
+
async stopRecording() {
|
|
74
|
+
const nativeTag = this.engine.tagOf(this.node);
|
|
75
|
+
if (!this.functions || nativeTag === null)
|
|
76
|
+
return;
|
|
77
|
+
await this.functions.stopRecording.call({ nativeTag });
|
|
78
|
+
}
|
|
52
79
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: Camera, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
53
80
|
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.2.0", type: Camera, isStandalone: true, selector: "expo-camera", exportAs: ["camera"], ngImport: i0 });
|
|
54
81
|
}
|
package/dist/camera.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"camera.js","sourceRoot":"","sources":["../src/camera.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"camera.js","sourceRoot":"","sources":["../src/camera.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAmB,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;;AAsB5D,MAAM,OAAO,MAAM;IACjB,8DAA8D;IAC9D,MAAM,CAAU,MAAM,GAAG,IAAI,cAAc,CACzC,6BAA6B,EAC7B;QACE,OAAO,EAAE,GAAG,EAAE;YACZ,MAAM,IAAI,GAAG,QAAQ,CACnB,GAAG,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAuC,CACzE,CAAC;YACF,MAAM,MAAM,GAAG,UAAU,CAAC,aAAa,EAAE,GAAG,EAAE,CAC5C,IAAI,EAAE,2BAA2B,CAE9B,YAAY,CAAC,CACjB,CAAC;YACF,iFAAiF;YACjF,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;gBAAE,OAAO,MAAwC,CAAC;YAChF,uFAAuF;YACvF,OAAO,MAAM,EAAE,cAAc,EAAE,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC;QACxD,CAAC;KACF,CACF,CAAC;IAEe,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IACxB,IAAI,GAAG,MAAM,CAAyB,UAAU,CAAC,CAAC,aAAa,CAAC;IAEjF;;;OAGG;IACH,KAAK,CAAC,WAAW,CAAC,UAA0B,EAAE;QAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,SAAS,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QACvD,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,EAAE,OAAO,CAAC,CAAC;IACjE,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,MAAM,CAAC,UAA4B,EAAE;QACzC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,SAAS,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QACvD,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IAED,gGAAgG;IAChG,KAAK,CAAC,aAAa;QACjB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,SAAS,KAAK,IAAI;YAAE,OAAO;QAClD,MAAM,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;IACzD,CAAC;uGAtDU,MAAM;2FAAN,MAAM;;2FAAN,MAAM;kBADlB,SAAS;mBAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE","sourcesContent":["/**\n * `Camera`: a picture taken, or a video recorded, from the `<expo-camera>` view on screen.\n *\n * ```ts\n * registerExpoViews('expo-camera'); // once, at startup\n *\n * @Component({\n * imports: [Camera],\n * template: `<expo-camera facing=\"back\" class=\"flex-1\" />`,\n * })\n * export class Scanner {\n * private readonly camera = viewChild.required(Camera);\n * async shoot() { const picture = await this.camera().takePicture({ quality: 0.8 }); }\n * }\n * ```\n *\n * A video is `record()`, which resolves once it stops - `stopRecording()`, or a `maxDuration` or\n * `maxFileSize` reached - on a view with `mode=\"video\"`.\n *\n * Importing it is all it takes: it applies to every `<expo-camera>` in the template. The view is\n * what takes the picture, so this is a directive on the view rather than a service.\n *\n * In React, `takePictureAsync` is a method on the component's ref. Underneath, it is one of the\n * functions Expo defines on the view (`AsyncFunction(\"takePicture\")` in the module, and `record`\n * and `stopRecording` beside it), which native\n * finds by reading `nativeTag` off whatever it is called on. So this calls the same function with\n * the tag the engine committed the view under, and no ref is needed.\n */\nimport { Directive, ElementRef, InjectionToken, inject } from '@angular/core';\nimport { Engine, type EngineNode } from '@ng-native/fabric';\nimport { expoModule, optional, present } from './native.ts';\n\nexport type PictureOptions = Omit<\n import('expo-camera').CameraPictureOptions,\n 'onPictureSaved' | 'pictureRef'\n>;\nexport type CameraPicture = import('expo-camera').CameraCapturedPicture;\n/** `expo-camera`'s own, less `mirror`, which it has deprecated for the view's `mirror` prop. */\nexport type RecordingOptions = Omit<import('expo-camera').CameraRecordingOptions, 'mirror'>;\n/** A recorded video: a file in the cache directory. */\nexport interface CameraRecording {\n readonly uri: string;\n}\n\n/** The functions `expo-camera` defines on its view, called with the view's tag as `this`. */\nexport interface CameraViewFunctions {\n takePicture(this: { nativeTag: number }, options: PictureOptions): Promise<CameraPicture>;\n record(this: { nativeTag: number }, options: RecordingOptions): Promise<CameraRecording>;\n stopRecording(this: { nativeTag: number }): Promise<void> | void;\n}\n\n@Directive({ selector: 'expo-camera', exportAs: 'camera' })\nexport class Camera {\n /** Overridden in a test to take pictures without a camera. */\n static readonly SOURCE = new InjectionToken<CameraViewFunctions | null>(\n 'angular-native.cameraSource',\n {\n factory: () => {\n const core = optional(\n () => require('expo-modules-core') as typeof import('expo-modules-core'),\n );\n const module = expoModule('expo-camera', () =>\n core?.requireOptionalNativeModule<{\n ViewPrototypes?: Record<string, CameraViewFunctions>;\n }>('ExpoCamera'),\n );\n // Missing, the stand-in is the functions: taking a picture says what to install.\n if (module && !present(module)) return module as unknown as CameraViewFunctions;\n // The camera is the module's first view, so its functions are under the module's name.\n return module?.ViewPrototypes?.['ExpoCamera'] ?? null;\n },\n },\n );\n\n private readonly functions = inject(Camera.SOURCE);\n private readonly engine = inject(Engine);\n private readonly node = inject<ElementRef<EngineNode>>(ElementRef).nativeElement;\n\n /**\n * Take a picture. Null without the module, or before the view has reached the screen - there is\n * no camera to take it with yet.\n */\n async takePicture(options: PictureOptions = {}): Promise<CameraPicture | null> {\n const nativeTag = this.engine.tagOf(this.node);\n if (!this.functions || nativeTag === null) return null;\n return this.functions.takePicture.call({ nativeTag }, options);\n }\n\n /**\n * Record a video, resolving once the recording stops: `stopRecording()`, a `maxDuration` (in\n * seconds) or `maxFileSize` (in bytes) reached, or the preview stopping. The view needs\n * `mode=\"video\"`, and the microphone permission unless it has `mute`: without it, Android rejects\n * and iOS records without sound. Null without the module, or before the view has reached the\n * screen.\n */\n async record(options: RecordingOptions = {}): Promise<CameraRecording | null> {\n const nativeTag = this.engine.tagOf(this.node);\n if (!this.functions || nativeTag === null) return null;\n return this.functions.record.call({ nativeTag }, options);\n }\n\n /** Stop the recording in progress, if there is one: `record()` then resolves with the video. */\n async stopRecording(): Promise<void> {\n const nativeTag = this.engine.tagOf(this.node);\n if (!this.functions || nativeTag === null) return;\n await this.functions.stopRecording.call({ nativeTag });\n }\n}\n"]}
|
package/dist/clipboard.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* expects. `expo-haptics`'s JavaScript adds none of that, which is why `./haptics.ts` skips it.
|
|
7
7
|
*/
|
|
8
8
|
import { DestroyRef, InjectionToken, Service, inject, signal } from '@angular/core';
|
|
9
|
-
import { expoModule } from "./native.js";
|
|
9
|
+
import { expoModule, present } from "./native.js";
|
|
10
10
|
import * as i0 from "@angular/core";
|
|
11
11
|
/**
|
|
12
12
|
* `changes` counts pasteboard changes rather than holding the contents, and that is deliberate:
|
|
@@ -26,6 +26,9 @@ export class Clipboard {
|
|
|
26
26
|
const expo = expoModule('expo-clipboard', () => require('expo-clipboard'));
|
|
27
27
|
if (!expo)
|
|
28
28
|
return null;
|
|
29
|
+
// Missing from the build: the stand-in, to say so when it is used.
|
|
30
|
+
if (!present(expo))
|
|
31
|
+
return expo;
|
|
29
32
|
return {
|
|
30
33
|
getStringAsync: () => expo.getStringAsync(),
|
|
31
34
|
setStringAsync: (text) => expo.setStringAsync(text),
|
|
@@ -39,7 +42,7 @@ export class Clipboard {
|
|
|
39
42
|
/** How many times the pasteboard has changed since the app started reading it. */
|
|
40
43
|
changes = this.count.asReadonly();
|
|
41
44
|
constructor() {
|
|
42
|
-
const listener = this.native?.addClipboardListener(() => this.count.update((n) => n + 1));
|
|
45
|
+
const listener = present(this.native)?.addClipboardListener(() => this.count.update((n) => n + 1));
|
|
43
46
|
if (listener)
|
|
44
47
|
inject(DestroyRef).onDestroy(() => listener.remove());
|
|
45
48
|
}
|
package/dist/clipboard.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clipboard.js","sourceRoot":"","sources":["../src/clipboard.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAe,MAAM,eAAe,CAAC;AACjG,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;;
|
|
1
|
+
{"version":3,"file":"clipboard.js","sourceRoot":"","sources":["../src/clipboard.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAe,MAAM,eAAe,CAAC;AACjG,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;;AASlD;;;;;;;;;;GAUG;AAEH,MAAM,OAAO,SAAS;IACpB,gEAAgE;IAChE,MAAM,CAAU,MAAM,GAAG,IAAI,cAAc,CACzC,gCAAgC,EAChC;QACE,OAAO,EAAE,GAAG,EAAE;YACZ,MAAM,IAAI,GAAG,UAAU,CACrB,gBAAgB,EAChB,GAAG,EAAE,CAAC,OAAO,CAAC,gBAAgB,CAAoC,CACnE,CAAC;YACF,IAAI,CAAC,IAAI;gBAAE,OAAO,IAAI,CAAC;YACvB,mEAAmE;YACnE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;gBAAE,OAAO,IAAa,CAAC;YACzC,OAAO;gBACL,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE;gBAC3C,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;gBACnD,oBAAoB,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC;aACxE,CAAC;QACJ,CAAC;KACF,CACF,CAAC;IAEe,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAClC,KAAK,GAAG,MAAM,CAAC,CAAC;8EAAC,CAAC;IAEnC,kFAAkF;IACzE,OAAO,GAAmB,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;IAE3D;QACE,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,oBAAoB,CAAC,GAAG,EAAE,CAC/D,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAChC,CAAC;QACF,IAAI,QAAQ;YAAE,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,sFAAsF;IACtF,IAAI;QACF,OAAO,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,8DAA8D;IAC9D,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,MAAM,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;uGA3CU,SAAS;wGAAT,SAAS;;2FAAT,SAAS;kBADrB,OAAO","sourcesContent":["/**\n * `Clipboard`, bound to `expo-clipboard`.\n *\n * The package's JavaScript is used here rather than the native module, because it does real work:\n * it carries the event name the change listener subscribes to, and the option defaults each call\n * expects. `expo-haptics`'s JavaScript adds none of that, which is why `./haptics.ts` skips it.\n */\nimport { DestroyRef, InjectionToken, Service, inject, signal, type Signal } from '@angular/core';\nimport { expoModule, present } from './native.ts';\n\n/** The slice of `expo-clipboard` this needs. */\nexport interface NativeClipboard {\n getStringAsync(): Promise<string>;\n setStringAsync(text: string): Promise<boolean>;\n addClipboardListener(listener: () => void): { remove(): void };\n}\n\n/**\n * `changes` counts pasteboard changes rather than holding the contents, and that is deliberate:\n * on iOS 16 and later, *reading* the clipboard prompts the user for permission. A signal that\n * held the text would prompt on every change, including changes made by other apps, which is\n * both a terrible experience and a good way to have the read denied. So the notification is free\n * and the read is explicit.\n *\n * The listener lives as long as the app does, and is removed when the app is destroyed: a root\n * service is one per app, not one per process, and an app that is mounted and unmounted - by a\n * test, a reload, a host embedding it - would otherwise leave one listener behind each time.\n */\n@Service()\nexport class Clipboard {\n /** Overridden in a test to drive the pasteboard without one. */\n static readonly SOURCE = new InjectionToken<NativeClipboard | null>(\n 'angular-native.clipboardSource',\n {\n factory: () => {\n const expo = expoModule(\n 'expo-clipboard',\n () => require('expo-clipboard') as typeof import('expo-clipboard'),\n );\n if (!expo) return null;\n // Missing from the build: the stand-in, to say so when it is used.\n if (!present(expo)) return expo as never;\n return {\n getStringAsync: () => expo.getStringAsync(),\n setStringAsync: (text) => expo.setStringAsync(text),\n addClipboardListener: (listener) => expo.addClipboardListener(listener),\n };\n },\n },\n );\n\n private readonly native = inject(Clipboard.SOURCE);\n private readonly count = signal(0);\n\n /** How many times the pasteboard has changed since the app started reading it. */\n readonly changes: Signal<number> = this.count.asReadonly();\n\n constructor() {\n const listener = present(this.native)?.addClipboardListener(() =>\n this.count.update((n) => n + 1),\n );\n if (listener) inject(DestroyRef).onDestroy(() => listener.remove());\n }\n\n /** What is on the clipboard. On iOS 16+ this is what asks the user for permission. */\n read(): Promise<string> {\n return this.native?.getStringAsync() ?? Promise.resolve('');\n }\n\n /** Put text on the clipboard. Resolves once native has it. */\n async write(text: string): Promise<void> {\n await this.native?.setStringAsync(text);\n }\n}\n"]}
|
package/dist/database.js
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* and an app usually has exactly one. Opening is deferred until something asks: a database opened
|
|
19
19
|
* at startup is a file handle and a WAL journal for an app that may never read from it.
|
|
20
20
|
*/
|
|
21
|
-
import {
|
|
21
|
+
import { expoModuleNow, unavailable } from "./native.js";
|
|
22
22
|
export class Database {
|
|
23
23
|
open;
|
|
24
24
|
migrations;
|
|
@@ -117,7 +117,7 @@ export function database(name, migrations = [], options = {}) {
|
|
|
117
117
|
return new Database(async () => {
|
|
118
118
|
if (opener)
|
|
119
119
|
return opener(name);
|
|
120
|
-
const expo =
|
|
120
|
+
const expo = expoModuleNow('expo-sqlite', () => require('expo-sqlite'), ['ios', 'android', 'web']);
|
|
121
121
|
if (!expo) {
|
|
122
122
|
throw unavailable('expo-sqlite', 'Point database() at a stand-in with openDatabasesWith(), such as memoryDatabase() from @ng-native/testing.');
|
|
123
123
|
}
|
package/dist/database.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.js","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `database()`, bound to `expo-sqlite`.\n *\n * `SQLiteProvider` and `useSQLiteContext` are the documented way in and both are React: a context\n * that opens the database, runs migrations, and closes it when the provider unmounts. The database\n * itself is a plain object with `getAllAsync` and the rest already on it, so what is rebuilt is\n * the *lifecycle* - opened once, migrated before anything queries, closed on request:\n *\n * ```ts\n * export const notes = database('notes.db', [\n * { to: 1, up: (db) => db.execAsync('CREATE TABLE note (id INTEGER PRIMARY KEY, body TEXT)') },\n * ]);\n *\n * const rows = await (await notes.ready()).getAllAsync<Note>('SELECT * FROM note');\n * ```\n *\n * A value rather than a service, because a schema belongs to a feature rather than to an injector,\n * and an app usually has exactly one. Opening is deferred until something asks: a database opened\n * at startup is a file handle and a WAL journal for an app that may never read from it.\n */\nimport { expoModuleNow, unavailable } from './native.ts';\n\n/** Enough of `SQLiteDatabase` to own it. Queries go through the database itself. */\nexport interface NativeDatabase {\n execAsync(source: string): Promise<void>;\n getFirstAsync<T>(source: string, ...params: unknown[]): Promise<T | null>;\n closeAsync(): Promise<void>;\n withTransactionAsync(task: () => Promise<void>): Promise<void>;\n}\n\n/** One step from one schema version to the next. Run in order, each inside a transaction. */\nexport interface Migration {\n /** The version this migration produces. Must be greater than every one before it. */\n readonly to: number;\n readonly up: (database: NativeDatabase) => Promise<void>;\n}\n\nexport interface DatabaseOptions<T extends NativeDatabase = NativeDatabase> {\n /**\n * Run on every open, before the migrations and outside any transaction: where the settings of a\n * connection go. `PRAGMA foreign_keys = ON` belongs here and nowhere else, since SQLite ignores\n * it inside a transaction, which a migration is, and forgets it when the connection closes.\n */\n readonly onOpen?: (database: T) => Promise<void> | void;\n}\n\nexport class Database<T extends NativeDatabase> {\n private readonly open: () => Promise<T>;\n private readonly migrations: readonly Migration[];\n private readonly onOpen: DatabaseOptions<T>['onOpen'];\n private opening: Promise<T> | null = null;\n\n constructor(\n open: () => Promise<T>,\n migrations: readonly Migration[] = [],\n options: DatabaseOptions<T> = {},\n ) {\n this.open = open;\n this.migrations = [...migrations].sort((a, b) => a.to - b.to);\n this.onOpen = options.onOpen;\n }\n\n /**\n * The database, opened and migrated.\n *\n * Awaited at every call site rather than held, because the first caller is the one that pays for\n * opening it and every caller after that is handed the same promise - including the ones that\n * arrive while it is still opening, which is what stops two connections being made at once.\n */\n ready(): Promise<T> {\n if (this.opening) return this.opening;\n const opening = this.start();\n this.opening = opening;\n // A failed open is forgotten once everyone waiting on it has heard, so the next caller tries\n // again rather than being handed the same failure for the life of the app.\n opening.catch(() => {\n if (this.opening === opening) this.opening = null;\n });\n return opening;\n }\n\n /**\n * Close it. The next caller reopens; this is for a sign-out that has to leave nothing behind.\n *\n * Resolves even when the open failed: the connection was already closed by the failure, so there\n * is nothing left to release.\n */\n async close(): Promise<void> {\n const opening = this.opening;\n this.opening = null;\n const database = await opening?.catch(() => null);\n await database?.closeAsync();\n }\n\n /** Open, set the connection up and migrate, closing it again if either fails. */\n private async start(): Promise<T> {\n const database = await this.open();\n try {\n await this.onOpen?.(database);\n await this.migrate(database);\n } catch (error) {\n // The migration's own error is the one worth reporting; a failure to close after it is not.\n await database.closeAsync().catch(() => {});\n throw error;\n }\n return database;\n }\n\n /**\n * Bring the schema up to date, in order, each step in its own transaction.\n *\n * `user_version` is SQLite's own integer for this, so the record of where a database has got to\n * lives in the database rather than in a table this has to create first. It is transactional,\n * so it is set inside the migration's own transaction: the schema change and the record of it\n * commit together or roll back together, and a migration can never be half done and recorded.\n */\n private async migrate(database: T): Promise<void> {\n if (!this.migrations.length) return;\n\n const row = await database.getFirstAsync<{ user_version: number }>('PRAGMA user_version');\n let version = row?.user_version ?? 0;\n\n for (const migration of this.migrations) {\n if (migration.to <= version) continue;\n await database.withTransactionAsync(async () => {\n await migration.up(database);\n await database.execAsync(`PRAGMA user_version = ${migration.to}`);\n });\n version = migration.to;\n }\n }\n}\n\nlet opener: ((name: string) => unknown) | null = null;\n\n/**\n * Open every `database()` with `open` in place of `expo-sqlite`, until the function this answers\n * is called. For a test, where no native module can load: `open` gives a stand-in, such as\n * `memoryDatabase()` from `@ng-native/testing`, and the migrations and `onOpen` run against it.\n */\nexport function openDatabasesWith(open: (name: string) => unknown): () => void {\n const before = opener;\n opener = open;\n return () => {\n opener = before;\n };\n}\n\n/** A database, opened on first use and migrated before the first query sees it. */\nexport function database(\n name: string,\n migrations: readonly Migration[] = [],\n options: DatabaseOptions<import('expo-sqlite').SQLiteDatabase> = {},\n) {\n return new Database<import('expo-sqlite').SQLiteDatabase>(\n async () => {\n if (opener) return opener(name) as import('expo-sqlite').SQLiteDatabase;\n const expo = expoModuleNow(\n 'expo-sqlite',\n () => require('expo-sqlite') as typeof import('expo-sqlite'),\n ['ios', 'android', 'web'],\n );\n if (!expo) {\n throw unavailable(\n 'expo-sqlite',\n 'Point database() at a stand-in with openDatabasesWith(), such as memoryDatabase() from @ng-native/testing.',\n );\n }\n return expo.openDatabaseAsync(name);\n },\n migrations,\n options,\n );\n}\n"]}
|
|
@@ -278,6 +278,10 @@ export declare class UiDatePicker {
|
|
|
278
278
|
protected readonly nativeView: true;
|
|
279
279
|
readonly title: import("@angular/core").InputSignal<string | undefined>;
|
|
280
280
|
readonly selection: import("@angular/core").InputSignal<string | undefined>;
|
|
281
|
+
/**
|
|
282
|
+
* What the picker shows. An empty list shows nothing in SwiftUI; Compose has no such choice,
|
|
283
|
+
* so on Android it shows the date and the time.
|
|
284
|
+
*/
|
|
281
285
|
readonly displayedComponents: import("@angular/core").InputSignal<readonly ("date" | "hourAndMinute")[] | undefined>;
|
|
282
286
|
readonly range: import("@angular/core").InputSignal<{
|
|
283
287
|
readonly start?: string;
|
|
@@ -293,6 +297,8 @@ export declare class UiDatePicker {
|
|
|
293
297
|
readonly dateChange: import("@angular/core").OutputEmitterRef<UiDateChangeEvent>;
|
|
294
298
|
private readonly android;
|
|
295
299
|
protected readonly resolvedSelection: Signal<string | undefined>;
|
|
300
|
+
/** SwiftUI takes a list of what to show, and Compose one word for it. */
|
|
301
|
+
protected readonly resolvedComponents: Signal<"date" | "hourAndMinute" | readonly ("date" | "hourAndMinute")[] | "dateAndTime" | undefined>;
|
|
296
302
|
protected readonly initialDate: Signal<number | null | undefined>;
|
|
297
303
|
protected readonly resolvedModifiers: Signal<readonly UiModifier[] | undefined>;
|
|
298
304
|
/**
|
|
@@ -307,16 +313,70 @@ export declare class UiDatePicker {
|
|
|
307
313
|
static ɵfac: i0.ɵɵFactoryDeclaration<UiDatePicker, never>;
|
|
308
314
|
static ɵcmp: i0.ɵɵComponentDeclaration<UiDatePicker, "ui-date-picker", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "selection": { "alias": "selection"; "required": false; "isSignal": true; }; "displayedComponents": { "alias": "displayedComponents"; "required": false; "isSignal": true; }; "range": { "alias": "range"; "required": false; "isSignal": true; }; "accessibilityLabel": { "alias": "accessibilityLabel"; "required": false; "isSignal": true; }; "modifiers": { "alias": "modifiers"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touch": "touch"; "dateChange": "dateChange"; }, never, never, true, never>;
|
|
309
315
|
}
|
|
316
|
+
/** Compose's `SingleChoiceSegmentedButtonRow`, Android only: a row of `ui-segmented-button`s. */
|
|
317
|
+
export declare class UiSingleChoiceSegmentedButtonRow {
|
|
318
|
+
protected readonly nativeView: true;
|
|
319
|
+
readonly modifiers: import("@angular/core").InputSignal<readonly UiModifier[] | undefined>;
|
|
320
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<UiSingleChoiceSegmentedButtonRow, never>;
|
|
321
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<UiSingleChoiceSegmentedButtonRow, "ui-single-choice-segmented-button-row", never, { "modifiers": { "alias": "modifiers"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
322
|
+
}
|
|
323
|
+
/** Compose's `SegmentedButton`, Android only, its label in a `<ui-slot name="label">`. */
|
|
324
|
+
export declare class UiSegmentedButton {
|
|
325
|
+
protected readonly nativeView: true;
|
|
326
|
+
readonly selected: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
327
|
+
readonly enabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
328
|
+
readonly modifiers: import("@angular/core").InputSignal<readonly UiModifier[] | undefined>;
|
|
329
|
+
readonly press: import("@angular/core").OutputEmitterRef<void>;
|
|
330
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<UiSegmentedButton, never>;
|
|
331
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<UiSegmentedButton, "ui-segmented-button", never, { "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "enabled": { "alias": "enabled"; "required": false; "isSignal": true; }; "modifiers": { "alias": "modifiers"; "required": false; "isSignal": true; }; }, { "press": "press"; }, never, ["*"], true, never>;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Compose's `ExposedDropdownMenuBox`, Android only: an anchor, a view with the `menuAnchor`
|
|
335
|
+
* modifier, and the `ui-exposed-dropdown-menu` it opens. A tap on the anchor asks to open or close
|
|
336
|
+
* it, through `toggled`; `expanded` says which it is.
|
|
337
|
+
*/
|
|
338
|
+
export declare class UiExposedDropdownMenuBox {
|
|
339
|
+
protected readonly nativeView: true;
|
|
340
|
+
readonly expanded: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
341
|
+
readonly toggled: import("@angular/core").OutputEmitterRef<boolean>;
|
|
342
|
+
readonly modifiers: import("@angular/core").InputSignal<readonly UiModifier[] | undefined>;
|
|
343
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<UiExposedDropdownMenuBox, never>;
|
|
344
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<UiExposedDropdownMenuBox, "ui-exposed-dropdown-menu-box", never, { "expanded": { "alias": "expanded"; "required": false; "isSignal": true; }; "modifiers": { "alias": "modifiers"; "required": false; "isSignal": true; }; }, { "toggled": "toggled"; }, never, ["*"], true, never>;
|
|
345
|
+
}
|
|
346
|
+
/** Compose's `ExposedDropdownMenu`, Android only: the `ui-dropdown-menu-item`s a box opens. */
|
|
347
|
+
export declare class UiExposedDropdownMenu {
|
|
348
|
+
protected readonly nativeView: true;
|
|
349
|
+
readonly expanded: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
350
|
+
readonly modifiers: import("@angular/core").InputSignal<readonly UiModifier[] | undefined>;
|
|
351
|
+
/** A tap outside the menu, or Back: the box should close it. */
|
|
352
|
+
readonly dismiss: import("@angular/core").OutputEmitterRef<void>;
|
|
353
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<UiExposedDropdownMenu, never>;
|
|
354
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<UiExposedDropdownMenu, "ui-exposed-dropdown-menu", never, { "expanded": { "alias": "expanded"; "required": false; "isSignal": true; }; "modifiers": { "alias": "modifiers"; "required": false; "isSignal": true; }; }, { "dismiss": "dismiss"; }, never, ["*"], true, never>;
|
|
355
|
+
}
|
|
356
|
+
/** Compose's `DropdownMenuItem`, Android only, its text in a `<ui-slot name="text">`. */
|
|
357
|
+
export declare class UiDropdownMenuItem {
|
|
358
|
+
protected readonly nativeView: true;
|
|
359
|
+
readonly enabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
360
|
+
readonly modifiers: import("@angular/core").InputSignal<readonly UiModifier[] | undefined>;
|
|
361
|
+
readonly press: import("@angular/core").OutputEmitterRef<void>;
|
|
362
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<UiDropdownMenuItem, never>;
|
|
363
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<UiDropdownMenuItem, "ui-dropdown-menu-item", never, { "enabled": { "alias": "enabled"; "required": false; "isSignal": true; }; "modifiers": { "alias": "modifiers"; "required": false; "isSignal": true; }; }, { "press": "press"; }, never, ["*"], true, never>;
|
|
364
|
+
}
|
|
310
365
|
/** One choice in a `ui-picker`: what the field is set to, and what the user reads. */
|
|
311
366
|
export interface UiPickerOption {
|
|
312
367
|
readonly value: string | number;
|
|
313
368
|
readonly label: string;
|
|
314
369
|
}
|
|
315
370
|
/**
|
|
316
|
-
* A SwiftUI `Picker
|
|
317
|
-
*
|
|
318
|
-
*
|
|
319
|
-
*
|
|
371
|
+
* A SwiftUI `Picker` as a Signal Forms field: `<ui-picker [options]="rooms" [formField]="f.room"
|
|
372
|
+
* />`. `options` draws the choices, each tagged with its value, which is the content slot and `tag`
|
|
373
|
+
* modifiers `@expo/ui` otherwise wants written out by hand; children still work for anything
|
|
374
|
+
* richer on iOS. `pickerStyle` is SwiftUI's (`menu`, `segmented`, `wheel`, `inline`).
|
|
375
|
+
*
|
|
376
|
+
* Compose has no `Picker`, so on Android the options are drawn with its own controls: `segmented`
|
|
377
|
+
* as a row of segmented buttons, and any other style as an exposed dropdown menu under the chosen
|
|
378
|
+
* option. `label`, `systemImage`, children and `modifiers` are SwiftUI's alone. A `font` modifier
|
|
379
|
+
* reaches a segmented picker's segments in a development build, not in Expo Go.
|
|
320
380
|
*/
|
|
321
381
|
export declare class UiPicker {
|
|
322
382
|
protected readonly nativeView: true;
|
|
@@ -324,7 +384,7 @@ export declare class UiPicker {
|
|
|
324
384
|
/** An SF Symbol name. */
|
|
325
385
|
readonly systemImage: import("@angular/core").InputSignal<string | undefined>;
|
|
326
386
|
readonly options: import("@angular/core").InputSignal<readonly UiPickerOption[] | undefined>;
|
|
327
|
-
readonly pickerStyle: import("@angular/core").InputSignal<"inline" | "
|
|
387
|
+
readonly pickerStyle: import("@angular/core").InputSignal<"inline" | "segmented" | "automatic" | "menu" | "wheel" | "palette" | undefined>;
|
|
328
388
|
readonly modifiers: import("@angular/core").InputSignal<readonly UiModifier[] | undefined>;
|
|
329
389
|
/** The chosen option's value: what `[formField]` binds. */
|
|
330
390
|
readonly value: import("@angular/core").ModelSignal<string | number | null>;
|
|
@@ -336,8 +396,23 @@ export declare class UiPicker {
|
|
|
336
396
|
}>>;
|
|
337
397
|
/** Each option's `tag`, one array per value, so a pass hands native the same objects. */
|
|
338
398
|
protected readonly tags: Signal<Map<string | number, readonly UiModifier[]>>;
|
|
399
|
+
protected readonly android: boolean;
|
|
400
|
+
/** Whether Android's dropdown is open. */
|
|
401
|
+
protected readonly open: import("@angular/core").WritableSignal<boolean>;
|
|
402
|
+
/**
|
|
403
|
+
* What Android's dropdown shows closed: the chosen option, or the label before there is one,
|
|
404
|
+
* with the arrow that says a tap opens it, which plain text otherwise does not.
|
|
405
|
+
*/
|
|
406
|
+
protected readonly chosenLabel: Signal<string>;
|
|
407
|
+
/** What anchors Android's dropdown to the option it shows. */
|
|
408
|
+
protected readonly anchor: Signal<{
|
|
409
|
+
$type: string;
|
|
410
|
+
type: string;
|
|
411
|
+
enabled: boolean;
|
|
412
|
+
}[]>;
|
|
339
413
|
protected readonly resolvedModifiers: Signal<readonly UiModifier[] | undefined>;
|
|
340
414
|
constructor();
|
|
415
|
+
protected choose(selection: string | number): void;
|
|
341
416
|
static ɵfac: i0.ɵɵFactoryDeclaration<UiPicker, never>;
|
|
342
417
|
static ɵcmp: i0.ɵɵComponentDeclaration<UiPicker, "ui-picker", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "systemImage": { "alias": "systemImage"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "pickerStyle": { "alias": "pickerStyle"; "required": false; "isSignal": true; }; "modifiers": { "alias": "modifiers"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touch": "touch"; "selectionChange": "selectionChange"; }, never, ["*"], true, never>;
|
|
343
418
|
}
|
|
@@ -655,13 +730,19 @@ export declare class UiForm {
|
|
|
655
730
|
static ɵfac: i0.ɵɵFactoryDeclaration<UiForm, never>;
|
|
656
731
|
static ɵcmp: i0.ɵɵComponentDeclaration<UiForm, "ui-form", never, { "modifiers": { "alias": "modifiers"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
657
732
|
}
|
|
658
|
-
/**
|
|
733
|
+
/**
|
|
734
|
+
* A SwiftUI `Section` of a form or a list, under `title`, iOS only. A `<ui-slot name="header">`
|
|
735
|
+
* is its header in place of a `title`, and a `<ui-slot name="footer">` is the note under its rows.
|
|
736
|
+
* When both a non-empty `title` and a header slot are set, `@expo/ui`'s `SectionView` draws the
|
|
737
|
+
* `title` and drops the slot; an empty `title` counts as unset. The slot's `name` is written as it is,
|
|
738
|
+
* not bound, as that is what picks it out of the rows.
|
|
739
|
+
*/
|
|
659
740
|
export declare class UiSection {
|
|
660
741
|
protected readonly nativeView: true;
|
|
661
742
|
readonly title: import("@angular/core").InputSignal<string | undefined>;
|
|
662
743
|
readonly modifiers: import("@angular/core").InputSignal<readonly UiModifier[] | undefined>;
|
|
663
744
|
static ɵfac: i0.ɵɵFactoryDeclaration<UiSection, never>;
|
|
664
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<UiSection, "ui-section", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "modifiers": { "alias": "modifiers"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
745
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<UiSection, "ui-section", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "modifiers": { "alias": "modifiers"; "required": false; "isSignal": true; }; }, {}, never, ["ui-slot[name=header]", "*", "ui-slot[name=footer]"], true, never>;
|
|
665
746
|
}
|
|
666
747
|
/**
|
|
667
748
|
* A SwiftUI `Group`, iOS only: its children as they are, with no layout of its own. What it is for
|
|
@@ -769,8 +850,9 @@ export interface UiBottomSheetViewFunctions {
|
|
|
769
850
|
* Unlike the other components here, the element this is mounted on is a plain view, which takes
|
|
770
851
|
* no room and needs no `ui-host` around it. The sheet is inside it, wrapped as `@expo/ui`'s own
|
|
771
852
|
* React component wraps one: a `ui-host`, the sheet, on iOS a `ui-group` that carries the
|
|
772
|
-
* presentation modifiers, and a `ui-view-host` holding the one view the content goes in.
|
|
773
|
-
* toolbar
|
|
853
|
+
* presentation modifiers, and a `ui-view-host` holding the one view the content goes in. Where the
|
|
854
|
+
* build has SwiftUI's toolbar and the sheet is not sized to its content, the view host is in a
|
|
855
|
+
* `ui-navigation-stack` under the group, over a `ui-toolbar` that holds the items.
|
|
774
856
|
*/
|
|
775
857
|
export declare class UiBottomSheet {
|
|
776
858
|
/**
|
|
@@ -806,6 +888,13 @@ export declare class UiBottomSheet {
|
|
|
806
888
|
readonly detents: import("@angular/core").InputSignal<readonly UiPresentationDetent[] | undefined>;
|
|
807
889
|
/** Whether the grabber shows at the top of the sheet. */
|
|
808
890
|
readonly showDragIndicator: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
891
|
+
/**
|
|
892
|
+
* The colour of the sheet behind its content: SwiftUI's `presentationBackground` on iOS, where
|
|
893
|
+
* a sheet below its full height is otherwise drawn as glass, and Compose's `containerColor` on
|
|
894
|
+
* Android. Over a `background-color` the element has from CSS, which colours the sheet the same
|
|
895
|
+
* way. Neither is the sheet as the system draws it.
|
|
896
|
+
*/
|
|
897
|
+
readonly backgroundColor: import("@angular/core").InputSignal<string | undefined>;
|
|
809
898
|
/**
|
|
810
899
|
* The sheet has finished closing, whether the user dismissed it or `open` was set false: the
|
|
811
900
|
* moment another sheet or a dialog can be presented.
|
|
@@ -815,6 +904,12 @@ export declare class UiBottomSheet {
|
|
|
815
904
|
private readonly toolbarItems;
|
|
816
905
|
/** Whether the sheet has a toolbar: it has items for one, and the build has the views. */
|
|
817
906
|
protected readonly toolbar: Signal<boolean>;
|
|
907
|
+
/**
|
|
908
|
+
* A sheet's bar never shows a large title, but a navigation stack leaves room for one under its
|
|
909
|
+
* bar. `@expo/ui` has no modifier for the title's display mode, so `@ng-native/expo` registers
|
|
910
|
+
* one natively, in a build with `@expo/ui`. One without it, Expo Go's, ignores the modifier.
|
|
911
|
+
*/
|
|
912
|
+
protected readonly inlineTitle: readonly UiModifier[];
|
|
818
913
|
/** SwiftUI's sheet stays in the tree; anywhere else it is there while it shows. */
|
|
819
914
|
protected readonly swiftUI: boolean;
|
|
820
915
|
protected readonly width: Signal<number | undefined>;
|
|
@@ -827,15 +922,35 @@ export declare class UiBottomSheet {
|
|
|
827
922
|
* Whether the sheet is sized to its content, as it opened: a view host takes its sizing once,
|
|
828
923
|
* as it mounts. SwiftUI's sheet is not where it has detents to rest at, nor where it has a
|
|
829
924
|
* toolbar: a navigation stack fills what it is given, and the bar is no part of the content.
|
|
830
|
-
* A toolbar that comes or goes while
|
|
831
|
-
* again around it.
|
|
925
|
+
* A toolbar that comes or goes while such a sheet is open is followed, since the view host is
|
|
926
|
+
* made again around it.
|
|
832
927
|
*/
|
|
833
928
|
protected readonly fits: Signal<boolean>;
|
|
929
|
+
/**
|
|
930
|
+
* Whether the content is in a navigation stack, beside a toolbar: wherever the build has one and
|
|
931
|
+
* the sheet is not sized to its content, items or none, so that an item coming or going never
|
|
932
|
+
* makes the view host again. `@expo/ui`'s view host takes its content's touches as it appears and
|
|
933
|
+
* gives them up as it disappears, and one made again around the same content appears before the
|
|
934
|
+
* old one has gone, leaving the content none. A stack with no item draws no bar. The toolbar is
|
|
935
|
+
* beside the view host rather than around it, since SwiftUI makes the view a toolbar is on again
|
|
936
|
+
* as its items change.
|
|
937
|
+
*/
|
|
938
|
+
protected readonly stacked: Signal<boolean>;
|
|
834
939
|
/**
|
|
835
940
|
* SwiftUI reads how a sheet is presented from modifiers on its content, not from props. The
|
|
836
941
|
* detents of a sheet not sized to its content are followed while it is open.
|
|
837
942
|
*/
|
|
838
943
|
protected readonly presentation: Signal<readonly UiModifier[]>;
|
|
944
|
+
/** The `background-color` the element has from CSS, which the sheet draws rather than it. */
|
|
945
|
+
private readonly painted;
|
|
946
|
+
/** The sheet's colour: the input's, or else the element's from CSS. */
|
|
947
|
+
protected readonly color: Signal<{} | undefined>;
|
|
948
|
+
/**
|
|
949
|
+
* The sheet's own background, a colour converted as any colour is, where one is given. As a
|
|
950
|
+
* shape style for `@expo/ui` 57.0.17 and later, and as the plain colour the versions before it
|
|
951
|
+
* read, Expo Go's among them. Each ignores the other's field.
|
|
952
|
+
*/
|
|
953
|
+
private readonly background;
|
|
839
954
|
/**
|
|
840
955
|
* The one view a view host holds. Sized to its content it needs a width of its own, the
|
|
841
956
|
* window's; otherwise it fills the height the sheet gives it.
|
|
@@ -877,6 +992,6 @@ export declare class UiBottomSheet {
|
|
|
877
992
|
/** The sheet has gone: its content leaves the tree. */
|
|
878
993
|
private finish;
|
|
879
994
|
static ɵfac: i0.ɵɵFactoryDeclaration<UiBottomSheet, never>;
|
|
880
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<UiBottomSheet, "ui-bottom-sheet", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "fitToContents": { "alias": "fitToContents"; "required": false; "isSignal": true; }; "detents": { "alias": "detents"; "required": false; "isSignal": true; }; "showDragIndicator": { "alias": "showDragIndicator"; "required": false; "isSignal": true; }; }, { "open": "openChange"; "dismissed": "dismissed"; }, ["toolbarItems"], ["*", "ui-toolbar-item"], true, never>;
|
|
995
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<UiBottomSheet, "ui-bottom-sheet", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "fitToContents": { "alias": "fitToContents"; "required": false; "isSignal": true; }; "detents": { "alias": "detents"; "required": false; "isSignal": true; }; "showDragIndicator": { "alias": "showDragIndicator"; "required": false; "isSignal": true; }; "backgroundColor": { "alias": "backgroundColor"; "required": false; "isSignal": true; }; }, { "open": "openChange"; "dismissed": "dismissed"; }, ["toolbarItems"], ["*", "ui-toolbar-item"], true, never>;
|
|
881
996
|
}
|
|
882
997
|
export {};
|