@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 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
+ });