@thelacanians/vue-native-runtime 0.1.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/dist/index.cjs +1847 -0
- package/dist/index.d.cts +1844 -0
- package/dist/index.d.ts +1844 -0
- package/dist/index.js +1773 -0
- package/package.json +48 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1847 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/index.ts
|
|
22
|
+
var index_exports = {};
|
|
23
|
+
__export(index_exports, {
|
|
24
|
+
NativeBridge: () => NativeBridge,
|
|
25
|
+
VActionSheet: () => VActionSheet,
|
|
26
|
+
VActivityIndicator: () => VActivityIndicator,
|
|
27
|
+
VAlertDialog: () => VAlertDialog,
|
|
28
|
+
VButton: () => VButton,
|
|
29
|
+
VImage: () => VImage,
|
|
30
|
+
VInput: () => VInput,
|
|
31
|
+
VKeyboardAvoiding: () => VKeyboardAvoiding,
|
|
32
|
+
VList: () => VList,
|
|
33
|
+
VModal: () => VModal,
|
|
34
|
+
VPicker: () => VPicker,
|
|
35
|
+
VProgressBar: () => VProgressBar,
|
|
36
|
+
VSafeArea: () => VSafeArea,
|
|
37
|
+
VScrollView: () => VScrollView,
|
|
38
|
+
VSegmentedControl: () => VSegmentedControl,
|
|
39
|
+
VSlider: () => VSlider,
|
|
40
|
+
VStatusBar: () => VStatusBar,
|
|
41
|
+
VSwitch: () => VSwitch,
|
|
42
|
+
VText: () => VText,
|
|
43
|
+
VView: () => VView,
|
|
44
|
+
VWebView: () => VWebView,
|
|
45
|
+
createApp: () => createApp,
|
|
46
|
+
createCommentNode: () => createCommentNode,
|
|
47
|
+
createNativeNode: () => createNativeNode,
|
|
48
|
+
createStyleSheet: () => createStyleSheet,
|
|
49
|
+
createTextNode: () => createTextNode,
|
|
50
|
+
render: () => render,
|
|
51
|
+
resetNodeId: () => resetNodeId,
|
|
52
|
+
useAnimation: () => useAnimation,
|
|
53
|
+
useAppState: () => useAppState,
|
|
54
|
+
useAsyncStorage: () => useAsyncStorage,
|
|
55
|
+
useBackHandler: () => useBackHandler,
|
|
56
|
+
useBiometry: () => useBiometry,
|
|
57
|
+
useCamera: () => useCamera,
|
|
58
|
+
useClipboard: () => useClipboard,
|
|
59
|
+
useColorScheme: () => useColorScheme,
|
|
60
|
+
useDeviceInfo: () => useDeviceInfo,
|
|
61
|
+
useGeolocation: () => useGeolocation,
|
|
62
|
+
useHaptics: () => useHaptics,
|
|
63
|
+
useHttp: () => useHttp,
|
|
64
|
+
useKeyboard: () => useKeyboard,
|
|
65
|
+
useLinking: () => useLinking,
|
|
66
|
+
useNetwork: () => useNetwork,
|
|
67
|
+
useNotifications: () => useNotifications,
|
|
68
|
+
usePermissions: () => usePermissions,
|
|
69
|
+
useShare: () => useShare,
|
|
70
|
+
vShow: () => vShow,
|
|
71
|
+
validStyleProperties: () => validStyleProperties
|
|
72
|
+
});
|
|
73
|
+
module.exports = __toCommonJS(index_exports);
|
|
74
|
+
var import_runtime_core32 = require("@vue/runtime-core");
|
|
75
|
+
|
|
76
|
+
// src/renderer.ts
|
|
77
|
+
var import_runtime_core = require("@vue/runtime-core");
|
|
78
|
+
|
|
79
|
+
// src/node.ts
|
|
80
|
+
var import_reactivity = require("@vue/reactivity");
|
|
81
|
+
var nextNodeId = 1;
|
|
82
|
+
var MAX_NODE_ID = 2147483647;
|
|
83
|
+
function resetNodeId() {
|
|
84
|
+
nextNodeId = 1;
|
|
85
|
+
}
|
|
86
|
+
function getNextNodeId() {
|
|
87
|
+
const id = nextNodeId;
|
|
88
|
+
if (nextNodeId >= MAX_NODE_ID) {
|
|
89
|
+
nextNodeId = 1;
|
|
90
|
+
} else {
|
|
91
|
+
nextNodeId++;
|
|
92
|
+
}
|
|
93
|
+
return id;
|
|
94
|
+
}
|
|
95
|
+
function createNativeNode(type) {
|
|
96
|
+
const node = {
|
|
97
|
+
id: getNextNodeId(),
|
|
98
|
+
type,
|
|
99
|
+
props: {},
|
|
100
|
+
children: [],
|
|
101
|
+
parent: null,
|
|
102
|
+
isText: false
|
|
103
|
+
};
|
|
104
|
+
return (0, import_reactivity.markRaw)(node);
|
|
105
|
+
}
|
|
106
|
+
function createTextNode(text) {
|
|
107
|
+
const node = {
|
|
108
|
+
id: getNextNodeId(),
|
|
109
|
+
type: "__TEXT__",
|
|
110
|
+
props: {},
|
|
111
|
+
children: [],
|
|
112
|
+
parent: null,
|
|
113
|
+
isText: true,
|
|
114
|
+
text
|
|
115
|
+
};
|
|
116
|
+
return (0, import_reactivity.markRaw)(node);
|
|
117
|
+
}
|
|
118
|
+
function createCommentNode(text) {
|
|
119
|
+
const node = {
|
|
120
|
+
id: getNextNodeId(),
|
|
121
|
+
type: "__COMMENT__",
|
|
122
|
+
props: {},
|
|
123
|
+
children: [],
|
|
124
|
+
parent: null,
|
|
125
|
+
isText: false
|
|
126
|
+
};
|
|
127
|
+
return (0, import_reactivity.markRaw)(node);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// src/bridge.ts
|
|
131
|
+
var NativeBridgeImpl = class {
|
|
132
|
+
constructor() {
|
|
133
|
+
/** Pending operations waiting to be flushed to native */
|
|
134
|
+
this.pendingOps = [];
|
|
135
|
+
/** Whether a microtask flush has been scheduled */
|
|
136
|
+
this.flushScheduled = false;
|
|
137
|
+
/** Event handler registry: "nodeId:eventName" -> callback */
|
|
138
|
+
this.eventHandlers = /* @__PURE__ */ new Map();
|
|
139
|
+
/** Pending async callbacks from native module invocations */
|
|
140
|
+
this.pendingCallbacks = /* @__PURE__ */ new Map();
|
|
141
|
+
/** Auto-incrementing callback ID for async native module calls */
|
|
142
|
+
this.nextCallbackId = 1;
|
|
143
|
+
/** Global event listeners: eventName -> Set of callbacks */
|
|
144
|
+
this.globalEventHandlers = /* @__PURE__ */ new Map();
|
|
145
|
+
}
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
// Operation batching
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
/**
|
|
150
|
+
* Enqueue an operation to be sent to the native side.
|
|
151
|
+
* If this is the first operation in the current microtask cycle,
|
|
152
|
+
* schedule a flush via queueMicrotask.
|
|
153
|
+
*/
|
|
154
|
+
enqueue(op, args) {
|
|
155
|
+
this.pendingOps.push({ op, args });
|
|
156
|
+
if (!this.flushScheduled) {
|
|
157
|
+
this.flushScheduled = true;
|
|
158
|
+
queueMicrotask(() => this.flush());
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Flush all pending operations to the native side by calling
|
|
163
|
+
* __VN_flushOperations with the JSON-serialized operation array.
|
|
164
|
+
*/
|
|
165
|
+
flush() {
|
|
166
|
+
this.flushScheduled = false;
|
|
167
|
+
if (this.pendingOps.length === 0) return;
|
|
168
|
+
const ops = this.pendingOps;
|
|
169
|
+
this.pendingOps = [];
|
|
170
|
+
const json = JSON.stringify(ops);
|
|
171
|
+
const flushFn = globalThis.__VN_flushOperations;
|
|
172
|
+
if (typeof flushFn === "function") {
|
|
173
|
+
flushFn(json);
|
|
174
|
+
} else if (__DEV__) {
|
|
175
|
+
console.warn(
|
|
176
|
+
"[VueNative] __VN_flushOperations is not registered. Make sure the Swift runtime has been initialized."
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Force an immediate synchronous flush. Used for testing and for
|
|
182
|
+
* critical operations that must be committed before the next microtask.
|
|
183
|
+
*/
|
|
184
|
+
flushSync() {
|
|
185
|
+
this.flush();
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Return the number of pending operations. Useful for testing.
|
|
189
|
+
*/
|
|
190
|
+
getPendingCount() {
|
|
191
|
+
return this.pendingOps.length;
|
|
192
|
+
}
|
|
193
|
+
// ---------------------------------------------------------------------------
|
|
194
|
+
// Node lifecycle operations
|
|
195
|
+
//
|
|
196
|
+
// Operation names match the Swift NativeBridge.processOperations() switch:
|
|
197
|
+
// "create", "createText", "setText", "setElementText"
|
|
198
|
+
// ---------------------------------------------------------------------------
|
|
199
|
+
/**
|
|
200
|
+
* Tell native to create a new view node.
|
|
201
|
+
* Swift handler: handleCreate(args: [nodeId, type])
|
|
202
|
+
*/
|
|
203
|
+
createNode(nodeId, type) {
|
|
204
|
+
this.enqueue("create", [nodeId, type]);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Tell native to create a text node.
|
|
208
|
+
* Swift handler: handleCreateText(args: [nodeId, text])
|
|
209
|
+
*/
|
|
210
|
+
createTextNode(nodeId, text) {
|
|
211
|
+
this.enqueue("createText", [nodeId, text]);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Update the text content of a text node.
|
|
215
|
+
* Swift handler: handleSetText(args: [nodeId, text])
|
|
216
|
+
*/
|
|
217
|
+
setText(nodeId, text) {
|
|
218
|
+
this.enqueue("setText", [nodeId, text]);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Set the text content of an element node (replaces all children with text).
|
|
222
|
+
* Swift handler: handleSetElementText(args: [nodeId, text])
|
|
223
|
+
*/
|
|
224
|
+
setElementText(nodeId, text) {
|
|
225
|
+
this.enqueue("setElementText", [nodeId, text]);
|
|
226
|
+
}
|
|
227
|
+
// ---------------------------------------------------------------------------
|
|
228
|
+
// Property / style updates
|
|
229
|
+
// ---------------------------------------------------------------------------
|
|
230
|
+
/**
|
|
231
|
+
* Update a single property on a native view.
|
|
232
|
+
* Swift handler: handleUpdateProp(args: [nodeId, key, value])
|
|
233
|
+
*/
|
|
234
|
+
updateProp(nodeId, key, value) {
|
|
235
|
+
this.enqueue("updateProp", [nodeId, key, value]);
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Update a single style property on a native view.
|
|
239
|
+
* Swift handler: handleUpdateStyle(args: [nodeId, { key: value }])
|
|
240
|
+
*
|
|
241
|
+
* Each style property update is sent as a dictionary with one key,
|
|
242
|
+
* matching the Swift side which iterates over the dictionary entries.
|
|
243
|
+
*/
|
|
244
|
+
updateStyle(nodeId, key, value) {
|
|
245
|
+
this.enqueue("updateStyle", [nodeId, { [key]: value }]);
|
|
246
|
+
}
|
|
247
|
+
// ---------------------------------------------------------------------------
|
|
248
|
+
// Tree mutations
|
|
249
|
+
// ---------------------------------------------------------------------------
|
|
250
|
+
/**
|
|
251
|
+
* Append a child node to a parent node.
|
|
252
|
+
* Swift handler: handleAppendChild(args: [parentId, childId])
|
|
253
|
+
*/
|
|
254
|
+
appendChild(parentId, childId) {
|
|
255
|
+
this.enqueue("appendChild", [parentId, childId]);
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Insert a child node before a reference node within a parent.
|
|
259
|
+
* Swift handler: handleInsertBefore(args: [parentId, childId, beforeId])
|
|
260
|
+
*/
|
|
261
|
+
insertBefore(parentId, childId, anchorId) {
|
|
262
|
+
this.enqueue("insertBefore", [parentId, childId, anchorId]);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Remove a child node from its parent.
|
|
266
|
+
* Swift handler: handleRemoveChild(args: [childId])
|
|
267
|
+
* Note: Swift only needs the childId since it calls removeFromSuperview().
|
|
268
|
+
*/
|
|
269
|
+
removeChild(_parentId, childId) {
|
|
270
|
+
this.enqueue("removeChild", [childId]);
|
|
271
|
+
}
|
|
272
|
+
// ---------------------------------------------------------------------------
|
|
273
|
+
// Event handling
|
|
274
|
+
// ---------------------------------------------------------------------------
|
|
275
|
+
/**
|
|
276
|
+
* Register an event listener for a node.
|
|
277
|
+
* The native side will call __VN_handleEvent when this event fires.
|
|
278
|
+
* Swift handler: handleAddEventListener(args: [nodeId, eventName])
|
|
279
|
+
*/
|
|
280
|
+
addEventListener(nodeId, eventName, callback) {
|
|
281
|
+
const key = `${nodeId}:${eventName}`;
|
|
282
|
+
this.eventHandlers.set(key, callback);
|
|
283
|
+
this.enqueue("addEventListener", [nodeId, eventName]);
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Remove a previously registered event listener.
|
|
287
|
+
* Swift handler: handleRemoveEventListener(args: [nodeId, eventName])
|
|
288
|
+
*/
|
|
289
|
+
removeEventListener(nodeId, eventName) {
|
|
290
|
+
const key = `${nodeId}:${eventName}`;
|
|
291
|
+
this.eventHandlers.delete(key);
|
|
292
|
+
this.enqueue("removeEventListener", [nodeId, eventName]);
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Called from Swift via globalThis.__VN_handleEvent when a native event fires.
|
|
296
|
+
* Looks up the registered handler and invokes it with the event payload.
|
|
297
|
+
*/
|
|
298
|
+
handleNativeEvent(nodeId, eventName, payload) {
|
|
299
|
+
const key = `${nodeId}:${eventName}`;
|
|
300
|
+
const handler = this.eventHandlers.get(key);
|
|
301
|
+
if (handler) {
|
|
302
|
+
try {
|
|
303
|
+
handler(payload);
|
|
304
|
+
} catch (err) {
|
|
305
|
+
console.error(`[VueNative] Error in event handler "${eventName}" on node ${nodeId}:`, err);
|
|
306
|
+
}
|
|
307
|
+
} else if (__DEV__) {
|
|
308
|
+
console.warn(
|
|
309
|
+
`[VueNative] No handler registered for event "${eventName}" on node ${nodeId}`
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// ---------------------------------------------------------------------------
|
|
314
|
+
// Root view
|
|
315
|
+
// ---------------------------------------------------------------------------
|
|
316
|
+
/**
|
|
317
|
+
* Tell native which node ID is the root of the view tree.
|
|
318
|
+
* Swift handler: handleSetRootView(args: [nodeId])
|
|
319
|
+
*/
|
|
320
|
+
setRootView(nodeId) {
|
|
321
|
+
this.enqueue("setRootView", [nodeId]);
|
|
322
|
+
}
|
|
323
|
+
// ---------------------------------------------------------------------------
|
|
324
|
+
// Native module invocation
|
|
325
|
+
// ---------------------------------------------------------------------------
|
|
326
|
+
/**
|
|
327
|
+
* Invoke a native module method asynchronously. Returns a Promise that
|
|
328
|
+
* resolves when Swift/Kotlin calls __VN_resolveCallback with the matching callbackId.
|
|
329
|
+
*
|
|
330
|
+
* A 30-second timeout is applied. If the native side never responds (e.g. due to
|
|
331
|
+
* a crash or unregistered module), the Promise rejects with a clear error instead
|
|
332
|
+
* of hanging forever.
|
|
333
|
+
*/
|
|
334
|
+
invokeNativeModule(moduleName, methodName, args = [], timeoutMs = 3e4) {
|
|
335
|
+
return new Promise((resolve, reject) => {
|
|
336
|
+
const callbackId = this.nextCallbackId++;
|
|
337
|
+
const timeoutId = setTimeout(() => {
|
|
338
|
+
if (this.pendingCallbacks.has(callbackId)) {
|
|
339
|
+
this.pendingCallbacks.delete(callbackId);
|
|
340
|
+
reject(new Error(
|
|
341
|
+
`[VueNative] Native module ${moduleName}.${methodName} timed out after ${timeoutMs}ms`
|
|
342
|
+
));
|
|
343
|
+
}
|
|
344
|
+
}, timeoutMs);
|
|
345
|
+
this.pendingCallbacks.set(callbackId, { resolve, reject, timeoutId });
|
|
346
|
+
this.enqueue("invokeNativeModule", [moduleName, methodName, args, callbackId]);
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Invoke a native module method synchronously.
|
|
351
|
+
* This sends the operation immediately and expects no callback.
|
|
352
|
+
* Use sparingly -- prefer the async variant.
|
|
353
|
+
*/
|
|
354
|
+
invokeNativeModuleSync(moduleName, methodName, args = []) {
|
|
355
|
+
this.enqueue("invokeNativeModuleSync", [moduleName, methodName, args]);
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Called from Swift via globalThis.__VN_resolveCallback when an async
|
|
359
|
+
* native module invocation completes.
|
|
360
|
+
*/
|
|
361
|
+
resolveCallback(callbackId, result, error) {
|
|
362
|
+
const pending = this.pendingCallbacks.get(callbackId);
|
|
363
|
+
if (!pending) {
|
|
364
|
+
if (__DEV__) {
|
|
365
|
+
console.warn(
|
|
366
|
+
`[VueNative] Received callback for unknown callbackId: ${callbackId}`
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
clearTimeout(pending.timeoutId);
|
|
372
|
+
this.pendingCallbacks.delete(callbackId);
|
|
373
|
+
if (error != null) {
|
|
374
|
+
pending.reject(typeof error === "string" ? new Error(error) : error);
|
|
375
|
+
} else {
|
|
376
|
+
pending.resolve(result);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
// ---------------------------------------------------------------------------
|
|
380
|
+
// Global push events
|
|
381
|
+
// ---------------------------------------------------------------------------
|
|
382
|
+
/**
|
|
383
|
+
* Register a handler for a push-based global event from native.
|
|
384
|
+
* Returns an unsubscribe function.
|
|
385
|
+
*/
|
|
386
|
+
onGlobalEvent(eventName, handler) {
|
|
387
|
+
if (!this.globalEventHandlers.has(eventName)) {
|
|
388
|
+
this.globalEventHandlers.set(eventName, /* @__PURE__ */ new Set());
|
|
389
|
+
}
|
|
390
|
+
this.globalEventHandlers.get(eventName).add(handler);
|
|
391
|
+
return () => {
|
|
392
|
+
this.globalEventHandlers.get(eventName)?.delete(handler);
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Called from Swift via globalThis.__VN_handleGlobalEvent when a push event fires.
|
|
397
|
+
*/
|
|
398
|
+
handleGlobalEvent(eventName, payloadJSON) {
|
|
399
|
+
let payload;
|
|
400
|
+
try {
|
|
401
|
+
payload = JSON.parse(payloadJSON);
|
|
402
|
+
} catch {
|
|
403
|
+
payload = {};
|
|
404
|
+
}
|
|
405
|
+
const handlers = this.globalEventHandlers.get(eventName);
|
|
406
|
+
if (handlers) {
|
|
407
|
+
handlers.forEach((h21) => {
|
|
408
|
+
try {
|
|
409
|
+
h21(payload);
|
|
410
|
+
} catch (err) {
|
|
411
|
+
console.error(`[VueNative] Error in global event handler "${eventName}":`, err);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
// ---------------------------------------------------------------------------
|
|
417
|
+
// Cleanup
|
|
418
|
+
// ---------------------------------------------------------------------------
|
|
419
|
+
/**
|
|
420
|
+
* Reset all internal state. Used for testing.
|
|
421
|
+
*/
|
|
422
|
+
reset() {
|
|
423
|
+
this.pendingOps = [];
|
|
424
|
+
this.flushScheduled = false;
|
|
425
|
+
this.eventHandlers.clear();
|
|
426
|
+
this.pendingCallbacks.clear();
|
|
427
|
+
this.nextCallbackId = 1;
|
|
428
|
+
this.globalEventHandlers.clear();
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
if (typeof globalThis.__DEV__ === "undefined") {
|
|
432
|
+
;
|
|
433
|
+
globalThis.__DEV__ = true;
|
|
434
|
+
}
|
|
435
|
+
var NativeBridge = new NativeBridgeImpl();
|
|
436
|
+
globalThis.__VN_handleEvent = NativeBridge.handleNativeEvent.bind(NativeBridge);
|
|
437
|
+
globalThis.__VN_resolveCallback = NativeBridge.resolveCallback.bind(NativeBridge);
|
|
438
|
+
globalThis.__VN_handleGlobalEvent = NativeBridge.handleGlobalEvent.bind(NativeBridge);
|
|
439
|
+
globalThis.__VN_teardown = () => {
|
|
440
|
+
NativeBridge.reset();
|
|
441
|
+
resetNodeId();
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
// src/renderer.ts
|
|
445
|
+
function toEventName(key) {
|
|
446
|
+
return key.slice(2).toLowerCase();
|
|
447
|
+
}
|
|
448
|
+
function patchStyle(nodeId, prevStyle, nextStyle) {
|
|
449
|
+
const prev = prevStyle || {};
|
|
450
|
+
const next = nextStyle || {};
|
|
451
|
+
for (const key in next) {
|
|
452
|
+
if (next[key] !== prev[key]) {
|
|
453
|
+
NativeBridge.updateStyle(nodeId, key, next[key]);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
for (const key in prev) {
|
|
457
|
+
if (!(key in next)) {
|
|
458
|
+
NativeBridge.updateStyle(nodeId, key, null);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
var nodeOps = {
|
|
463
|
+
/**
|
|
464
|
+
* Create a native element node.
|
|
465
|
+
*/
|
|
466
|
+
createElement(type) {
|
|
467
|
+
const node = createNativeNode(type);
|
|
468
|
+
NativeBridge.createNode(node.id, type);
|
|
469
|
+
return node;
|
|
470
|
+
},
|
|
471
|
+
/**
|
|
472
|
+
* Create a text node containing raw text content.
|
|
473
|
+
*/
|
|
474
|
+
createText(text) {
|
|
475
|
+
const node = createTextNode(text);
|
|
476
|
+
NativeBridge.createTextNode(node.id, text);
|
|
477
|
+
return node;
|
|
478
|
+
},
|
|
479
|
+
/**
|
|
480
|
+
* Create a comment node. Comments are invisible placeholders used by Vue
|
|
481
|
+
* for anchoring conditional and list rendering. We create a JS-side node
|
|
482
|
+
* but do NOT send it to native — comments have no visual representation.
|
|
483
|
+
*/
|
|
484
|
+
createComment(text) {
|
|
485
|
+
return createCommentNode(text);
|
|
486
|
+
},
|
|
487
|
+
/**
|
|
488
|
+
* Update the text content of a text node.
|
|
489
|
+
*/
|
|
490
|
+
setText(node, text) {
|
|
491
|
+
node.text = text;
|
|
492
|
+
NativeBridge.setText(node.id, text);
|
|
493
|
+
},
|
|
494
|
+
/**
|
|
495
|
+
* Set the text content of an element, replacing all its children.
|
|
496
|
+
*/
|
|
497
|
+
setElementText(node, text) {
|
|
498
|
+
for (const child of node.children) {
|
|
499
|
+
child.parent = null;
|
|
500
|
+
}
|
|
501
|
+
node.children = [];
|
|
502
|
+
NativeBridge.setElementText(node.id, text);
|
|
503
|
+
},
|
|
504
|
+
/**
|
|
505
|
+
* Patch a single prop on an element. Routes to the appropriate bridge
|
|
506
|
+
* method based on the prop key:
|
|
507
|
+
* - "on*" keys -> event listener management
|
|
508
|
+
* - "style" -> style diffing
|
|
509
|
+
* - all else -> updateProp
|
|
510
|
+
*/
|
|
511
|
+
patchProp(el, key, prevValue, nextValue) {
|
|
512
|
+
if (key.startsWith("on") && key.length > 2 && key[2] === key[2].toUpperCase()) {
|
|
513
|
+
const eventName = toEventName(key);
|
|
514
|
+
if (prevValue) {
|
|
515
|
+
NativeBridge.removeEventListener(el.id, eventName);
|
|
516
|
+
}
|
|
517
|
+
if (nextValue) {
|
|
518
|
+
NativeBridge.addEventListener(el.id, eventName, nextValue);
|
|
519
|
+
}
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
if (key === "style") {
|
|
523
|
+
patchStyle(el.id, prevValue, nextValue);
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
el.props[key] = nextValue;
|
|
527
|
+
NativeBridge.updateProp(el.id, key, nextValue);
|
|
528
|
+
},
|
|
529
|
+
/**
|
|
530
|
+
* Insert a child node into a parent, optionally before an anchor node.
|
|
531
|
+
* Manages both the JS-side tree structure and the native-side tree.
|
|
532
|
+
*/
|
|
533
|
+
insert(child, parent, anchor) {
|
|
534
|
+
if (child.parent) {
|
|
535
|
+
const oldParent = child.parent;
|
|
536
|
+
const idx = oldParent.children.indexOf(child);
|
|
537
|
+
if (idx !== -1) {
|
|
538
|
+
oldParent.children.splice(idx, 1);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
child.parent = parent;
|
|
542
|
+
if (anchor) {
|
|
543
|
+
const anchorIdx = parent.children.indexOf(anchor);
|
|
544
|
+
if (anchorIdx !== -1) {
|
|
545
|
+
parent.children.splice(anchorIdx, 0, child);
|
|
546
|
+
} else {
|
|
547
|
+
parent.children.push(child);
|
|
548
|
+
}
|
|
549
|
+
if (child.type !== "__COMMENT__") {
|
|
550
|
+
if (anchor.type !== "__COMMENT__") {
|
|
551
|
+
NativeBridge.insertBefore(parent.id, child.id, anchor.id);
|
|
552
|
+
} else {
|
|
553
|
+
const realAnchor = findNextNonComment(parent, anchor);
|
|
554
|
+
if (realAnchor) {
|
|
555
|
+
NativeBridge.insertBefore(parent.id, child.id, realAnchor.id);
|
|
556
|
+
} else {
|
|
557
|
+
NativeBridge.appendChild(parent.id, child.id);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
} else {
|
|
562
|
+
parent.children.push(child);
|
|
563
|
+
if (child.type !== "__COMMENT__") {
|
|
564
|
+
NativeBridge.appendChild(parent.id, child.id);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
},
|
|
568
|
+
/**
|
|
569
|
+
* Remove a child from the tree.
|
|
570
|
+
*/
|
|
571
|
+
remove(child) {
|
|
572
|
+
const parent = child.parent;
|
|
573
|
+
if (parent) {
|
|
574
|
+
const idx = parent.children.indexOf(child);
|
|
575
|
+
if (idx !== -1) {
|
|
576
|
+
parent.children.splice(idx, 1);
|
|
577
|
+
}
|
|
578
|
+
child.parent = null;
|
|
579
|
+
if (child.type !== "__COMMENT__") {
|
|
580
|
+
NativeBridge.removeChild(parent.id, child.id);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
},
|
|
584
|
+
/**
|
|
585
|
+
* Return the parent of a node.
|
|
586
|
+
*/
|
|
587
|
+
parentNode(node) {
|
|
588
|
+
return node.parent;
|
|
589
|
+
},
|
|
590
|
+
/**
|
|
591
|
+
* Return the next sibling of a node in the parent's children array.
|
|
592
|
+
*/
|
|
593
|
+
nextSibling(node) {
|
|
594
|
+
const parent = node.parent;
|
|
595
|
+
if (!parent) return null;
|
|
596
|
+
const idx = parent.children.indexOf(node);
|
|
597
|
+
if (idx === -1 || idx >= parent.children.length - 1) return null;
|
|
598
|
+
return parent.children[idx + 1];
|
|
599
|
+
}
|
|
600
|
+
};
|
|
601
|
+
function findNextNonComment(parent, anchor) {
|
|
602
|
+
const idx = parent.children.indexOf(anchor);
|
|
603
|
+
if (idx === -1) return null;
|
|
604
|
+
for (let i = idx + 1; i < parent.children.length; i++) {
|
|
605
|
+
if (parent.children[i].type !== "__COMMENT__") {
|
|
606
|
+
return parent.children[i];
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
return null;
|
|
610
|
+
}
|
|
611
|
+
var { render, createApp: baseCreateApp } = (0, import_runtime_core.createRenderer)(nodeOps);
|
|
612
|
+
|
|
613
|
+
// src/components/VView.ts
|
|
614
|
+
var import_runtime_core2 = require("@vue/runtime-core");
|
|
615
|
+
var VView = (0, import_runtime_core2.defineComponent)({
|
|
616
|
+
name: "VView",
|
|
617
|
+
props: {
|
|
618
|
+
style: Object,
|
|
619
|
+
testID: String,
|
|
620
|
+
accessibilityLabel: String
|
|
621
|
+
},
|
|
622
|
+
setup(props, { slots }) {
|
|
623
|
+
return () => (0, import_runtime_core2.h)("VView", { ...props }, slots.default?.());
|
|
624
|
+
}
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
// src/components/VText.ts
|
|
628
|
+
var import_runtime_core3 = require("@vue/runtime-core");
|
|
629
|
+
var VText = (0, import_runtime_core3.defineComponent)({
|
|
630
|
+
name: "VText",
|
|
631
|
+
props: {
|
|
632
|
+
style: Object,
|
|
633
|
+
numberOfLines: Number,
|
|
634
|
+
selectable: {
|
|
635
|
+
type: Boolean,
|
|
636
|
+
default: false
|
|
637
|
+
},
|
|
638
|
+
accessibilityRole: String
|
|
639
|
+
},
|
|
640
|
+
setup(props, { slots }) {
|
|
641
|
+
return () => (0, import_runtime_core3.h)("VText", { ...props }, slots.default?.());
|
|
642
|
+
}
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
// src/components/VButton.ts
|
|
646
|
+
var import_runtime_core4 = require("@vue/runtime-core");
|
|
647
|
+
var VButton = (0, import_runtime_core4.defineComponent)({
|
|
648
|
+
name: "VButton",
|
|
649
|
+
props: {
|
|
650
|
+
style: Object,
|
|
651
|
+
disabled: {
|
|
652
|
+
type: Boolean,
|
|
653
|
+
default: false
|
|
654
|
+
},
|
|
655
|
+
activeOpacity: {
|
|
656
|
+
type: Number,
|
|
657
|
+
default: 0.7
|
|
658
|
+
},
|
|
659
|
+
onPress: Function,
|
|
660
|
+
onLongPress: Function
|
|
661
|
+
},
|
|
662
|
+
setup(props, { slots }) {
|
|
663
|
+
return () => (0, import_runtime_core4.h)(
|
|
664
|
+
"VButton",
|
|
665
|
+
{
|
|
666
|
+
...props,
|
|
667
|
+
onPress: props.disabled ? void 0 : props.onPress,
|
|
668
|
+
onLongPress: props.disabled ? void 0 : props.onLongPress
|
|
669
|
+
},
|
|
670
|
+
slots.default?.()
|
|
671
|
+
);
|
|
672
|
+
}
|
|
673
|
+
});
|
|
674
|
+
|
|
675
|
+
// src/components/VInput.ts
|
|
676
|
+
var import_runtime_core5 = require("@vue/runtime-core");
|
|
677
|
+
var VInput = (0, import_runtime_core5.defineComponent)({
|
|
678
|
+
name: "VInput",
|
|
679
|
+
props: {
|
|
680
|
+
modelValue: {
|
|
681
|
+
type: String,
|
|
682
|
+
default: ""
|
|
683
|
+
},
|
|
684
|
+
placeholder: String,
|
|
685
|
+
secureTextEntry: {
|
|
686
|
+
type: Boolean,
|
|
687
|
+
default: false
|
|
688
|
+
},
|
|
689
|
+
keyboardType: {
|
|
690
|
+
type: String,
|
|
691
|
+
default: "default"
|
|
692
|
+
},
|
|
693
|
+
returnKeyType: {
|
|
694
|
+
type: String,
|
|
695
|
+
default: "done"
|
|
696
|
+
},
|
|
697
|
+
autoCapitalize: {
|
|
698
|
+
type: String,
|
|
699
|
+
default: "sentences"
|
|
700
|
+
},
|
|
701
|
+
autoCorrect: {
|
|
702
|
+
type: Boolean,
|
|
703
|
+
default: true
|
|
704
|
+
},
|
|
705
|
+
maxLength: Number,
|
|
706
|
+
multiline: {
|
|
707
|
+
type: Boolean,
|
|
708
|
+
default: false
|
|
709
|
+
},
|
|
710
|
+
style: Object
|
|
711
|
+
},
|
|
712
|
+
emits: ["update:modelValue", "focus", "blur", "submit"],
|
|
713
|
+
setup(props, { emit }) {
|
|
714
|
+
const onChangetext = (payload) => {
|
|
715
|
+
const text = typeof payload === "string" ? payload : payload?.text ?? "";
|
|
716
|
+
emit("update:modelValue", text);
|
|
717
|
+
};
|
|
718
|
+
const onFocus = (payload) => {
|
|
719
|
+
emit("focus", payload);
|
|
720
|
+
};
|
|
721
|
+
const onBlur = (payload) => {
|
|
722
|
+
emit("blur", payload);
|
|
723
|
+
};
|
|
724
|
+
const onSubmit = (payload) => {
|
|
725
|
+
emit("submit", payload);
|
|
726
|
+
};
|
|
727
|
+
return () => (0, import_runtime_core5.h)("VInput", {
|
|
728
|
+
text: props.modelValue,
|
|
729
|
+
placeholder: props.placeholder,
|
|
730
|
+
secureTextEntry: props.secureTextEntry,
|
|
731
|
+
keyboardType: props.keyboardType,
|
|
732
|
+
returnKeyType: props.returnKeyType,
|
|
733
|
+
autoCapitalize: props.autoCapitalize,
|
|
734
|
+
autoCorrect: props.autoCorrect,
|
|
735
|
+
maxLength: props.maxLength,
|
|
736
|
+
multiline: props.multiline,
|
|
737
|
+
style: props.style,
|
|
738
|
+
onChangetext,
|
|
739
|
+
onFocus,
|
|
740
|
+
onBlur,
|
|
741
|
+
onSubmit
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
// src/components/VSwitch.ts
|
|
747
|
+
var import_runtime_core6 = require("@vue/runtime-core");
|
|
748
|
+
var VSwitch = (0, import_runtime_core6.defineComponent)({
|
|
749
|
+
name: "VSwitch",
|
|
750
|
+
props: {
|
|
751
|
+
modelValue: {
|
|
752
|
+
type: Boolean,
|
|
753
|
+
default: false
|
|
754
|
+
},
|
|
755
|
+
disabled: {
|
|
756
|
+
type: Boolean,
|
|
757
|
+
default: false
|
|
758
|
+
},
|
|
759
|
+
onTintColor: String,
|
|
760
|
+
thumbTintColor: String,
|
|
761
|
+
style: Object
|
|
762
|
+
},
|
|
763
|
+
emits: ["update:modelValue", "change"],
|
|
764
|
+
setup(props, { emit }) {
|
|
765
|
+
const onChange = (payload) => {
|
|
766
|
+
const value = typeof payload === "boolean" ? payload : !!(payload?.value ?? payload);
|
|
767
|
+
emit("update:modelValue", value);
|
|
768
|
+
emit("change", value);
|
|
769
|
+
};
|
|
770
|
+
return () => (0, import_runtime_core6.h)("VSwitch", {
|
|
771
|
+
value: props.modelValue,
|
|
772
|
+
disabled: props.disabled,
|
|
773
|
+
onTintColor: props.onTintColor,
|
|
774
|
+
thumbTintColor: props.thumbTintColor,
|
|
775
|
+
style: props.style,
|
|
776
|
+
onChange
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
});
|
|
780
|
+
|
|
781
|
+
// src/components/VActivityIndicator.ts
|
|
782
|
+
var import_runtime_core7 = require("@vue/runtime-core");
|
|
783
|
+
var VActivityIndicator = (0, import_runtime_core7.defineComponent)({
|
|
784
|
+
name: "VActivityIndicator",
|
|
785
|
+
props: {
|
|
786
|
+
animating: {
|
|
787
|
+
type: Boolean,
|
|
788
|
+
default: true
|
|
789
|
+
},
|
|
790
|
+
color: String,
|
|
791
|
+
size: {
|
|
792
|
+
type: String,
|
|
793
|
+
default: "medium"
|
|
794
|
+
// 'small' | 'medium' | 'large'
|
|
795
|
+
},
|
|
796
|
+
hidesWhenStopped: {
|
|
797
|
+
type: Boolean,
|
|
798
|
+
default: true
|
|
799
|
+
},
|
|
800
|
+
style: Object
|
|
801
|
+
},
|
|
802
|
+
setup(props) {
|
|
803
|
+
return () => (0, import_runtime_core7.h)("VActivityIndicator", {
|
|
804
|
+
animating: props.animating,
|
|
805
|
+
color: props.color,
|
|
806
|
+
size: props.size,
|
|
807
|
+
hidesWhenStopped: props.hidesWhenStopped,
|
|
808
|
+
style: props.style
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
});
|
|
812
|
+
|
|
813
|
+
// src/components/VScrollView.ts
|
|
814
|
+
var import_runtime_core8 = require("@vue/runtime-core");
|
|
815
|
+
var VScrollView = (0, import_runtime_core8.defineComponent)({
|
|
816
|
+
name: "VScrollView",
|
|
817
|
+
props: {
|
|
818
|
+
horizontal: {
|
|
819
|
+
type: Boolean,
|
|
820
|
+
default: false
|
|
821
|
+
},
|
|
822
|
+
showsVerticalScrollIndicator: {
|
|
823
|
+
type: Boolean,
|
|
824
|
+
default: true
|
|
825
|
+
},
|
|
826
|
+
showsHorizontalScrollIndicator: {
|
|
827
|
+
type: Boolean,
|
|
828
|
+
default: false
|
|
829
|
+
},
|
|
830
|
+
scrollEnabled: {
|
|
831
|
+
type: Boolean,
|
|
832
|
+
default: true
|
|
833
|
+
},
|
|
834
|
+
bounces: {
|
|
835
|
+
type: Boolean,
|
|
836
|
+
default: true
|
|
837
|
+
},
|
|
838
|
+
pagingEnabled: {
|
|
839
|
+
type: Boolean,
|
|
840
|
+
default: false
|
|
841
|
+
},
|
|
842
|
+
contentContainerStyle: Object,
|
|
843
|
+
/** Whether the pull-to-refresh indicator is active */
|
|
844
|
+
refreshing: {
|
|
845
|
+
type: Boolean,
|
|
846
|
+
default: false
|
|
847
|
+
},
|
|
848
|
+
style: Object
|
|
849
|
+
},
|
|
850
|
+
emits: ["scroll", "refresh"],
|
|
851
|
+
setup(props, { slots, emit }) {
|
|
852
|
+
const onScroll = (payload) => {
|
|
853
|
+
emit("scroll", payload);
|
|
854
|
+
};
|
|
855
|
+
const onRefresh = () => {
|
|
856
|
+
emit("refresh");
|
|
857
|
+
};
|
|
858
|
+
return () => (0, import_runtime_core8.h)(
|
|
859
|
+
"VScrollView",
|
|
860
|
+
{
|
|
861
|
+
horizontal: props.horizontal,
|
|
862
|
+
showsVerticalScrollIndicator: props.showsVerticalScrollIndicator,
|
|
863
|
+
showsHorizontalScrollIndicator: props.showsHorizontalScrollIndicator,
|
|
864
|
+
scrollEnabled: props.scrollEnabled,
|
|
865
|
+
bounces: props.bounces,
|
|
866
|
+
pagingEnabled: props.pagingEnabled,
|
|
867
|
+
contentContainerStyle: props.contentContainerStyle,
|
|
868
|
+
refreshing: props.refreshing,
|
|
869
|
+
style: props.style,
|
|
870
|
+
onScroll,
|
|
871
|
+
onRefresh
|
|
872
|
+
},
|
|
873
|
+
slots.default?.()
|
|
874
|
+
);
|
|
875
|
+
}
|
|
876
|
+
});
|
|
877
|
+
|
|
878
|
+
// src/components/VImage.ts
|
|
879
|
+
var import_runtime_core9 = require("@vue/runtime-core");
|
|
880
|
+
var VImage = (0, import_runtime_core9.defineComponent)({
|
|
881
|
+
name: "VImage",
|
|
882
|
+
props: {
|
|
883
|
+
source: Object,
|
|
884
|
+
resizeMode: {
|
|
885
|
+
type: String,
|
|
886
|
+
default: "cover"
|
|
887
|
+
},
|
|
888
|
+
style: Object,
|
|
889
|
+
testID: String,
|
|
890
|
+
accessibilityLabel: String
|
|
891
|
+
},
|
|
892
|
+
emits: ["load", "error"],
|
|
893
|
+
setup(props, { emit }) {
|
|
894
|
+
return () => (0, import_runtime_core9.h)(
|
|
895
|
+
"VImage",
|
|
896
|
+
{
|
|
897
|
+
...props,
|
|
898
|
+
onLoad: () => emit("load"),
|
|
899
|
+
onError: (e) => emit("error", e)
|
|
900
|
+
}
|
|
901
|
+
);
|
|
902
|
+
}
|
|
903
|
+
});
|
|
904
|
+
|
|
905
|
+
// src/components/VKeyboardAvoiding.ts
|
|
906
|
+
var import_runtime_core10 = require("@vue/runtime-core");
|
|
907
|
+
var VKeyboardAvoiding = (0, import_runtime_core10.defineComponent)({
|
|
908
|
+
name: "VKeyboardAvoiding",
|
|
909
|
+
props: {
|
|
910
|
+
style: Object,
|
|
911
|
+
testID: String
|
|
912
|
+
},
|
|
913
|
+
setup(props, { slots }) {
|
|
914
|
+
return () => (0, import_runtime_core10.h)("VKeyboardAvoiding", { ...props }, slots.default?.());
|
|
915
|
+
}
|
|
916
|
+
});
|
|
917
|
+
|
|
918
|
+
// src/components/VSafeArea.ts
|
|
919
|
+
var import_runtime_core11 = require("@vue/runtime-core");
|
|
920
|
+
var VSafeArea = (0, import_runtime_core11.defineComponent)({
|
|
921
|
+
name: "VSafeArea",
|
|
922
|
+
props: {
|
|
923
|
+
style: { type: Object, default: () => ({}) }
|
|
924
|
+
},
|
|
925
|
+
setup(props, { slots }) {
|
|
926
|
+
return () => (0, import_runtime_core11.h)("VSafeArea", { style: props.style }, slots.default?.());
|
|
927
|
+
}
|
|
928
|
+
});
|
|
929
|
+
|
|
930
|
+
// src/components/VSlider.ts
|
|
931
|
+
var import_runtime_core12 = require("@vue/runtime-core");
|
|
932
|
+
var VSlider = (0, import_runtime_core12.defineComponent)({
|
|
933
|
+
name: "VSlider",
|
|
934
|
+
props: {
|
|
935
|
+
modelValue: { type: Number, default: 0 },
|
|
936
|
+
min: { type: Number, default: 0 },
|
|
937
|
+
max: { type: Number, default: 1 },
|
|
938
|
+
style: { type: Object, default: () => ({}) }
|
|
939
|
+
},
|
|
940
|
+
emits: ["update:modelValue", "change"],
|
|
941
|
+
setup(props, { emit }) {
|
|
942
|
+
return () => (0, import_runtime_core12.h)("VSlider", {
|
|
943
|
+
style: props.style,
|
|
944
|
+
value: props.modelValue,
|
|
945
|
+
minimumValue: props.min,
|
|
946
|
+
maximumValue: props.max,
|
|
947
|
+
onChange: (val) => {
|
|
948
|
+
emit("update:modelValue", val);
|
|
949
|
+
emit("change", val);
|
|
950
|
+
}
|
|
951
|
+
});
|
|
952
|
+
}
|
|
953
|
+
});
|
|
954
|
+
|
|
955
|
+
// src/components/VList.ts
|
|
956
|
+
var import_runtime_core13 = require("@vue/runtime-core");
|
|
957
|
+
var VList = (0, import_runtime_core13.defineComponent)({
|
|
958
|
+
name: "VList",
|
|
959
|
+
props: {
|
|
960
|
+
/** Array of data items to render */
|
|
961
|
+
data: {
|
|
962
|
+
type: Array,
|
|
963
|
+
required: true
|
|
964
|
+
},
|
|
965
|
+
/** Extract a unique key from each item. Defaults to index as string. */
|
|
966
|
+
keyExtractor: {
|
|
967
|
+
type: Function,
|
|
968
|
+
default: (_item, index) => String(index)
|
|
969
|
+
},
|
|
970
|
+
/** Estimated height per row in points. Used before layout runs. Default: 44 */
|
|
971
|
+
estimatedItemHeight: {
|
|
972
|
+
type: Number,
|
|
973
|
+
default: 44
|
|
974
|
+
},
|
|
975
|
+
/** Show vertical scroll indicator. Default: true */
|
|
976
|
+
showsScrollIndicator: {
|
|
977
|
+
type: Boolean,
|
|
978
|
+
default: true
|
|
979
|
+
},
|
|
980
|
+
/** Enable bounce at scroll boundaries. Default: true */
|
|
981
|
+
bounces: {
|
|
982
|
+
type: Boolean,
|
|
983
|
+
default: true
|
|
984
|
+
},
|
|
985
|
+
/** Render list horizontally. Default: false */
|
|
986
|
+
horizontal: {
|
|
987
|
+
type: Boolean,
|
|
988
|
+
default: false
|
|
989
|
+
},
|
|
990
|
+
style: {
|
|
991
|
+
type: Object,
|
|
992
|
+
default: () => ({})
|
|
993
|
+
}
|
|
994
|
+
},
|
|
995
|
+
emits: ["scroll", "endReached"],
|
|
996
|
+
setup(props, { slots, emit }) {
|
|
997
|
+
return () => {
|
|
998
|
+
const items = props.data ?? [];
|
|
999
|
+
const children = [];
|
|
1000
|
+
if (slots.header) {
|
|
1001
|
+
children.push(
|
|
1002
|
+
(0, import_runtime_core13.h)("VView", { key: "__header__", style: { flexShrink: 0 } }, slots.header())
|
|
1003
|
+
);
|
|
1004
|
+
}
|
|
1005
|
+
if (items.length === 0 && slots.empty) {
|
|
1006
|
+
children.push(
|
|
1007
|
+
(0, import_runtime_core13.h)("VView", { key: "__empty__", style: { flexShrink: 0 } }, slots.empty())
|
|
1008
|
+
);
|
|
1009
|
+
}
|
|
1010
|
+
for (let index = 0; index < items.length; index++) {
|
|
1011
|
+
const item = items[index];
|
|
1012
|
+
children.push(
|
|
1013
|
+
(0, import_runtime_core13.h)(
|
|
1014
|
+
"VView",
|
|
1015
|
+
{
|
|
1016
|
+
key: props.keyExtractor(item, index),
|
|
1017
|
+
style: { flexShrink: 0 }
|
|
1018
|
+
},
|
|
1019
|
+
slots.item?.({ item, index }) ?? []
|
|
1020
|
+
)
|
|
1021
|
+
);
|
|
1022
|
+
}
|
|
1023
|
+
if (slots.footer) {
|
|
1024
|
+
children.push(
|
|
1025
|
+
(0, import_runtime_core13.h)("VView", { key: "__footer__", style: { flexShrink: 0 } }, slots.footer())
|
|
1026
|
+
);
|
|
1027
|
+
}
|
|
1028
|
+
return (0, import_runtime_core13.h)(
|
|
1029
|
+
"VList",
|
|
1030
|
+
{
|
|
1031
|
+
style: props.style,
|
|
1032
|
+
estimatedItemHeight: props.estimatedItemHeight,
|
|
1033
|
+
showsScrollIndicator: props.showsScrollIndicator,
|
|
1034
|
+
bounces: props.bounces,
|
|
1035
|
+
horizontal: props.horizontal,
|
|
1036
|
+
onScroll: (e) => emit("scroll", e),
|
|
1037
|
+
onEndReached: () => emit("endReached")
|
|
1038
|
+
},
|
|
1039
|
+
children
|
|
1040
|
+
);
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
});
|
|
1044
|
+
|
|
1045
|
+
// src/components/VModal.ts
|
|
1046
|
+
var import_runtime_core14 = require("@vue/runtime-core");
|
|
1047
|
+
var VModal = (0, import_runtime_core14.defineComponent)({
|
|
1048
|
+
name: "VModal",
|
|
1049
|
+
props: {
|
|
1050
|
+
visible: {
|
|
1051
|
+
type: Boolean,
|
|
1052
|
+
default: false
|
|
1053
|
+
},
|
|
1054
|
+
style: {
|
|
1055
|
+
type: Object,
|
|
1056
|
+
default: () => ({})
|
|
1057
|
+
}
|
|
1058
|
+
},
|
|
1059
|
+
emits: ["dismiss"],
|
|
1060
|
+
setup(props, { slots, emit }) {
|
|
1061
|
+
return () => (0, import_runtime_core14.h)(
|
|
1062
|
+
"VModal",
|
|
1063
|
+
{
|
|
1064
|
+
visible: props.visible,
|
|
1065
|
+
style: props.style,
|
|
1066
|
+
onDismiss: () => emit("dismiss")
|
|
1067
|
+
},
|
|
1068
|
+
slots.default?.() ?? []
|
|
1069
|
+
);
|
|
1070
|
+
}
|
|
1071
|
+
});
|
|
1072
|
+
|
|
1073
|
+
// src/components/VAlertDialog.ts
|
|
1074
|
+
var import_runtime_core15 = require("@vue/runtime-core");
|
|
1075
|
+
var VAlertDialog = (0, import_runtime_core15.defineComponent)({
|
|
1076
|
+
name: "VAlertDialog",
|
|
1077
|
+
props: {
|
|
1078
|
+
visible: { type: Boolean, default: false },
|
|
1079
|
+
title: { type: String, default: "" },
|
|
1080
|
+
message: { type: String, default: "" },
|
|
1081
|
+
buttons: { type: Array, default: () => [] }
|
|
1082
|
+
},
|
|
1083
|
+
emits: ["confirm", "cancel", "action"],
|
|
1084
|
+
setup(props, { emit }) {
|
|
1085
|
+
return () => (0, import_runtime_core15.h)("VAlertDialog", {
|
|
1086
|
+
visible: props.visible,
|
|
1087
|
+
title: props.title,
|
|
1088
|
+
message: props.message,
|
|
1089
|
+
buttons: props.buttons,
|
|
1090
|
+
onConfirm: (e) => emit("confirm", e),
|
|
1091
|
+
onCancel: () => emit("cancel"),
|
|
1092
|
+
onAction: (e) => emit("action", e)
|
|
1093
|
+
});
|
|
1094
|
+
}
|
|
1095
|
+
});
|
|
1096
|
+
|
|
1097
|
+
// src/components/VStatusBar.ts
|
|
1098
|
+
var import_runtime_core16 = require("@vue/runtime-core");
|
|
1099
|
+
var VStatusBar = (0, import_runtime_core16.defineComponent)({
|
|
1100
|
+
name: "VStatusBar",
|
|
1101
|
+
props: {
|
|
1102
|
+
barStyle: { type: String, default: "default" },
|
|
1103
|
+
hidden: { type: Boolean, default: false },
|
|
1104
|
+
animated: { type: Boolean, default: true }
|
|
1105
|
+
},
|
|
1106
|
+
setup(props) {
|
|
1107
|
+
return () => (0, import_runtime_core16.h)("VStatusBar", {
|
|
1108
|
+
barStyle: props.barStyle,
|
|
1109
|
+
hidden: props.hidden,
|
|
1110
|
+
animated: props.animated
|
|
1111
|
+
});
|
|
1112
|
+
}
|
|
1113
|
+
});
|
|
1114
|
+
|
|
1115
|
+
// src/components/VWebView.ts
|
|
1116
|
+
var import_runtime_core17 = require("@vue/runtime-core");
|
|
1117
|
+
var VWebView = (0, import_runtime_core17.defineComponent)({
|
|
1118
|
+
name: "VWebView",
|
|
1119
|
+
props: {
|
|
1120
|
+
source: { type: Object, required: true },
|
|
1121
|
+
style: { type: Object, default: () => ({}) },
|
|
1122
|
+
javaScriptEnabled: { type: Boolean, default: true }
|
|
1123
|
+
},
|
|
1124
|
+
emits: ["load", "error", "message"],
|
|
1125
|
+
setup(props, { emit }) {
|
|
1126
|
+
return () => (0, import_runtime_core17.h)("VWebView", {
|
|
1127
|
+
source: props.source,
|
|
1128
|
+
style: props.style,
|
|
1129
|
+
javaScriptEnabled: props.javaScriptEnabled,
|
|
1130
|
+
onLoad: (e) => emit("load", e),
|
|
1131
|
+
onError: (e) => emit("error", e),
|
|
1132
|
+
onMessage: (e) => emit("message", e)
|
|
1133
|
+
});
|
|
1134
|
+
}
|
|
1135
|
+
});
|
|
1136
|
+
|
|
1137
|
+
// src/components/VProgressBar.ts
|
|
1138
|
+
var import_runtime_core18 = require("@vue/runtime-core");
|
|
1139
|
+
var VProgressBar = (0, import_runtime_core18.defineComponent)({
|
|
1140
|
+
name: "VProgressBar",
|
|
1141
|
+
props: {
|
|
1142
|
+
progress: { type: Number, default: 0 },
|
|
1143
|
+
progressTintColor: { type: String, default: void 0 },
|
|
1144
|
+
trackTintColor: { type: String, default: void 0 },
|
|
1145
|
+
animated: { type: Boolean, default: true },
|
|
1146
|
+
style: { type: Object, default: () => ({}) }
|
|
1147
|
+
},
|
|
1148
|
+
setup(props) {
|
|
1149
|
+
return () => (0, import_runtime_core18.h)("VProgressBar", {
|
|
1150
|
+
progress: props.progress,
|
|
1151
|
+
progressTintColor: props.progressTintColor,
|
|
1152
|
+
trackTintColor: props.trackTintColor,
|
|
1153
|
+
animated: props.animated,
|
|
1154
|
+
style: props.style
|
|
1155
|
+
});
|
|
1156
|
+
}
|
|
1157
|
+
});
|
|
1158
|
+
|
|
1159
|
+
// src/components/VPicker.ts
|
|
1160
|
+
var import_runtime_core19 = require("@vue/runtime-core");
|
|
1161
|
+
var VPicker = (0, import_runtime_core19.defineComponent)({
|
|
1162
|
+
name: "VPicker",
|
|
1163
|
+
props: {
|
|
1164
|
+
mode: { type: String, default: "date" },
|
|
1165
|
+
value: { type: Number, default: void 0 },
|
|
1166
|
+
// epoch milliseconds
|
|
1167
|
+
minimumDate: { type: Number, default: void 0 },
|
|
1168
|
+
maximumDate: { type: Number, default: void 0 },
|
|
1169
|
+
minuteInterval: { type: Number, default: 1 },
|
|
1170
|
+
style: { type: Object, default: () => ({}) }
|
|
1171
|
+
},
|
|
1172
|
+
emits: ["change"],
|
|
1173
|
+
setup(props, { emit }) {
|
|
1174
|
+
return () => (0, import_runtime_core19.h)("VPicker", {
|
|
1175
|
+
mode: props.mode,
|
|
1176
|
+
value: props.value,
|
|
1177
|
+
minimumDate: props.minimumDate,
|
|
1178
|
+
maximumDate: props.maximumDate,
|
|
1179
|
+
minuteInterval: props.minuteInterval,
|
|
1180
|
+
style: props.style,
|
|
1181
|
+
onChange: (e) => emit("change", e)
|
|
1182
|
+
});
|
|
1183
|
+
}
|
|
1184
|
+
});
|
|
1185
|
+
|
|
1186
|
+
// src/components/VSegmentedControl.ts
|
|
1187
|
+
var import_runtime_core20 = require("@vue/runtime-core");
|
|
1188
|
+
var VSegmentedControl = (0, import_runtime_core20.defineComponent)({
|
|
1189
|
+
name: "VSegmentedControl",
|
|
1190
|
+
props: {
|
|
1191
|
+
values: { type: Array, required: true },
|
|
1192
|
+
selectedIndex: { type: Number, default: 0 },
|
|
1193
|
+
tintColor: { type: String, default: void 0 },
|
|
1194
|
+
enabled: { type: Boolean, default: true },
|
|
1195
|
+
style: { type: Object, default: () => ({}) }
|
|
1196
|
+
},
|
|
1197
|
+
emits: ["change"],
|
|
1198
|
+
setup(props, { emit }) {
|
|
1199
|
+
return () => (0, import_runtime_core20.h)("VSegmentedControl", {
|
|
1200
|
+
values: props.values,
|
|
1201
|
+
selectedIndex: props.selectedIndex,
|
|
1202
|
+
tintColor: props.tintColor,
|
|
1203
|
+
enabled: props.enabled,
|
|
1204
|
+
style: props.style,
|
|
1205
|
+
onChange: (e) => emit("change", e)
|
|
1206
|
+
});
|
|
1207
|
+
}
|
|
1208
|
+
});
|
|
1209
|
+
|
|
1210
|
+
// src/components/VActionSheet.ts
|
|
1211
|
+
var import_runtime_core21 = require("@vue/runtime-core");
|
|
1212
|
+
var VActionSheet = (0, import_runtime_core21.defineComponent)({
|
|
1213
|
+
name: "VActionSheet",
|
|
1214
|
+
props: {
|
|
1215
|
+
visible: { type: Boolean, default: false },
|
|
1216
|
+
title: { type: String, default: void 0 },
|
|
1217
|
+
message: { type: String, default: void 0 },
|
|
1218
|
+
actions: { type: Array, default: () => [] }
|
|
1219
|
+
},
|
|
1220
|
+
emits: ["action", "cancel"],
|
|
1221
|
+
setup(props, { emit }) {
|
|
1222
|
+
return () => (0, import_runtime_core21.h)("VActionSheet", {
|
|
1223
|
+
visible: props.visible,
|
|
1224
|
+
title: props.title,
|
|
1225
|
+
message: props.message,
|
|
1226
|
+
actions: props.actions,
|
|
1227
|
+
onAction: (e) => emit("action", e),
|
|
1228
|
+
onCancel: () => emit("cancel")
|
|
1229
|
+
});
|
|
1230
|
+
}
|
|
1231
|
+
});
|
|
1232
|
+
|
|
1233
|
+
// src/directives/vShow.ts
|
|
1234
|
+
var vShow = {
|
|
1235
|
+
beforeMount(el, { value }) {
|
|
1236
|
+
NativeBridge.updateProp(el.id, "hidden", !value);
|
|
1237
|
+
},
|
|
1238
|
+
updated(el, { value, oldValue }) {
|
|
1239
|
+
if (value === oldValue) return;
|
|
1240
|
+
NativeBridge.updateProp(el.id, "hidden", !value);
|
|
1241
|
+
}
|
|
1242
|
+
};
|
|
1243
|
+
|
|
1244
|
+
// src/index.ts
|
|
1245
|
+
__reExport(index_exports, require("@vue/runtime-core"), module.exports);
|
|
1246
|
+
|
|
1247
|
+
// src/stylesheet.ts
|
|
1248
|
+
var validStyleProperties = /* @__PURE__ */ new Set([
|
|
1249
|
+
// Layout (Yoga / Flexbox)
|
|
1250
|
+
"flex",
|
|
1251
|
+
"flexDirection",
|
|
1252
|
+
"flexWrap",
|
|
1253
|
+
"flexGrow",
|
|
1254
|
+
"flexShrink",
|
|
1255
|
+
"flexBasis",
|
|
1256
|
+
"justifyContent",
|
|
1257
|
+
"alignItems",
|
|
1258
|
+
"alignSelf",
|
|
1259
|
+
"alignContent",
|
|
1260
|
+
"position",
|
|
1261
|
+
"top",
|
|
1262
|
+
"right",
|
|
1263
|
+
"bottom",
|
|
1264
|
+
"left",
|
|
1265
|
+
"width",
|
|
1266
|
+
"height",
|
|
1267
|
+
"minWidth",
|
|
1268
|
+
"minHeight",
|
|
1269
|
+
"maxWidth",
|
|
1270
|
+
"maxHeight",
|
|
1271
|
+
"margin",
|
|
1272
|
+
"marginTop",
|
|
1273
|
+
"marginRight",
|
|
1274
|
+
"marginBottom",
|
|
1275
|
+
"marginLeft",
|
|
1276
|
+
"marginHorizontal",
|
|
1277
|
+
"marginVertical",
|
|
1278
|
+
"padding",
|
|
1279
|
+
"paddingTop",
|
|
1280
|
+
"paddingRight",
|
|
1281
|
+
"paddingBottom",
|
|
1282
|
+
"paddingLeft",
|
|
1283
|
+
"paddingHorizontal",
|
|
1284
|
+
"paddingVertical",
|
|
1285
|
+
"gap",
|
|
1286
|
+
"rowGap",
|
|
1287
|
+
"columnGap",
|
|
1288
|
+
"display",
|
|
1289
|
+
"overflow",
|
|
1290
|
+
"zIndex",
|
|
1291
|
+
"aspectRatio",
|
|
1292
|
+
// Visual
|
|
1293
|
+
"backgroundColor",
|
|
1294
|
+
"opacity",
|
|
1295
|
+
// Borders
|
|
1296
|
+
"borderWidth",
|
|
1297
|
+
"borderTopWidth",
|
|
1298
|
+
"borderRightWidth",
|
|
1299
|
+
"borderBottomWidth",
|
|
1300
|
+
"borderLeftWidth",
|
|
1301
|
+
"borderColor",
|
|
1302
|
+
"borderTopColor",
|
|
1303
|
+
"borderRightColor",
|
|
1304
|
+
"borderBottomColor",
|
|
1305
|
+
"borderLeftColor",
|
|
1306
|
+
"borderRadius",
|
|
1307
|
+
"borderTopLeftRadius",
|
|
1308
|
+
"borderTopRightRadius",
|
|
1309
|
+
"borderBottomLeftRadius",
|
|
1310
|
+
"borderBottomRightRadius",
|
|
1311
|
+
"borderStyle",
|
|
1312
|
+
// Shadow
|
|
1313
|
+
"shadowColor",
|
|
1314
|
+
"shadowOffset",
|
|
1315
|
+
"shadowOpacity",
|
|
1316
|
+
"shadowRadius",
|
|
1317
|
+
// Text
|
|
1318
|
+
"color",
|
|
1319
|
+
"fontSize",
|
|
1320
|
+
"fontWeight",
|
|
1321
|
+
"fontFamily",
|
|
1322
|
+
"fontStyle",
|
|
1323
|
+
"lineHeight",
|
|
1324
|
+
"letterSpacing",
|
|
1325
|
+
"textAlign",
|
|
1326
|
+
"textDecorationLine",
|
|
1327
|
+
"textDecorationStyle",
|
|
1328
|
+
"textDecorationColor",
|
|
1329
|
+
"textTransform",
|
|
1330
|
+
"includeFontPadding",
|
|
1331
|
+
// Image
|
|
1332
|
+
"resizeMode",
|
|
1333
|
+
"tintColor",
|
|
1334
|
+
// Transform
|
|
1335
|
+
"transform"
|
|
1336
|
+
]);
|
|
1337
|
+
function createStyleSheet(styles) {
|
|
1338
|
+
const isDev = typeof __DEV__ !== "undefined" ? __DEV__ : true;
|
|
1339
|
+
if (isDev) {
|
|
1340
|
+
for (const styleName in styles) {
|
|
1341
|
+
const styleObj = styles[styleName];
|
|
1342
|
+
for (const prop in styleObj) {
|
|
1343
|
+
if (!validStyleProperties.has(prop)) {
|
|
1344
|
+
console.warn(
|
|
1345
|
+
`[VueNative] Unknown style property "${prop}" in style "${styleName}". This property will be ignored by the native renderer.`
|
|
1346
|
+
);
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
const result = {};
|
|
1352
|
+
for (const key in styles) {
|
|
1353
|
+
result[key] = Object.freeze({ ...styles[key] });
|
|
1354
|
+
}
|
|
1355
|
+
return Object.freeze(result);
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
// src/composables/useHaptics.ts
|
|
1359
|
+
function useHaptics() {
|
|
1360
|
+
function vibrate(style = "medium") {
|
|
1361
|
+
return NativeBridge.invokeNativeModule("Haptics", "vibrate", [style]).then(() => void 0);
|
|
1362
|
+
}
|
|
1363
|
+
function notificationFeedback(type = "success") {
|
|
1364
|
+
return NativeBridge.invokeNativeModule("Haptics", "notificationFeedback", [type]).then(() => void 0);
|
|
1365
|
+
}
|
|
1366
|
+
function selectionChanged() {
|
|
1367
|
+
return NativeBridge.invokeNativeModule("Haptics", "selectionChanged", []).then(() => void 0);
|
|
1368
|
+
}
|
|
1369
|
+
return { vibrate, notificationFeedback, selectionChanged };
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
// src/composables/useAsyncStorage.ts
|
|
1373
|
+
function useAsyncStorage() {
|
|
1374
|
+
function getItem(key) {
|
|
1375
|
+
return NativeBridge.invokeNativeModule("AsyncStorage", "getItem", [key]);
|
|
1376
|
+
}
|
|
1377
|
+
function setItem(key, value) {
|
|
1378
|
+
return NativeBridge.invokeNativeModule("AsyncStorage", "setItem", [key, value]).then(() => void 0);
|
|
1379
|
+
}
|
|
1380
|
+
function removeItem(key) {
|
|
1381
|
+
return NativeBridge.invokeNativeModule("AsyncStorage", "removeItem", [key]).then(() => void 0);
|
|
1382
|
+
}
|
|
1383
|
+
function getAllKeys() {
|
|
1384
|
+
return NativeBridge.invokeNativeModule("AsyncStorage", "getAllKeys", []);
|
|
1385
|
+
}
|
|
1386
|
+
function clear() {
|
|
1387
|
+
return NativeBridge.invokeNativeModule("AsyncStorage", "clear", []).then(() => void 0);
|
|
1388
|
+
}
|
|
1389
|
+
return { getItem, setItem, removeItem, getAllKeys, clear };
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
// src/composables/useClipboard.ts
|
|
1393
|
+
var import_runtime_core22 = require("@vue/runtime-core");
|
|
1394
|
+
function useClipboard() {
|
|
1395
|
+
const content = (0, import_runtime_core22.ref)("");
|
|
1396
|
+
function copy(text) {
|
|
1397
|
+
return NativeBridge.invokeNativeModule("Clipboard", "copy", [text]).then(() => void 0);
|
|
1398
|
+
}
|
|
1399
|
+
async function paste() {
|
|
1400
|
+
const text = await NativeBridge.invokeNativeModule("Clipboard", "paste", []);
|
|
1401
|
+
const result = typeof text === "string" ? text : "";
|
|
1402
|
+
content.value = result;
|
|
1403
|
+
return result;
|
|
1404
|
+
}
|
|
1405
|
+
return { copy, paste, content };
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
// src/composables/useDeviceInfo.ts
|
|
1409
|
+
var import_runtime_core23 = require("@vue/runtime-core");
|
|
1410
|
+
function useDeviceInfo() {
|
|
1411
|
+
const model = (0, import_runtime_core23.ref)("");
|
|
1412
|
+
const systemVersion = (0, import_runtime_core23.ref)("");
|
|
1413
|
+
const systemName = (0, import_runtime_core23.ref)("");
|
|
1414
|
+
const name = (0, import_runtime_core23.ref)("");
|
|
1415
|
+
const screenWidth = (0, import_runtime_core23.ref)(0);
|
|
1416
|
+
const screenHeight = (0, import_runtime_core23.ref)(0);
|
|
1417
|
+
const scale = (0, import_runtime_core23.ref)(1);
|
|
1418
|
+
const isLoaded = (0, import_runtime_core23.ref)(false);
|
|
1419
|
+
async function fetchInfo() {
|
|
1420
|
+
const info = await NativeBridge.invokeNativeModule("DeviceInfo", "getInfo", []);
|
|
1421
|
+
model.value = info.model ?? "";
|
|
1422
|
+
systemVersion.value = info.systemVersion ?? "";
|
|
1423
|
+
systemName.value = info.systemName ?? "";
|
|
1424
|
+
name.value = info.name ?? "";
|
|
1425
|
+
screenWidth.value = info.screenWidth ?? 0;
|
|
1426
|
+
screenHeight.value = info.screenHeight ?? 0;
|
|
1427
|
+
scale.value = info.scale ?? 1;
|
|
1428
|
+
isLoaded.value = true;
|
|
1429
|
+
}
|
|
1430
|
+
(0, import_runtime_core23.onMounted)(() => {
|
|
1431
|
+
fetchInfo();
|
|
1432
|
+
});
|
|
1433
|
+
return {
|
|
1434
|
+
model,
|
|
1435
|
+
systemVersion,
|
|
1436
|
+
systemName,
|
|
1437
|
+
name,
|
|
1438
|
+
screenWidth,
|
|
1439
|
+
screenHeight,
|
|
1440
|
+
scale,
|
|
1441
|
+
isLoaded,
|
|
1442
|
+
fetchInfo
|
|
1443
|
+
};
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
// src/composables/useKeyboard.ts
|
|
1447
|
+
var import_runtime_core24 = require("@vue/runtime-core");
|
|
1448
|
+
function useKeyboard() {
|
|
1449
|
+
const isVisible = (0, import_runtime_core24.ref)(false);
|
|
1450
|
+
const height = (0, import_runtime_core24.ref)(0);
|
|
1451
|
+
function dismiss() {
|
|
1452
|
+
return NativeBridge.invokeNativeModule("Keyboard", "dismiss", []).then(() => void 0);
|
|
1453
|
+
}
|
|
1454
|
+
async function getHeight() {
|
|
1455
|
+
const result = await NativeBridge.invokeNativeModule("Keyboard", "getHeight", []);
|
|
1456
|
+
isVisible.value = result.isVisible ?? false;
|
|
1457
|
+
height.value = result.height ?? 0;
|
|
1458
|
+
return result;
|
|
1459
|
+
}
|
|
1460
|
+
return { isVisible, height, dismiss, getHeight };
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
// src/composables/useAnimation.ts
|
|
1464
|
+
var Easing = {
|
|
1465
|
+
linear: "linear",
|
|
1466
|
+
ease: "ease",
|
|
1467
|
+
easeIn: "easeIn",
|
|
1468
|
+
easeOut: "easeOut",
|
|
1469
|
+
easeInOut: "easeInOut"
|
|
1470
|
+
};
|
|
1471
|
+
function useAnimation() {
|
|
1472
|
+
function timing(viewId, toStyles, config = {}) {
|
|
1473
|
+
return NativeBridge.invokeNativeModule("Animation", "timing", [viewId, toStyles, config]);
|
|
1474
|
+
}
|
|
1475
|
+
function spring(viewId, toStyles, config = {}) {
|
|
1476
|
+
return NativeBridge.invokeNativeModule("Animation", "spring", [viewId, toStyles, config]);
|
|
1477
|
+
}
|
|
1478
|
+
function keyframe(viewId, steps, config = {}) {
|
|
1479
|
+
return NativeBridge.invokeNativeModule("Animation", "keyframe", [viewId, steps, config]);
|
|
1480
|
+
}
|
|
1481
|
+
function sequence(animations) {
|
|
1482
|
+
return NativeBridge.invokeNativeModule("Animation", "sequence", [animations]);
|
|
1483
|
+
}
|
|
1484
|
+
function parallel(animations) {
|
|
1485
|
+
return NativeBridge.invokeNativeModule("Animation", "parallel", [animations]);
|
|
1486
|
+
}
|
|
1487
|
+
function fadeOut(viewId, duration = 300) {
|
|
1488
|
+
return timing(viewId, { opacity: 0 }, { duration });
|
|
1489
|
+
}
|
|
1490
|
+
function fadeIn(viewId, duration = 300) {
|
|
1491
|
+
return timing(viewId, { opacity: 1 }, { duration });
|
|
1492
|
+
}
|
|
1493
|
+
function slideInFromRight(viewId, duration = 300) {
|
|
1494
|
+
return timing(viewId, { translateX: 0 }, { duration, easing: "easeOut" });
|
|
1495
|
+
}
|
|
1496
|
+
function slideOutToRight(viewId, duration = 300) {
|
|
1497
|
+
return timing(viewId, { translateX: 400 }, { duration, easing: "easeIn" });
|
|
1498
|
+
}
|
|
1499
|
+
return {
|
|
1500
|
+
timing,
|
|
1501
|
+
spring,
|
|
1502
|
+
keyframe,
|
|
1503
|
+
sequence,
|
|
1504
|
+
parallel,
|
|
1505
|
+
fadeIn,
|
|
1506
|
+
fadeOut,
|
|
1507
|
+
slideInFromRight,
|
|
1508
|
+
slideOutToRight,
|
|
1509
|
+
Easing
|
|
1510
|
+
};
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
// src/composables/useNetwork.ts
|
|
1514
|
+
var import_runtime_core25 = require("@vue/runtime-core");
|
|
1515
|
+
function useNetwork() {
|
|
1516
|
+
const isConnected = (0, import_runtime_core25.ref)(true);
|
|
1517
|
+
const connectionType = (0, import_runtime_core25.ref)("unknown");
|
|
1518
|
+
NativeBridge.invokeNativeModule("Network", "getStatus").then((status) => {
|
|
1519
|
+
isConnected.value = status.isConnected;
|
|
1520
|
+
connectionType.value = status.connectionType;
|
|
1521
|
+
}).catch(() => {
|
|
1522
|
+
});
|
|
1523
|
+
const unsubscribe = NativeBridge.onGlobalEvent("network:change", (payload) => {
|
|
1524
|
+
isConnected.value = payload.isConnected;
|
|
1525
|
+
connectionType.value = payload.connectionType;
|
|
1526
|
+
});
|
|
1527
|
+
(0, import_runtime_core25.onUnmounted)(unsubscribe);
|
|
1528
|
+
return { isConnected, connectionType };
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
// src/composables/useAppState.ts
|
|
1532
|
+
var import_runtime_core26 = require("@vue/runtime-core");
|
|
1533
|
+
function useAppState() {
|
|
1534
|
+
const state = (0, import_runtime_core26.ref)("active");
|
|
1535
|
+
NativeBridge.invokeNativeModule("AppState", "getState").then((s) => {
|
|
1536
|
+
state.value = s;
|
|
1537
|
+
}).catch(() => {
|
|
1538
|
+
});
|
|
1539
|
+
const unsubscribe = NativeBridge.onGlobalEvent("appState:change", (payload) => {
|
|
1540
|
+
state.value = payload.state;
|
|
1541
|
+
});
|
|
1542
|
+
(0, import_runtime_core26.onUnmounted)(unsubscribe);
|
|
1543
|
+
return { state };
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
// src/composables/useLinking.ts
|
|
1547
|
+
function useLinking() {
|
|
1548
|
+
async function openURL(url) {
|
|
1549
|
+
await NativeBridge.invokeNativeModule("Linking", "openURL", [url]);
|
|
1550
|
+
}
|
|
1551
|
+
async function canOpenURL(url) {
|
|
1552
|
+
return NativeBridge.invokeNativeModule("Linking", "canOpenURL", [url]);
|
|
1553
|
+
}
|
|
1554
|
+
return { openURL, canOpenURL };
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
// src/composables/useShare.ts
|
|
1558
|
+
function useShare() {
|
|
1559
|
+
async function share(content) {
|
|
1560
|
+
return NativeBridge.invokeNativeModule("Share", "share", [content]);
|
|
1561
|
+
}
|
|
1562
|
+
return { share };
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
// src/composables/usePermissions.ts
|
|
1566
|
+
function usePermissions() {
|
|
1567
|
+
async function request(permission) {
|
|
1568
|
+
return NativeBridge.invokeNativeModule("Permissions", "request", [permission]);
|
|
1569
|
+
}
|
|
1570
|
+
async function check(permission) {
|
|
1571
|
+
return NativeBridge.invokeNativeModule("Permissions", "check", [permission]);
|
|
1572
|
+
}
|
|
1573
|
+
return { request, check };
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
// src/composables/useGeolocation.ts
|
|
1577
|
+
var import_runtime_core27 = require("@vue/runtime-core");
|
|
1578
|
+
function useGeolocation() {
|
|
1579
|
+
const coords = (0, import_runtime_core27.ref)(null);
|
|
1580
|
+
const error = (0, import_runtime_core27.ref)(null);
|
|
1581
|
+
let watchId = null;
|
|
1582
|
+
async function getCurrentPosition() {
|
|
1583
|
+
const result = await NativeBridge.invokeNativeModule("Geolocation", "getCurrentPosition");
|
|
1584
|
+
coords.value = result;
|
|
1585
|
+
return result;
|
|
1586
|
+
}
|
|
1587
|
+
async function watchPosition() {
|
|
1588
|
+
const id = await NativeBridge.invokeNativeModule("Geolocation", "watchPosition");
|
|
1589
|
+
watchId = id;
|
|
1590
|
+
const unsubscribe = NativeBridge.onGlobalEvent("location:update", (payload) => {
|
|
1591
|
+
coords.value = payload;
|
|
1592
|
+
});
|
|
1593
|
+
(0, import_runtime_core27.onUnmounted)(() => {
|
|
1594
|
+
unsubscribe();
|
|
1595
|
+
if (watchId !== null) clearWatch(watchId);
|
|
1596
|
+
});
|
|
1597
|
+
return id;
|
|
1598
|
+
}
|
|
1599
|
+
async function clearWatch(id) {
|
|
1600
|
+
await NativeBridge.invokeNativeModule("Geolocation", "clearWatch", [id]);
|
|
1601
|
+
watchId = null;
|
|
1602
|
+
}
|
|
1603
|
+
return { coords, error, getCurrentPosition, watchPosition, clearWatch };
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
// src/composables/useCamera.ts
|
|
1607
|
+
function useCamera() {
|
|
1608
|
+
async function launchCamera(options = {}) {
|
|
1609
|
+
return NativeBridge.invokeNativeModule("Camera", "launchCamera", [options]);
|
|
1610
|
+
}
|
|
1611
|
+
async function launchImageLibrary(options = {}) {
|
|
1612
|
+
return NativeBridge.invokeNativeModule("Camera", "launchImageLibrary", [options]);
|
|
1613
|
+
}
|
|
1614
|
+
return { launchCamera, launchImageLibrary };
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
// src/composables/useNotifications.ts
|
|
1618
|
+
var import_runtime_core28 = require("@vue/runtime-core");
|
|
1619
|
+
function useNotifications() {
|
|
1620
|
+
const isGranted = (0, import_runtime_core28.ref)(false);
|
|
1621
|
+
async function requestPermission() {
|
|
1622
|
+
const granted = await NativeBridge.invokeNativeModule("Notifications", "requestPermission");
|
|
1623
|
+
isGranted.value = granted;
|
|
1624
|
+
return granted;
|
|
1625
|
+
}
|
|
1626
|
+
async function getPermissionStatus() {
|
|
1627
|
+
return NativeBridge.invokeNativeModule("Notifications", "getPermissionStatus");
|
|
1628
|
+
}
|
|
1629
|
+
async function scheduleLocal(notification) {
|
|
1630
|
+
return NativeBridge.invokeNativeModule("Notifications", "scheduleLocal", [notification]);
|
|
1631
|
+
}
|
|
1632
|
+
async function cancel(id) {
|
|
1633
|
+
return NativeBridge.invokeNativeModule("Notifications", "cancel", [id]);
|
|
1634
|
+
}
|
|
1635
|
+
async function cancelAll() {
|
|
1636
|
+
return NativeBridge.invokeNativeModule("Notifications", "cancelAll");
|
|
1637
|
+
}
|
|
1638
|
+
function onNotification(handler) {
|
|
1639
|
+
const unsubscribe = NativeBridge.onGlobalEvent("notification:received", handler);
|
|
1640
|
+
(0, import_runtime_core28.onUnmounted)(unsubscribe);
|
|
1641
|
+
return unsubscribe;
|
|
1642
|
+
}
|
|
1643
|
+
return { isGranted, requestPermission, getPermissionStatus, scheduleLocal, cancel, cancelAll, onNotification };
|
|
1644
|
+
}
|
|
1645
|
+
|
|
1646
|
+
// src/composables/useBiometry.ts
|
|
1647
|
+
function useBiometry() {
|
|
1648
|
+
async function authenticate(reason = "Authenticate") {
|
|
1649
|
+
return NativeBridge.invokeNativeModule("Biometry", "authenticate", [reason]);
|
|
1650
|
+
}
|
|
1651
|
+
async function getSupportedBiometry() {
|
|
1652
|
+
return NativeBridge.invokeNativeModule("Biometry", "getSupportedBiometry");
|
|
1653
|
+
}
|
|
1654
|
+
async function isAvailable() {
|
|
1655
|
+
return NativeBridge.invokeNativeModule("Biometry", "isAvailable");
|
|
1656
|
+
}
|
|
1657
|
+
return { authenticate, getSupportedBiometry, isAvailable };
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
// src/composables/useHttp.ts
|
|
1661
|
+
var import_runtime_core29 = require("@vue/runtime-core");
|
|
1662
|
+
function useHttp(config = {}) {
|
|
1663
|
+
const loading = (0, import_runtime_core29.ref)(false);
|
|
1664
|
+
const error = (0, import_runtime_core29.ref)(null);
|
|
1665
|
+
async function request(method, url, options = {}) {
|
|
1666
|
+
const fullUrl = config.baseURL ? `${config.baseURL}${url}` : url;
|
|
1667
|
+
loading.value = true;
|
|
1668
|
+
error.value = null;
|
|
1669
|
+
try {
|
|
1670
|
+
const mergedHeaders = {
|
|
1671
|
+
"Content-Type": "application/json",
|
|
1672
|
+
...config.headers ?? {},
|
|
1673
|
+
...options.headers ?? {}
|
|
1674
|
+
};
|
|
1675
|
+
const fetchOptions = {
|
|
1676
|
+
method: method.toUpperCase(),
|
|
1677
|
+
headers: mergedHeaders
|
|
1678
|
+
};
|
|
1679
|
+
if (options.body !== void 0) {
|
|
1680
|
+
fetchOptions.body = JSON.stringify(options.body);
|
|
1681
|
+
}
|
|
1682
|
+
const response = await fetch(fullUrl, fetchOptions);
|
|
1683
|
+
const data = await response.json();
|
|
1684
|
+
return {
|
|
1685
|
+
data,
|
|
1686
|
+
status: response.status,
|
|
1687
|
+
ok: response.ok,
|
|
1688
|
+
headers: {}
|
|
1689
|
+
};
|
|
1690
|
+
} catch (e) {
|
|
1691
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
1692
|
+
error.value = msg;
|
|
1693
|
+
throw e;
|
|
1694
|
+
} finally {
|
|
1695
|
+
loading.value = false;
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
return {
|
|
1699
|
+
loading,
|
|
1700
|
+
error,
|
|
1701
|
+
get: (url, headers) => request("GET", url, { headers }),
|
|
1702
|
+
post: (url, body, headers) => request("POST", url, { body, headers }),
|
|
1703
|
+
put: (url, body, headers) => request("PUT", url, { body, headers }),
|
|
1704
|
+
patch: (url, body, headers) => request("PATCH", url, { body, headers }),
|
|
1705
|
+
delete: (url, headers) => request("DELETE", url, { headers })
|
|
1706
|
+
};
|
|
1707
|
+
}
|
|
1708
|
+
|
|
1709
|
+
// src/composables/useColorScheme.ts
|
|
1710
|
+
var import_runtime_core30 = require("@vue/runtime-core");
|
|
1711
|
+
function useColorScheme() {
|
|
1712
|
+
const colorScheme = (0, import_runtime_core30.ref)("light");
|
|
1713
|
+
const isDark = (0, import_runtime_core30.ref)(false);
|
|
1714
|
+
const unsubscribe = NativeBridge.onGlobalEvent(
|
|
1715
|
+
"colorScheme:change",
|
|
1716
|
+
(payload) => {
|
|
1717
|
+
colorScheme.value = payload.colorScheme;
|
|
1718
|
+
isDark.value = payload.colorScheme === "dark";
|
|
1719
|
+
}
|
|
1720
|
+
);
|
|
1721
|
+
(0, import_runtime_core30.onUnmounted)(unsubscribe);
|
|
1722
|
+
return { colorScheme, isDark };
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
// src/composables/useBackHandler.ts
|
|
1726
|
+
var import_runtime_core31 = require("@vue/runtime-core");
|
|
1727
|
+
function useBackHandler(handler) {
|
|
1728
|
+
let unsubscribe = null;
|
|
1729
|
+
(0, import_runtime_core31.onMounted)(() => {
|
|
1730
|
+
unsubscribe = NativeBridge.onGlobalEvent("hardware:backPress", () => {
|
|
1731
|
+
handler();
|
|
1732
|
+
});
|
|
1733
|
+
});
|
|
1734
|
+
(0, import_runtime_core31.onUnmounted)(() => {
|
|
1735
|
+
unsubscribe?.();
|
|
1736
|
+
unsubscribe = null;
|
|
1737
|
+
});
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
// src/index.ts
|
|
1741
|
+
function createApp(rootComponent, rootProps) {
|
|
1742
|
+
const app = baseCreateApp(rootComponent, rootProps);
|
|
1743
|
+
app.component("VView", VView);
|
|
1744
|
+
app.component("VText", VText);
|
|
1745
|
+
app.component("VButton", VButton);
|
|
1746
|
+
app.component("VInput", VInput);
|
|
1747
|
+
app.component("VSwitch", VSwitch);
|
|
1748
|
+
app.component("VActivityIndicator", VActivityIndicator);
|
|
1749
|
+
app.component("VScrollView", VScrollView);
|
|
1750
|
+
app.component("VImage", VImage);
|
|
1751
|
+
app.component("VKeyboardAvoiding", VKeyboardAvoiding);
|
|
1752
|
+
app.component("VSafeArea", VSafeArea);
|
|
1753
|
+
app.component("VSlider", VSlider);
|
|
1754
|
+
app.component("VList", VList);
|
|
1755
|
+
app.component("VModal", VModal);
|
|
1756
|
+
app.component("VAlertDialog", VAlertDialog);
|
|
1757
|
+
app.component("VStatusBar", VStatusBar);
|
|
1758
|
+
app.component("VWebView", VWebView);
|
|
1759
|
+
app.component("VProgressBar", VProgressBar);
|
|
1760
|
+
app.component("VPicker", VPicker);
|
|
1761
|
+
app.component("VSegmentedControl", VSegmentedControl);
|
|
1762
|
+
app.component("VActionSheet", VActionSheet);
|
|
1763
|
+
app.directive("show", vShow);
|
|
1764
|
+
app.config.errorHandler = (err, instance, info) => {
|
|
1765
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
1766
|
+
const componentName = instance?.$options?.name || instance?.$.type?.name || "Anonymous";
|
|
1767
|
+
const errorInfo = JSON.stringify({
|
|
1768
|
+
message: error.message,
|
|
1769
|
+
stack: error.stack || "",
|
|
1770
|
+
componentName,
|
|
1771
|
+
info
|
|
1772
|
+
});
|
|
1773
|
+
console.error(`[VueNative] Error in ${componentName}: ${error.message}`);
|
|
1774
|
+
const handleError = globalThis.__VN_handleError;
|
|
1775
|
+
if (typeof handleError === "function") {
|
|
1776
|
+
handleError(errorInfo);
|
|
1777
|
+
}
|
|
1778
|
+
};
|
|
1779
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
1780
|
+
app.config.warnHandler = (msg, instance, trace) => {
|
|
1781
|
+
const componentName = instance?.$options?.name || instance?.$.type?.name || "Anonymous";
|
|
1782
|
+
console.warn(`[VueNative] Warning in ${componentName}: ${msg}`);
|
|
1783
|
+
};
|
|
1784
|
+
}
|
|
1785
|
+
app.start = () => {
|
|
1786
|
+
const root = createNativeNode("__ROOT__");
|
|
1787
|
+
NativeBridge.createNode(root.id, "__ROOT__");
|
|
1788
|
+
NativeBridge.setRootView(root.id);
|
|
1789
|
+
const vnode = (0, import_runtime_core32.createVNode)(rootComponent, rootProps);
|
|
1790
|
+
vnode.appContext = app._context;
|
|
1791
|
+
render(vnode, root);
|
|
1792
|
+
return root;
|
|
1793
|
+
};
|
|
1794
|
+
return app;
|
|
1795
|
+
}
|
|
1796
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1797
|
+
0 && (module.exports = {
|
|
1798
|
+
NativeBridge,
|
|
1799
|
+
VActionSheet,
|
|
1800
|
+
VActivityIndicator,
|
|
1801
|
+
VAlertDialog,
|
|
1802
|
+
VButton,
|
|
1803
|
+
VImage,
|
|
1804
|
+
VInput,
|
|
1805
|
+
VKeyboardAvoiding,
|
|
1806
|
+
VList,
|
|
1807
|
+
VModal,
|
|
1808
|
+
VPicker,
|
|
1809
|
+
VProgressBar,
|
|
1810
|
+
VSafeArea,
|
|
1811
|
+
VScrollView,
|
|
1812
|
+
VSegmentedControl,
|
|
1813
|
+
VSlider,
|
|
1814
|
+
VStatusBar,
|
|
1815
|
+
VSwitch,
|
|
1816
|
+
VText,
|
|
1817
|
+
VView,
|
|
1818
|
+
VWebView,
|
|
1819
|
+
createApp,
|
|
1820
|
+
createCommentNode,
|
|
1821
|
+
createNativeNode,
|
|
1822
|
+
createStyleSheet,
|
|
1823
|
+
createTextNode,
|
|
1824
|
+
render,
|
|
1825
|
+
resetNodeId,
|
|
1826
|
+
useAnimation,
|
|
1827
|
+
useAppState,
|
|
1828
|
+
useAsyncStorage,
|
|
1829
|
+
useBackHandler,
|
|
1830
|
+
useBiometry,
|
|
1831
|
+
useCamera,
|
|
1832
|
+
useClipboard,
|
|
1833
|
+
useColorScheme,
|
|
1834
|
+
useDeviceInfo,
|
|
1835
|
+
useGeolocation,
|
|
1836
|
+
useHaptics,
|
|
1837
|
+
useHttp,
|
|
1838
|
+
useKeyboard,
|
|
1839
|
+
useLinking,
|
|
1840
|
+
useNetwork,
|
|
1841
|
+
useNotifications,
|
|
1842
|
+
usePermissions,
|
|
1843
|
+
useShare,
|
|
1844
|
+
vShow,
|
|
1845
|
+
validStyleProperties,
|
|
1846
|
+
...require("@vue/runtime-core")
|
|
1847
|
+
});
|