@ng-native/expo 0.14.0 → 0.16.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 +2 -0
- package/android/src/main/java/dev/ngnative/expo/SearchFieldModule.kt +61 -0
- package/dist/camera.d.ts +28 -2
- package/dist/camera.js +26 -2
- package/dist/camera.js.map +1 -1
- package/dist/expo-ui-components.d.ts +73 -6
- package/dist/expo-ui-components.js +202 -54
- package/dist/expo-ui-components.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/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 +7 -3
- package/dist/register-expo-view.js +27 -7
- package/dist/register-expo-view.js.map +1 -1
- package/dist/search-field.d.ts +2 -0
- package/dist/search-field.js +15 -2
- package/dist/search-field.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/video.js +1 -1
- package/dist/video.js.map +1 -1
- package/ios/SearchField.swift +70 -0
- package/package.json +2 -2
package/android/build.gradle
CHANGED
|
@@ -19,4 +19,6 @@ dependencies {
|
|
|
19
19
|
implementation 'androidx.core:core:1.17.0'
|
|
20
20
|
// `<search-field>`'s SearchView. React Native depends on AppCompat already.
|
|
21
21
|
implementation 'androidx.appcompat:appcompat:1.7.0'
|
|
22
|
+
// ReactTypefaceUtils, which finds a face expo-font registered for `<search-field>` as a text's.
|
|
23
|
+
implementation 'com.facebook.react:react-android'
|
|
22
24
|
}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
package dev.ngnative.expo
|
|
2
2
|
|
|
3
3
|
import android.content.Context
|
|
4
|
+
import android.util.TypedValue
|
|
4
5
|
import android.view.inputmethod.InputMethodManager
|
|
6
|
+
import android.widget.TextView
|
|
5
7
|
import androidx.appcompat.widget.SearchView
|
|
8
|
+
import com.facebook.react.views.text.ReactTypefaceUtils
|
|
6
9
|
import expo.modules.kotlin.AppContext
|
|
7
10
|
import expo.modules.kotlin.modules.Module
|
|
8
11
|
import expo.modules.kotlin.modules.ModuleDefinition
|
|
12
|
+
import expo.modules.kotlin.types.Either
|
|
9
13
|
import expo.modules.kotlin.viewevent.EventDispatcher
|
|
10
14
|
import expo.modules.kotlin.views.ExpoView
|
|
11
15
|
|
|
@@ -29,6 +33,19 @@ class SearchFieldModule : Module() {
|
|
|
29
33
|
Prop("placeholder") { view: SearchFieldView, placeholder: String? ->
|
|
30
34
|
view.search.queryHint = placeholder
|
|
31
35
|
}
|
|
36
|
+
// The face and size the field's CSS resolves to, as a text's: the face by the name expo-font
|
|
37
|
+
// registers it under.
|
|
38
|
+
Prop("fontFamily") { view: SearchFieldView, family: String? -> view.fontFamily = family }
|
|
39
|
+
Prop("fontSize") { view: SearchFieldView, size: Double? -> view.fontSize = size?.toFloat() }
|
|
40
|
+
// A weight and a slant no matched face already draws: a number, or `normal` and `bold`.
|
|
41
|
+
Prop("fontWeight") { view: SearchFieldView, weight: Either<Double, String>? ->
|
|
42
|
+
view.fontWeight = when {
|
|
43
|
+
weight == null -> null
|
|
44
|
+
weight.`is`(Double::class) -> weight.get(Double::class).toInt().toString()
|
|
45
|
+
else -> weight.get(String::class)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
Prop("fontStyle") { view: SearchFieldView, style: String? -> view.fontStyle = style }
|
|
32
49
|
|
|
33
50
|
AsyncFunction("focus") { view: SearchFieldView -> view.focus() }.runOnQueue(expo.modules.kotlin.functions.Queues.MAIN)
|
|
34
51
|
AsyncFunction("blur") { view: SearchFieldView -> view.search.clearFocus() }.runOnQueue(expo.modules.kotlin.functions.Queues.MAIN)
|
|
@@ -85,6 +102,50 @@ class SearchFieldView(context: Context, appContext: AppContext) : ExpoView(conte
|
|
|
85
102
|
addView(search, LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT))
|
|
86
103
|
}
|
|
87
104
|
|
|
105
|
+
/** The text box, and the face and size it starts with, put back when the CSS names none. */
|
|
106
|
+
private val input = search.findViewById<TextView>(androidx.appcompat.R.id.search_src_text)
|
|
107
|
+
private val systemTypeface = input?.typeface
|
|
108
|
+
private val systemTextSize = input?.textSize
|
|
109
|
+
|
|
110
|
+
var fontFamily: String? = null
|
|
111
|
+
set(value) {
|
|
112
|
+
field = value
|
|
113
|
+
applyFont()
|
|
114
|
+
}
|
|
115
|
+
var fontSize: Float? = null
|
|
116
|
+
set(value) {
|
|
117
|
+
field = value
|
|
118
|
+
applyFont()
|
|
119
|
+
}
|
|
120
|
+
var fontWeight: String? = null
|
|
121
|
+
set(value) {
|
|
122
|
+
field = value
|
|
123
|
+
applyFont()
|
|
124
|
+
}
|
|
125
|
+
var fontStyle: String? = null
|
|
126
|
+
set(value) {
|
|
127
|
+
field = value
|
|
128
|
+
applyFont()
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* The CSS's face, weight and slant, found as a text's is, at its size in sp, so it scales with the
|
|
133
|
+
* font size setting.
|
|
134
|
+
*/
|
|
135
|
+
private fun applyFont() {
|
|
136
|
+
val input = input ?: return
|
|
137
|
+
input.typeface = ReactTypefaceUtils.applyStyles(
|
|
138
|
+
systemTypeface,
|
|
139
|
+
ReactTypefaceUtils.parseFontStyle(fontStyle),
|
|
140
|
+
ReactTypefaceUtils.parseFontWeight(fontWeight),
|
|
141
|
+
fontFamily,
|
|
142
|
+
context.assets,
|
|
143
|
+
)
|
|
144
|
+
val size = fontSize
|
|
145
|
+
if (size != null) input.setTextSize(TypedValue.COMPLEX_UNIT_SP, size)
|
|
146
|
+
else if (systemTextSize != null) input.setTextSize(TypedValue.COMPLEX_UNIT_PX, systemTextSize)
|
|
147
|
+
}
|
|
148
|
+
|
|
88
149
|
/** Puts JavaScript's text in the field, unless it answers a keystroke older than the last one. */
|
|
89
150
|
private fun applyText() {
|
|
90
151
|
if (mostRecentEventCount < eventCount || search.query.toString() == text) return
|
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,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
|
*/
|
|
@@ -52,6 +56,26 @@ export class Camera {
|
|
|
52
56
|
return null;
|
|
53
57
|
return this.functions.takePicture.call({ nativeTag }, options);
|
|
54
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
|
+
}
|
|
55
79
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: Camera, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
56
80
|
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.2.0", type: Camera, isStandalone: true, selector: "expo-camera", exportAs: ["camera"], ngImport: i0 });
|
|
57
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"]}
|
|
@@ -42,12 +42,14 @@ export interface UiModifier {
|
|
|
42
42
|
*/
|
|
43
43
|
export declare class UiHost {
|
|
44
44
|
protected readonly nativeView: true;
|
|
45
|
+
protected readonly android: boolean;
|
|
45
46
|
readonly matchContents: import("@angular/core").InputSignal<boolean | {
|
|
46
47
|
readonly vertical?: boolean;
|
|
47
48
|
readonly horizontal?: boolean;
|
|
48
49
|
} | undefined>;
|
|
49
50
|
protected readonly matchVertical: Signal<boolean | undefined>;
|
|
50
51
|
protected readonly matchHorizontal: Signal<boolean | undefined>;
|
|
52
|
+
/** The safe area SwiftUI's host ignores, iOS only: Compose's host has no such prop. */
|
|
51
53
|
readonly ignoreSafeArea: import("@angular/core").InputSignal<"all" | "keyboard" | "container" | undefined>;
|
|
52
54
|
readonly useViewportSizeMeasurement: import("@angular/core").InputSignalWithTransform<boolean | undefined, unknown>;
|
|
53
55
|
static ɵfac: i0.ɵɵFactoryDeclaration<UiHost, never>;
|
|
@@ -56,11 +58,14 @@ export declare class UiHost {
|
|
|
56
58
|
/** A SwiftUI `Menu`. Its trigger is the `label` or a `<ui-slot name="label">`; its items are children. */
|
|
57
59
|
export declare class UiMenu {
|
|
58
60
|
protected readonly nativeView: true;
|
|
61
|
+
protected readonly android: boolean;
|
|
59
62
|
readonly label: import("@angular/core").InputSignal<string | undefined>;
|
|
60
63
|
/** An SF Symbol name. */
|
|
61
64
|
readonly systemImage: import("@angular/core").InputSignal<string | undefined>;
|
|
65
|
+
/** What VoiceOver reads for the menu's trigger: SwiftUI's `accessibilityLabel` modifier. */
|
|
62
66
|
readonly accessibilityLabel: import("@angular/core").InputSignal<string | undefined>;
|
|
63
67
|
readonly modifiers: import("@angular/core").InputSignal<readonly UiModifier[] | undefined>;
|
|
68
|
+
protected readonly resolvedModifiers: Signal<readonly UiModifier[] | undefined>;
|
|
64
69
|
static ɵfac: i0.ɵɵFactoryDeclaration<UiMenu, never>;
|
|
65
70
|
static ɵcmp: i0.ɵɵComponentDeclaration<UiMenu, "ui-menu", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "systemImage": { "alias": "systemImage"; "required": false; "isSignal": true; }; "accessibilityLabel": { "alias": "accessibilityLabel"; "required": false; "isSignal": true; }; "modifiers": { "alias": "modifiers"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
66
71
|
}
|
|
@@ -75,6 +80,7 @@ export declare class UiMenu {
|
|
|
75
80
|
* and no height.
|
|
76
81
|
*/
|
|
77
82
|
export declare class UiViewHost {
|
|
83
|
+
protected readonly android: boolean;
|
|
78
84
|
protected readonly nativeView: true;
|
|
79
85
|
readonly matchContents: import("@angular/core").InputSignalWithTransform<boolean | undefined, unknown>;
|
|
80
86
|
/**
|
|
@@ -82,6 +88,7 @@ export declare class UiViewHost {
|
|
|
82
88
|
* delivers its touches: it then takes them itself, and is measured from itself.
|
|
83
89
|
*/
|
|
84
90
|
readonly layoutRoot: import("@angular/core").InputSignalWithTransform<boolean | undefined, unknown>;
|
|
91
|
+
/** Compose's modifiers for the view host, Android only: SwiftUI's view host takes none. */
|
|
85
92
|
readonly modifiers: import("@angular/core").InputSignal<readonly UiModifier[] | undefined>;
|
|
86
93
|
static ɵfac: i0.ɵɵFactoryDeclaration<UiViewHost, never>;
|
|
87
94
|
static ɵcmp: i0.ɵɵComponentDeclaration<UiViewHost, "ui-view-host", never, { "matchContents": { "alias": "matchContents"; "required": false; "isSignal": true; }; "layoutRoot": { "alias": "layoutRoot"; "required": false; "isSignal": true; }; "modifiers": { "alias": "modifiers"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
@@ -115,7 +122,8 @@ export declare class UiButton {
|
|
|
115
122
|
readonly role: import("@angular/core").InputSignal<"default" | "cancel" | "destructive" | "close" | undefined>;
|
|
116
123
|
/**
|
|
117
124
|
* In a home-screen widget's or a Live Activity's layout, what a tap on it hands the app: see
|
|
118
|
-
* `@ng-native/expo/widget` and `@ng-native/expo/live-activity`.
|
|
125
|
+
* `@ng-native/expo/widget` and `@ng-native/expo/live-activity`. The layout's build reads it, so
|
|
126
|
+
* an app's own button is not sent it: `@expo/ui`'s button there has no target.
|
|
119
127
|
*/
|
|
120
128
|
readonly target: import("@angular/core").InputSignal<string | undefined>;
|
|
121
129
|
readonly modifiers: import("@angular/core").InputSignal<readonly UiModifier[] | undefined>;
|
|
@@ -139,6 +147,7 @@ export declare class UiSlot {
|
|
|
139
147
|
protected readonly nativeView: true;
|
|
140
148
|
protected readonly android: boolean;
|
|
141
149
|
readonly name: import("@angular/core").InputSignal<string>;
|
|
150
|
+
/** What the slot tells its SwiftUI parent about itself, iOS only. */
|
|
142
151
|
readonly extraProps: import("@angular/core").InputSignal<Readonly<Record<string, unknown>> | undefined>;
|
|
143
152
|
static ɵfac: i0.ɵɵFactoryDeclaration<UiSlot, never>;
|
|
144
153
|
static ɵcmp: i0.ɵɵComponentDeclaration<UiSlot, "ui-slot", never, { "name": { "alias": "name"; "required": true; "isSignal": true; }; "extraProps": { "alias": "extraProps"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
@@ -213,12 +222,22 @@ export declare class UiVStack {
|
|
|
213
222
|
*/
|
|
214
223
|
export declare class UiImage {
|
|
215
224
|
protected readonly nativeView: true;
|
|
225
|
+
/** Compose's image is another control, which takes a `source`: none of these are its. */
|
|
226
|
+
protected readonly android: boolean;
|
|
216
227
|
readonly systemName: import("@angular/core").InputSignal<string | undefined>;
|
|
217
228
|
readonly assetName: import("@angular/core").InputSignal<string | undefined>;
|
|
218
229
|
readonly uiImage: import("@angular/core").InputSignal<string | undefined>;
|
|
230
|
+
/**
|
|
231
|
+
* A symbol's size in points, as a `font` modifier of that size, which does not scale with
|
|
232
|
+
* Dynamic Type. A `font` modifier in `modifiers` wins over it. Without either, the symbol is
|
|
233
|
+
* SwiftUI's default size, where `@expo/ui`'s own `Image` and a widget layout draw it at 24.
|
|
234
|
+
*/
|
|
219
235
|
readonly size: import("@angular/core").InputSignalWithTransform<number | undefined, unknown>;
|
|
236
|
+
/** A symbol's colour, as a `foregroundStyle` modifier. */
|
|
220
237
|
readonly color: import("@angular/core").InputSignal<string | undefined>;
|
|
221
238
|
readonly modifiers: import("@angular/core").InputSignal<readonly UiModifier[] | undefined>;
|
|
239
|
+
/** SwiftUI's image reads neither `size` nor `color`: `@expo/ui`'s `Image` makes them modifiers. */
|
|
240
|
+
protected readonly resolvedModifiers: Signal<readonly UiModifier[] | undefined>;
|
|
222
241
|
static ɵfac: i0.ɵɵFactoryDeclaration<UiImage, never>;
|
|
223
242
|
static ɵcmp: i0.ɵɵComponentDeclaration<UiImage, "ui-image", never, { "systemName": { "alias": "systemName"; "required": false; "isSignal": true; }; "assetName": { "alias": "assetName"; "required": false; "isSignal": true; }; "uiImage": { "alias": "uiImage"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "modifiers": { "alias": "modifiers"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
224
243
|
}
|
|
@@ -299,7 +318,16 @@ export declare class UiDatePicker {
|
|
|
299
318
|
protected readonly resolvedSelection: Signal<string | undefined>;
|
|
300
319
|
/** SwiftUI takes a list of what to show, and Compose one word for it. */
|
|
301
320
|
protected readonly resolvedComponents: Signal<"date" | "hourAndMinute" | readonly ("date" | "hourAndMinute")[] | "dateAndTime" | undefined>;
|
|
302
|
-
protected readonly initialDate: Signal<number | null
|
|
321
|
+
protected readonly initialDate: Signal<number | null>;
|
|
322
|
+
/** Compose takes `range` as `selectableDates`, each end in milliseconds. */
|
|
323
|
+
protected readonly selectableDates: Signal<{
|
|
324
|
+
start: number | null;
|
|
325
|
+
end: number | null;
|
|
326
|
+
} | undefined>;
|
|
327
|
+
/**
|
|
328
|
+
* SwiftUI's picker reads `disabled` and `accessibilityLabel` as modifiers, and Compose's reads
|
|
329
|
+
* `accessibilityLabel` as the `semantics` modifier's `contentDescription`.
|
|
330
|
+
*/
|
|
303
331
|
protected readonly resolvedModifiers: Signal<readonly UiModifier[] | undefined>;
|
|
304
332
|
/**
|
|
305
333
|
* SwiftUI's picker cannot be empty: it shows today, and reports that as a change the moment it
|
|
@@ -397,6 +425,8 @@ export declare class UiPicker {
|
|
|
397
425
|
/** Each option's `tag`, one array per value, so a pass hands native the same objects. */
|
|
398
426
|
protected readonly tags: Signal<Map<string | number, readonly UiModifier[]>>;
|
|
399
427
|
protected readonly android: boolean;
|
|
428
|
+
/** SwiftUI's picker view draws nothing without a label, and a segmented one never shows it. */
|
|
429
|
+
protected readonly shownLabel: Signal<string>;
|
|
400
430
|
/** Whether Android's dropdown is open. */
|
|
401
431
|
protected readonly open: import("@angular/core").WritableSignal<boolean>;
|
|
402
432
|
/**
|
|
@@ -488,17 +518,25 @@ export declare class UiColorPicker {
|
|
|
488
518
|
static ɵfac: i0.ɵɵFactoryDeclaration<UiColorPicker, never>;
|
|
489
519
|
static ɵcmp: i0.ɵɵComponentDeclaration<UiColorPicker, "ui-color-picker", never, { "selection": { "alias": "selection"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "supportsOpacity": { "alias": "supportsOpacity"; "required": false; "isSignal": true; }; "modifiers": { "alias": "modifiers"; "required": false; "isSignal": true; }; }, { "selectionChange": "selectionChange"; }, never, never, true, never>;
|
|
490
520
|
}
|
|
491
|
-
/**
|
|
521
|
+
/**
|
|
522
|
+
* A SwiftUI `Gauge`: `value` between `min` and `max`, drawn as `type` says, with its labels drawn as
|
|
523
|
+
* text in the slots SwiftUI reads them from, as `@expo/ui`'s `Gauge` draws them.
|
|
524
|
+
*/
|
|
492
525
|
export declare class UiGauge {
|
|
493
526
|
protected readonly nativeView: true;
|
|
494
527
|
readonly value: import("@angular/core").InputSignalWithTransform<number | undefined, unknown>;
|
|
495
528
|
readonly min: import("@angular/core").InputSignalWithTransform<number | undefined, unknown>;
|
|
496
529
|
readonly max: import("@angular/core").InputSignalWithTransform<number | undefined, unknown>;
|
|
530
|
+
/**
|
|
531
|
+
* How it is drawn, as the `gaugeStyle` modifier: `'automatic'`, `'circular'`,
|
|
532
|
+
* `'circularCapacity'`, `'linear'` or `'linearCapacity'`.
|
|
533
|
+
*/
|
|
497
534
|
readonly type: import("@angular/core").InputSignal<string | undefined>;
|
|
498
535
|
readonly currentValueLabel: import("@angular/core").InputSignal<string | undefined>;
|
|
499
536
|
readonly minimumValueLabel: import("@angular/core").InputSignal<string | undefined>;
|
|
500
537
|
readonly maximumValueLabel: import("@angular/core").InputSignal<string | undefined>;
|
|
501
538
|
readonly modifiers: import("@angular/core").InputSignal<readonly UiModifier[] | undefined>;
|
|
539
|
+
protected readonly resolvedModifiers: Signal<readonly UiModifier[] | undefined>;
|
|
502
540
|
static ɵfac: i0.ɵɵFactoryDeclaration<UiGauge, never>;
|
|
503
541
|
static ɵcmp: i0.ɵɵComponentDeclaration<UiGauge, "ui-gauge", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "currentValueLabel": { "alias": "currentValueLabel"; "required": false; "isSignal": true; }; "minimumValueLabel": { "alias": "minimumValueLabel"; "required": false; "isSignal": true; }; "maximumValueLabel": { "alias": "maximumValueLabel"; "required": false; "isSignal": true; }; "modifiers": { "alias": "modifiers"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
504
542
|
}
|
|
@@ -698,8 +736,14 @@ export declare class UiLabel {
|
|
|
698
736
|
readonly title: import("@angular/core").InputSignal<string | undefined>;
|
|
699
737
|
/** An SF Symbol name. */
|
|
700
738
|
readonly systemImage: import("@angular/core").InputSignal<string | undefined>;
|
|
739
|
+
/**
|
|
740
|
+
* The colour of the symbol alone, drawn as the label's icon in that colour, since SwiftUI's
|
|
741
|
+
* label takes no colour. The `foregroundStyle` modifier colours the title too.
|
|
742
|
+
*/
|
|
701
743
|
readonly color: import("@angular/core").InputSignal<string | undefined>;
|
|
702
744
|
readonly modifiers: import("@angular/core").InputSignal<readonly UiModifier[] | undefined>;
|
|
745
|
+
/** The icon's colour, when there is a symbol to draw in it. */
|
|
746
|
+
protected readonly iconColor: Signal<UiModifier | undefined>;
|
|
703
747
|
static ɵfac: i0.ɵɵFactoryDeclaration<UiLabel, never>;
|
|
704
748
|
static ɵcmp: i0.ɵɵComponentDeclaration<UiLabel, "ui-label", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "systemImage": { "alias": "systemImage"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "modifiers": { "alias": "modifiers"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
705
749
|
}
|
|
@@ -730,13 +774,19 @@ export declare class UiForm {
|
|
|
730
774
|
static ɵfac: i0.ɵɵFactoryDeclaration<UiForm, never>;
|
|
731
775
|
static ɵcmp: i0.ɵɵComponentDeclaration<UiForm, "ui-form", never, { "modifiers": { "alias": "modifiers"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
732
776
|
}
|
|
733
|
-
/**
|
|
777
|
+
/**
|
|
778
|
+
* A SwiftUI `Section` of a form or a list, under `title`, iOS only. A `<ui-slot name="header">`
|
|
779
|
+
* is its header in place of a `title`, and a `<ui-slot name="footer">` is the note under its rows.
|
|
780
|
+
* When both a non-empty `title` and a header slot are set, `@expo/ui`'s `SectionView` draws the
|
|
781
|
+
* `title` and drops the slot; an empty `title` counts as unset. The slot's `name` is written as it is,
|
|
782
|
+
* not bound, as that is what picks it out of the rows.
|
|
783
|
+
*/
|
|
734
784
|
export declare class UiSection {
|
|
735
785
|
protected readonly nativeView: true;
|
|
736
786
|
readonly title: import("@angular/core").InputSignal<string | undefined>;
|
|
737
787
|
readonly modifiers: import("@angular/core").InputSignal<readonly UiModifier[] | undefined>;
|
|
738
788
|
static ɵfac: i0.ɵɵFactoryDeclaration<UiSection, never>;
|
|
739
|
-
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>;
|
|
789
|
+
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>;
|
|
740
790
|
}
|
|
741
791
|
/**
|
|
742
792
|
* A SwiftUI `Group`, iOS only: its children as they are, with no layout of its own. What it is for
|
|
@@ -882,6 +932,13 @@ export declare class UiBottomSheet {
|
|
|
882
932
|
readonly detents: import("@angular/core").InputSignal<readonly UiPresentationDetent[] | undefined>;
|
|
883
933
|
/** Whether the grabber shows at the top of the sheet. */
|
|
884
934
|
readonly showDragIndicator: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
935
|
+
/**
|
|
936
|
+
* The colour of the sheet behind its content: SwiftUI's `presentationBackground` on iOS, where
|
|
937
|
+
* a sheet below its full height is otherwise drawn as glass, and Compose's `containerColor` on
|
|
938
|
+
* Android. Over a `background-color` the element has from CSS, which colours the sheet the same
|
|
939
|
+
* way. Neither is the sheet as the system draws it.
|
|
940
|
+
*/
|
|
941
|
+
readonly backgroundColor: import("@angular/core").InputSignal<string | undefined>;
|
|
885
942
|
/**
|
|
886
943
|
* The sheet has finished closing, whether the user dismissed it or `open` was set false: the
|
|
887
944
|
* moment another sheet or a dialog can be presented.
|
|
@@ -928,6 +985,16 @@ export declare class UiBottomSheet {
|
|
|
928
985
|
* detents of a sheet not sized to its content are followed while it is open.
|
|
929
986
|
*/
|
|
930
987
|
protected readonly presentation: Signal<readonly UiModifier[]>;
|
|
988
|
+
/** The `background-color` the element has from CSS, which the sheet draws rather than it. */
|
|
989
|
+
private readonly painted;
|
|
990
|
+
/** The sheet's colour: the input's, or else the element's from CSS. */
|
|
991
|
+
protected readonly color: Signal<{} | undefined>;
|
|
992
|
+
/**
|
|
993
|
+
* The sheet's own background, a colour converted as any colour is, where one is given. As a
|
|
994
|
+
* shape style for `@expo/ui` 57.0.17 and later, and as the plain colour the versions before it
|
|
995
|
+
* read, Expo Go's among them. Each ignores the other's field.
|
|
996
|
+
*/
|
|
997
|
+
private readonly background;
|
|
931
998
|
/**
|
|
932
999
|
* The one view a view host holds. Sized to its content it needs a width of its own, the
|
|
933
1000
|
* window's; otherwise it fills the height the sheet gives it.
|
|
@@ -969,6 +1036,6 @@ export declare class UiBottomSheet {
|
|
|
969
1036
|
/** The sheet has gone: its content leaves the tree. */
|
|
970
1037
|
private finish;
|
|
971
1038
|
static ɵfac: i0.ɵɵFactoryDeclaration<UiBottomSheet, never>;
|
|
972
|
-
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>;
|
|
1039
|
+
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>;
|
|
973
1040
|
}
|
|
974
1041
|
export {};
|