@lingxia/types 0.8.0 → 0.10.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.
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Share APIs.
3
+ */
4
+
5
+ export type ShareQuery = Record<string, string | number | boolean>;
6
+
7
+ export type SharePage =
8
+ /**
9
+ * Share the current page.
10
+ */
11
+ | true
12
+ /**
13
+ * Share the current page with query.
14
+ */
15
+ | {
16
+ /**
17
+ * Query appended to the current page. Query belongs to the page target and is
18
+ * encoded into the AppLink URL.
19
+ */
20
+ query?: ShareQuery;
21
+ };
22
+
23
+ interface ShareTitleOptions {
24
+ /**
25
+ * Share title.
26
+ */
27
+ title?: string;
28
+ }
29
+
30
+ interface ShareTextBaseOptions extends ShareTitleOptions {
31
+ /**
32
+ * Share text body.
33
+ */
34
+ text?: string;
35
+ }
36
+
37
+ /**
38
+ * Share title/text only. Receiver support is platform/app dependent; some
39
+ * share extensions may reject text-only shares.
40
+ */
41
+ export interface ShareTextOptions extends ShareTextBaseOptions {
42
+ page?: never;
43
+ files?: never;
44
+ }
45
+
46
+ /**
47
+ * Share the current page as an AppLink.
48
+ */
49
+ export interface SharePageOptions extends ShareTextBaseOptions {
50
+ /**
51
+ * Share the current page. The runtime uses the current appId and page path
52
+ * implicitly and shares it through the host AppLink configuration.
53
+ *
54
+ * Rejects when the host app has no `appLinks.hosts` configuration because
55
+ * receivers would not be able to open the shared page.
56
+ *
57
+ * `title` and `text` are presentation hints. Platforms and receivers may
58
+ * ignore them; on iOS the URL is shared by itself so receivers can render it
59
+ * as a webpage card when they support that.
60
+ *
61
+ * `page` and `files` are mutually exclusive.
62
+ */
63
+ page: SharePage;
64
+ files?: never;
65
+ }
66
+
67
+ /**
68
+ * Share images, PDFs, or other files.
69
+ */
70
+ export interface ShareFilesOptions extends ShareTitleOptions {
71
+ /**
72
+ * File paths returned by LingXia APIs to share. Images, PDFs, and other
73
+ * documents are all represented as file paths.
74
+ *
75
+ * Use `lx.chooseFile` for system files and `lx.chooseMedia` for picked media;
76
+ * pass the returned path here without parsing it.
77
+ * Some platforms or receivers may limit multi-file shares. Share files one
78
+ * at a time when targeting those receivers.
79
+ *
80
+ * `files` and `page` are mutually exclusive.
81
+ * `text` is intentionally not supported for file shares because system
82
+ * receivers handle text+attachment inconsistently.
83
+ */
84
+ files: string[];
85
+ page?: never;
86
+ text?: never;
87
+ }
88
+
89
+ export type ShareOptions = ShareTextOptions | SharePageOptions | ShareFilesOptions;
90
+
91
+ export interface ShareResult {
92
+ /**
93
+ * Best-effort completion flag. Some platforms can only confirm that the
94
+ * system share UI was opened or closed.
95
+ */
96
+ completed?: boolean;
97
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * System settings and URL APIs.
2
+ * System settings.
3
3
  */
4
4
 
5
5
  export interface SystemSettingInfo {
@@ -7,8 +7,3 @@ export interface SystemSettingInfo {
7
7
  locationEnabled: boolean;
8
8
  wifiEnabled: boolean;
9
9
  }
10
-
11
- export interface OpenURLOptions {
12
- url: string;
13
- target?: 'self' | 'external';
14
- }
@@ -2,7 +2,22 @@
2
2
  * Transfer task APIs.
3
3
  */
4
4
 
5
- export interface DownloadOptions {
5
+ declare const appDownloadPathBrand: unique symbol;
6
+ declare const systemDownloadsPathBrand: unique symbol;
7
+
8
+ export type DownloadDestination = 'app' | 'downloads';
9
+
10
+ /** Runtime-managed app download path, usually under `lx://userdata`. */
11
+ export type AppDownloadFilePath = string & {
12
+ readonly [appDownloadPathBrand]: 'app-download-file-path';
13
+ };
14
+
15
+ /** Native system Downloads path. Do not pass this to `FileManager`. */
16
+ export type SystemDownloadsPath = string & {
17
+ readonly [systemDownloadsPathBrand]: 'system-downloads-path';
18
+ };
19
+
20
+ export interface DownloadOptionsBase {
6
21
  /** HTTP(S) source URL. */
7
22
  url: string;
8
23
  /**
@@ -12,35 +27,66 @@ export interface DownloadOptions {
12
27
  headers?: Record<string, string>;
13
28
  /** Request timeout in milliseconds. */
14
29
  timeout?: number;
30
+ /** Optional abort signal. */
31
+ signal?: AbortSignal;
32
+ }
33
+
34
+ export interface AppDownloadOptions extends DownloadOptionsBase {
15
35
  /**
16
- * Optional durable destination.
17
- *
18
- * - Omit `filePath` to receive a temporary file in `tempFilePath`
19
- * - Relative paths resolve under user data
20
- * - `lx://` paths must target `lx://userdata`
36
+ * Optional app-owned durable output path.
21
37
  *
38
+ * Omit `filePath` to receive a temporary result in `tempFilePath`. Relative
39
+ * paths resolve under user data. `lx://` paths must target `lx://userdata`;
22
40
  * `lx://usercache` is not accepted here.
23
41
  */
24
42
  filePath?: string;
25
- /** Optional abort signal. */
26
- signal?: AbortSignal;
43
+ /**
44
+ * App-owned output. Omit to use a temporary output unless `filePath` is set.
45
+ */
46
+ destination?: 'app';
47
+ }
48
+
49
+ export interface DownloadsDownloadOptions extends DownloadOptionsBase {
50
+ /**
51
+ * Optional filename hint for the system Downloads destination.
52
+ * This is not an app-owned FileManager path.
53
+ */
54
+ filePath?: string;
55
+ /** Save into the user's system Downloads directory. */
56
+ destination: 'downloads';
27
57
  }
28
58
 
29
- export interface DownloadProgressEvent {
59
+ /**
60
+ * Download options.
61
+ *
62
+ * - `app`: app-owned temporary output, or durable `lx://userdata` output when
63
+ * `filePath` is set
64
+ * - `downloads`: user-visible system Downloads output, requiring
65
+ * `security.privileges: ["downloads"]` in `lxapp.json`
66
+ *
67
+ * Default: `app`.
68
+ */
69
+ export type DownloadOptions<TDestination extends DownloadDestination = DownloadDestination> =
70
+ TDestination extends 'downloads' ? DownloadsDownloadOptions : AppDownloadOptions;
71
+
72
+ export type DownloadResultForDestination<TDestination extends DownloadDestination> =
73
+ TDestination extends 'downloads' ? DownloadsDownloadResult : AppDownloadResult;
74
+
75
+ export interface DownloadProgressEvent<TResult extends DownloadResult = DownloadResult> {
30
76
  kind: 'progress' | 'paused' | 'resumed' | 'canceled' | 'completed';
31
77
  downloadedBytes?: number;
32
78
  totalBytes?: number;
33
79
  /** Present only when the total size is known. */
34
80
  progress?: number;
35
- result?: DownloadResult;
81
+ result?: TResult;
36
82
  }
37
83
 
38
- export interface DownloadIteratorResult {
84
+ export interface DownloadIteratorResult<TResult extends DownloadResult = DownloadResult> {
39
85
  done: boolean;
40
- value?: DownloadProgressEvent;
86
+ value?: DownloadProgressEvent<TResult>;
41
87
  }
42
88
 
43
- export type DownloadResult =
89
+ export type AppDownloadResult =
44
90
  | {
45
91
  /**
46
92
  * Temporary result.
@@ -57,26 +103,38 @@ export type DownloadResult =
57
103
  }
58
104
  | {
59
105
  /** Durable destination under `lx://userdata`. */
60
- filePath: string;
106
+ filePath: AppDownloadFilePath;
61
107
  tempFilePath?: never;
62
108
  mimeType?: string;
63
109
  size: number;
64
110
  };
65
111
 
66
- export interface DownloadTask extends PromiseLike<DownloadResult>, AsyncIterable<DownloadProgressEvent> {
67
- next(): Promise<DownloadIteratorResult>;
112
+ export interface DownloadsDownloadResult {
113
+ /** Native system Downloads path. Do not pass this to `FileManager`. */
114
+ filePath: SystemDownloadsPath;
115
+ tempFilePath?: never;
116
+ mimeType?: string;
117
+ size: number;
118
+ }
119
+
120
+ export type DownloadResult = AppDownloadResult | DownloadsDownloadResult;
121
+
122
+ export interface DownloadTask<TDownloadResult extends DownloadResult = DownloadResult>
123
+ extends PromiseLike<TDownloadResult>,
124
+ AsyncIterable<DownloadProgressEvent<TDownloadResult>> {
125
+ next(): Promise<DownloadIteratorResult<TDownloadResult>>;
68
126
  /** Stops iteration only. Does not cancel the underlying download task. */
69
- return(): Promise<DownloadIteratorResult>;
70
- catch<TResult = never>(
71
- onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null,
72
- ): Promise<DownloadResult | TResult>;
73
- finally(onfinally?: (() => void) | null): Promise<DownloadResult>;
127
+ return(): Promise<DownloadIteratorResult<TDownloadResult>>;
128
+ catch<TRejected = never>(
129
+ onrejected?: ((reason: unknown) => TRejected | PromiseLike<TRejected>) | null,
130
+ ): Promise<TDownloadResult | TRejected>;
131
+ finally(onfinally?: (() => void) | null): Promise<TDownloadResult>;
74
132
  pause(): Promise<void>;
75
133
  resume(): Promise<void>;
76
134
  cancel(): Promise<void>;
77
135
  /** Alias for cancel(), matching browser/mini-program abort naming. */
78
136
  abort(): Promise<void>;
79
- wait(): Promise<DownloadResult>;
137
+ wait(): Promise<TDownloadResult>;
80
138
  }
81
139
 
82
140
  export interface UploadOptions {
package/src/ui/index.ts CHANGED
@@ -38,13 +38,33 @@ export interface ActionSheetResult {
38
38
  export type PageQueryValue = string | number | boolean | null | undefined;
39
39
  export type PageQuery = Record<string, PageQueryValue>;
40
40
 
41
+ /**
42
+ * Target page for `navigateTo` / `redirectTo` / `switchTab` / `reLaunch`.
43
+ *
44
+ * Pass **exactly one** of `page` or `path` — there is **no `url` field**:
45
+ * - `page` — a configured page **name** from `lingxia.yaml` / `lxapp.json`
46
+ * (e.g. `"pullToRefresh"`), resolved to its route by the page registry.
47
+ * - `path` — the full page **route**, e.g. `"/pages/pulltorefresh/index"`.
48
+ *
49
+ * Both are discoverable with `lxdev lxapp pages`, which lists every page's
50
+ * `name` and `path`; `lxdev lxapp nav to|relaunch|redirect|switch-tab <name>`
51
+ * drives navigation by name when automating.
52
+ */
41
53
  export type PageTargetOptions =
42
54
  | {
55
+ /**
56
+ * Configured page **name** from `lingxia.yaml` / `lxapp.json`
57
+ * (e.g. `"pullToRefresh"`). Mutually exclusive with `path`.
58
+ */
43
59
  page: string;
44
60
  path?: never;
45
61
  query?: PageQuery;
46
62
  }
47
63
  | {
64
+ /**
65
+ * Full page **route**, e.g. `"/pages/pulltorefresh/index"`.
66
+ * Mutually exclusive with `page`.
67
+ */
48
68
  path: string;
49
69
  page?: never;
50
70
  query?: PageQuery;
@@ -98,77 +118,42 @@ export interface SetTabBarItemOptions {
98
118
  selectedIconPath?: string;
99
119
  }
100
120
 
101
- export type SurfaceQueryValue = PageQueryValue;
102
- export type SurfaceQuery = PageQuery;
103
-
104
- export type SurfacePageTargetOptions =
105
- | {
106
- page: string;
107
- path?: never;
108
- url?: never;
109
- query?: SurfaceQuery;
110
- }
111
- | {
112
- path: string;
113
- page?: never;
114
- url?: never;
115
- query?: SurfaceQuery;
116
- };
117
-
118
- export type SurfaceUrlTargetOptions = {
119
- url: string;
120
- page?: never;
121
- path?: never;
122
- query?: never;
123
- };
124
-
125
- export type SurfaceTargetOptions = SurfacePageTargetOptions | SurfaceUrlTargetOptions;
121
+ // ── Adaptive Surface Layout ─────────────────────────────────────────────────
122
+ // The form is expressed by the `as` field on `lx.openSurface({ page, as })`; the
123
+ // Host arbitrates the realized platform form (split pane on larger screens,
124
+ // full-screen drill-in on compact screens).
126
125
 
127
126
  /**
128
- * Overlay surface size value.
127
+ * Size hint for an overlay surface (aside / float).
129
128
  *
130
- * - number: absolute size, must be > 0
131
- * - `${number}%`: percentage size, must be > 0% and <= 100%
129
+ * - number: absolute px, must be > 0
130
+ * - `${number}%`: percentage of the container, 0 < N ≤ 100
132
131
  */
133
132
  export type OverlaySurfaceSizeValue = number | `${number}%`;
134
133
 
135
134
  export interface OverlaySurfaceSize {
136
- /** Width for overlay surface. */
135
+ /** Width hint. */
137
136
  width?: OverlaySurfaceSizeValue;
138
- /** Height for overlay surface. */
137
+ /** Height hint. */
139
138
  height?: OverlaySurfaceSizeValue;
140
139
  }
141
140
 
142
- /**
143
- * Overlay surface: a webview composited on top of the host activity's
144
- * content. Cross-platform. Covers the screen (or a fraction of it) until
145
- * closed; coexists with native media preview at the same z-tier — the
146
- * later-added overlay or preview wins compositing order.
147
- */
148
- export type OverlaySurfaceOptions = SurfaceTargetOptions & {
149
- kind: 'overlay';
150
- position?: 'center' | 'bottom' | 'left' | 'right' | 'top';
151
- size?: OverlaySurfaceSize;
152
- };
153
-
154
- export interface WindowSurfaceSize {
155
- /** Window width, must be a positive number. */
156
- width?: number;
157
- /** Window height, must be a positive number. */
158
- height?: number;
159
- }
141
+ /** Edge an aside docks to; the Host decides the realized form by screen size. */
142
+ export type SurfaceEdge = 'left' | 'right' | 'top' | 'bottom';
143
+
144
+ /** Where a float popup anchors (default `center`). */
145
+ export type SurfaceFloatPosition = 'center' | 'top' | 'bottom' | 'left' | 'right';
160
146
 
161
147
  /**
162
- * Window-kind surfaces are macOS-only. Android, iOS, and Harmony reject
163
- * `kind: 'window'` at open() and surface a `surface_open_failed` error;
164
- * use `OverlaySurfaceOptions` for cross-platform code.
148
+ * The window's adaptive context, delivered to `lx.onSurfaceContext()` so an
149
+ * lxapp can self-adapt (e.g. switch column count by `sizeClass`).
165
150
  */
166
- export type WindowSurfaceOptions = SurfaceTargetOptions & {
167
- kind: 'window';
168
- size?: WindowSurfaceSize;
169
- };
170
-
171
- export type SurfaceOpenOptions = OverlaySurfaceOptions | WindowSurfaceOptions;
151
+ export interface SurfaceContext {
152
+ /** compact (<600) / medium (600–840) / expanded (>840), with hysteresis. */
153
+ sizeClass: 'compact' | 'medium' | 'expanded';
154
+ /** In compact, the bottom region belongs to the app content. */
155
+ bottomOwner: 'app';
156
+ }
172
157
 
173
158
  export interface CapsuleRect {
174
159
  width?: number;