@thelacanians/vue-native-runtime 0.4.14 → 0.6.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 CHANGED
@@ -28,7 +28,11 @@ __export(index_exports, {
28
28
  VAlertDialog: () => VAlertDialog,
29
29
  VButton: () => VButton,
30
30
  VCheckbox: () => VCheckbox,
31
+ VDrawer: () => VDrawer,
32
+ VDrawerItem: () => VDrawerItem,
33
+ VDrawerSection: () => VDrawerSection,
31
34
  VDropdown: () => VDropdown,
35
+ VFlatList: () => VFlatList,
32
36
  VImage: () => VImage,
33
37
  VInput: () => VInput,
34
38
  VKeyboardAvoiding: () => VKeyboardAvoiding,
@@ -46,16 +50,20 @@ __export(index_exports, {
46
50
  VSlider: () => VSlider,
47
51
  VStatusBar: () => VStatusBar,
48
52
  VSwitch: () => VSwitch,
53
+ VTabBar: () => VTabBar,
49
54
  VText: () => VText,
50
55
  VVideo: () => VVideo,
51
56
  VView: () => VView,
52
57
  VWebView: () => VWebView,
58
+ builtInComponents: () => builtInComponents,
53
59
  clearSharedElementRegistry: () => clearSharedElementRegistry,
54
60
  createApp: () => createApp,
55
61
  createCommentNode: () => createCommentNode,
62
+ createDynamicStyleSheet: () => createDynamicStyleSheet,
56
63
  createNativeNode: () => createNativeNode,
57
64
  createStyleSheet: () => createStyleSheet,
58
65
  createTextNode: () => createTextNode,
66
+ createTheme: () => createTheme,
59
67
  getRegisteredSharedElements: () => getRegisteredSharedElements,
60
68
  getSharedElementViewId: () => getSharedElementViewId,
61
69
  measureViewFrame: () => measureViewFrame,
@@ -75,12 +83,16 @@ __export(index_exports, {
75
83
  useCamera: () => useCamera,
76
84
  useClipboard: () => useClipboard,
77
85
  useColorScheme: () => useColorScheme,
86
+ useComposedGestures: () => useComposedGestures,
78
87
  useContacts: () => useContacts,
79
88
  useDatabase: () => useDatabase,
80
89
  useDeviceInfo: () => useDeviceInfo,
81
90
  useDimensions: () => useDimensions,
91
+ useDragDrop: () => useDragDrop,
92
+ useFileDialog: () => useFileDialog,
82
93
  useFileSystem: () => useFileSystem,
83
94
  useGeolocation: () => useGeolocation,
95
+ useGesture: () => useGesture,
84
96
  useGoogleSignIn: () => useGoogleSignIn,
85
97
  useGyroscope: () => useGyroscope,
86
98
  useHaptics: () => useHaptics,
@@ -89,6 +101,7 @@ __export(index_exports, {
89
101
  useIAP: () => useIAP,
90
102
  useKeyboard: () => useKeyboard,
91
103
  useLinking: () => useLinking,
104
+ useMenu: () => useMenu,
92
105
  useNetwork: () => useNetwork,
93
106
  useNotifications: () => useNotifications,
94
107
  useOTAUpdate: () => useOTAUpdate,
@@ -98,12 +111,15 @@ __export(index_exports, {
98
111
  useSecureStorage: () => useSecureStorage,
99
112
  useShare: () => useShare,
100
113
  useSharedElementTransition: () => useSharedElementTransition,
114
+ useTeleport: () => useTeleport,
101
115
  useWebSocket: () => useWebSocket,
116
+ useWindow: () => useWindow,
117
+ vModel: () => vModel,
102
118
  vShow: () => vShow,
103
119
  validStyleProperties: () => validStyleProperties
104
120
  });
105
121
  module.exports = __toCommonJS(index_exports);
106
- var import_runtime_core57 = require("@vue/runtime-core");
122
+ var import_runtime_core66 = require("@vue/runtime-core");
107
123
 
108
124
  // src/renderer.ts
109
125
  var import_runtime_core = require("@vue/runtime-core");
@@ -112,16 +128,25 @@ var import_runtime_core = require("@vue/runtime-core");
112
128
  var import_reactivity = require("@vue/reactivity");
113
129
  var nextNodeId = 1;
114
130
  var MAX_NODE_ID = 2147483647;
131
+ var activeNodeIds = /* @__PURE__ */ new Set();
115
132
  function resetNodeId() {
116
133
  nextNodeId = 1;
134
+ activeNodeIds.clear();
135
+ }
136
+ function releaseNodeId(id) {
137
+ activeNodeIds.delete(id);
117
138
  }
118
139
  function getNextNodeId() {
119
140
  const id = nextNodeId;
120
141
  if (nextNodeId >= MAX_NODE_ID) {
121
142
  nextNodeId = 1;
143
+ while (activeNodeIds.has(nextNodeId) && nextNodeId < MAX_NODE_ID) {
144
+ nextNodeId++;
145
+ }
122
146
  } else {
123
147
  nextNodeId++;
124
148
  }
149
+ activeNodeIds.add(id);
125
150
  return id;
126
151
  }
127
152
  function createNativeNode(type) {
@@ -160,6 +185,7 @@ function createCommentNode(_text) {
160
185
  }
161
186
 
162
187
  // src/bridge.ts
188
+ var bridgeGlobals = globalThis;
163
189
  var _NativeBridgeImpl = class _NativeBridgeImpl {
164
190
  constructor() {
165
191
  /** Pending operations waiting to be flushed to native */
@@ -201,7 +227,7 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
201
227
  const ops = this.pendingOps;
202
228
  this.pendingOps = [];
203
229
  const json = JSON.stringify(ops);
204
- const flushFn = globalThis.__VN_flushOperations;
230
+ const flushFn = bridgeGlobals.__VN_flushOperations;
205
231
  if (typeof flushFn === "function") {
206
232
  try {
207
233
  flushFn(json);
@@ -281,6 +307,16 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
281
307
  updateStyle(nodeId, key, value) {
282
308
  this.enqueue("updateStyle", [nodeId, { [key]: value }]);
283
309
  }
310
+ /**
311
+ * Update multiple style properties on a native view in a single bridge op.
312
+ * Swift/Kotlin handler: handleUpdateStyle(args: [nodeId, { key1: val1, key2: val2, ... }])
313
+ *
314
+ * More efficient than calling updateStyle() per property — sends one op
315
+ * instead of N ops, reducing JSON overhead and bridge dispatch.
316
+ */
317
+ updateStyles(nodeId, styles) {
318
+ this.enqueue("updateStyle", [nodeId, styles]);
319
+ }
284
320
  // ---------------------------------------------------------------------------
285
321
  // Tree mutations
286
322
  // ---------------------------------------------------------------------------
@@ -368,6 +404,8 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
368
404
  * a crash or unregistered module), the Promise rejects with a clear error instead
369
405
  * of hanging forever.
370
406
  */
407
+ // Native module results are intentionally dynamic; callers often narrow them
408
+ // ad hoc based on the module contract rather than a shared generated type.
371
409
  invokeNativeModule(moduleName, methodName, args = [], timeoutMs = 3e4) {
372
410
  return new Promise((resolve, reject) => {
373
411
  const callbackId = this.nextCallbackId;
@@ -395,7 +433,11 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
395
433
  }
396
434
  }
397
435
  }
398
- this.pendingCallbacks.set(callbackId, { resolve, reject, timeoutId });
436
+ this.pendingCallbacks.set(callbackId, {
437
+ resolve: (result) => resolve(result),
438
+ reject: (error) => reject(error),
439
+ timeoutId
440
+ });
399
441
  this.enqueue("invokeNativeModule", [moduleName, methodName, args, callbackId]);
400
442
  });
401
443
  }
@@ -427,6 +469,28 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
427
469
  pending.resolve(result);
428
470
  }
429
471
  }
472
+ /**
473
+ * Create teleport markers in native.
474
+ * Used for Teleport component to render content outside parent hierarchy.
475
+ */
476
+ createTeleport(parentId, startId, endId) {
477
+ this.enqueue("createTeleport", [parentId, startId, endId]);
478
+ }
479
+ /**
480
+ * Remove teleport markers from native.
481
+ * Cleans up teleport containers and markers.
482
+ */
483
+ removeTeleport(parentId, startId, endId) {
484
+ this.enqueue("removeTeleport", [parentId, startId, endId]);
485
+ }
486
+ /**
487
+ * Move a node to a teleport target.
488
+ * @param target - Teleport target name ('modal', 'root', etc.)
489
+ * @param nodeId - Node ID to teleport
490
+ */
491
+ teleportTo(target, nodeId) {
492
+ this.enqueue("teleportTo", [target, nodeId]);
493
+ }
430
494
  // ---------------------------------------------------------------------------
431
495
  // Global push events
432
496
  // ---------------------------------------------------------------------------
@@ -447,7 +511,7 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
447
511
  * Called from Swift via globalThis.__VN_handleGlobalEvent when a push event fires.
448
512
  */
449
513
  handleGlobalEvent(eventName, payloadJSON) {
450
- let payload;
514
+ let payload = {};
451
515
  try {
452
516
  payload = JSON.parse(payloadJSON);
453
517
  } catch {
@@ -455,9 +519,9 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
455
519
  }
456
520
  const handlers = this.globalEventHandlers.get(eventName);
457
521
  if (handlers) {
458
- handlers.forEach((h28) => {
522
+ handlers.forEach((h33) => {
459
523
  try {
460
- h28(payload);
524
+ h33(payload);
461
525
  } catch (err) {
462
526
  console.error(`[VueNative] Error in global event handler "${eventName}":`, err);
463
527
  }
@@ -474,6 +538,9 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
474
538
  this.pendingOps = [];
475
539
  this.flushScheduled = false;
476
540
  this.eventHandlers.clear();
541
+ for (const pending of this.pendingCallbacks.values()) {
542
+ clearTimeout(pending.timeoutId);
543
+ }
477
544
  this.pendingCallbacks.clear();
478
545
  this.nextCallbackId = 1;
479
546
  this.globalEventHandlers.clear();
@@ -484,15 +551,14 @@ _NativeBridgeImpl.MAX_CALLBACK_ID = 2147483647;
484
551
  /** Maximum number of pending callbacks before evicting the oldest */
485
552
  _NativeBridgeImpl.MAX_PENDING_CALLBACKS = 1e3;
486
553
  var NativeBridgeImpl = _NativeBridgeImpl;
487
- if (typeof globalThis.__DEV__ === "undefined") {
488
- ;
489
- globalThis.__DEV__ = true;
554
+ if (typeof bridgeGlobals.__DEV__ === "undefined") {
555
+ bridgeGlobals.__DEV__ = true;
490
556
  }
491
557
  var NativeBridge = new NativeBridgeImpl();
492
- globalThis.__VN_handleEvent = NativeBridge.handleNativeEvent.bind(NativeBridge);
493
- globalThis.__VN_resolveCallback = NativeBridge.resolveCallback.bind(NativeBridge);
494
- globalThis.__VN_handleGlobalEvent = NativeBridge.handleGlobalEvent.bind(NativeBridge);
495
- globalThis.__VN_teardown = () => {
558
+ bridgeGlobals.__VN_handleEvent = NativeBridge.handleNativeEvent.bind(NativeBridge);
559
+ bridgeGlobals.__VN_resolveCallback = NativeBridge.resolveCallback.bind(NativeBridge);
560
+ bridgeGlobals.__VN_handleGlobalEvent = NativeBridge.handleGlobalEvent.bind(NativeBridge);
561
+ bridgeGlobals.__VN_teardown = () => {
496
562
  NativeBridge.reset();
497
563
  resetNodeId();
498
564
  };
@@ -501,20 +567,30 @@ globalThis.__VN_teardown = () => {
501
567
  function toEventName(key) {
502
568
  return key.slice(2).toLowerCase();
503
569
  }
570
+ function isEventHandler(value) {
571
+ return typeof value === "function";
572
+ }
504
573
  function patchStyle(nodeId, prevStyle, nextStyle) {
505
574
  try {
506
- const prev = prevStyle || {};
507
- const next = nextStyle || {};
575
+ const prev = typeof prevStyle === "object" && prevStyle !== null ? prevStyle : {};
576
+ const next = typeof nextStyle === "object" && nextStyle !== null ? nextStyle : {};
577
+ const changes = {};
578
+ let hasChanges = false;
508
579
  for (const key in next) {
509
580
  if (next[key] !== prev[key]) {
510
- NativeBridge.updateStyle(nodeId, key, next[key]);
581
+ changes[key] = next[key];
582
+ hasChanges = true;
511
583
  }
512
584
  }
513
585
  for (const key in prev) {
514
586
  if (!(key in next)) {
515
- NativeBridge.updateStyle(nodeId, key, null);
587
+ changes[key] = null;
588
+ hasChanges = true;
516
589
  }
517
590
  }
591
+ if (hasChanges) {
592
+ NativeBridge.updateStyles(nodeId, changes);
593
+ }
518
594
  } catch (err) {
519
595
  console.error(`[VueNative] Error patching style on node ${nodeId}:`, err);
520
596
  }
@@ -575,7 +651,7 @@ var nodeOps = {
575
651
  if (prevValue) {
576
652
  NativeBridge.removeEventListener(el.id, eventName);
577
653
  }
578
- if (nextValue) {
654
+ if (isEventHandler(nextValue)) {
579
655
  NativeBridge.addEventListener(el.id, eventName, nextValue);
580
656
  }
581
657
  return;
@@ -651,6 +727,7 @@ var nodeOps = {
651
727
  } catch (err) {
652
728
  console.error(`[VueNative] Error removing node ${child.id}:`, err);
653
729
  }
730
+ releaseNodeId(child.id);
654
731
  }
655
732
  },
656
733
  /**
@@ -668,6 +745,25 @@ var nodeOps = {
668
745
  const idx = parent.children.indexOf(node);
669
746
  if (idx === -1 || idx >= parent.children.length - 1) return null;
670
747
  return parent.children[idx + 1];
748
+ },
749
+ /**
750
+ * Insert static content (for Teleport).
751
+ * Creates teleport boundary markers.
752
+ */
753
+ insertStaticContent(content, parent, anchor, _namespace, _start, _end) {
754
+ const startNode = createNativeNode("__TELEPORT_START__");
755
+ const endNode = createNativeNode("__TELEPORT_END__");
756
+ if (anchor) {
757
+ const idx = parent.children.indexOf(anchor);
758
+ if (idx !== -1) {
759
+ parent.children.splice(idx, 0, startNode);
760
+ parent.children.splice(idx + 1, 0, endNode);
761
+ }
762
+ } else {
763
+ parent.children.push(startNode, endNode);
764
+ }
765
+ NativeBridge.createTeleport(parent.id, startNode.id, endNode.id);
766
+ return [startNode, endNode];
671
767
  }
672
768
  };
673
769
  function findNextNonComment(parent, anchor) {
@@ -756,6 +852,16 @@ var VButton = (0, import_runtime_core4.defineComponent)({
756
852
 
757
853
  // src/components/VInput.ts
758
854
  var import_runtime_core5 = require("@vue/runtime-core");
855
+ function extractText(payload) {
856
+ if (typeof payload === "string") {
857
+ return payload;
858
+ }
859
+ if (typeof payload === "object" && payload !== null && "text" in payload) {
860
+ const text = payload.text;
861
+ return typeof text === "string" ? text : "";
862
+ }
863
+ return "";
864
+ }
759
865
  var VInput = (0, import_runtime_core5.defineComponent)({
760
866
  name: "VInput",
761
867
  props: {
@@ -803,13 +909,11 @@ var VInput = (0, import_runtime_core5.defineComponent)({
803
909
  };
804
910
  const onCompositionend = (payload) => {
805
911
  isComposing.value = false;
806
- const text = typeof payload === "string" ? payload : payload?.text ?? "";
807
- emit("update:modelValue", text);
912
+ emit("update:modelValue", extractText(payload));
808
913
  };
809
914
  const onChangetext = (payload) => {
810
915
  if (isComposing.value) return;
811
- const text = typeof payload === "string" ? payload : payload?.text ?? "";
812
- emit("update:modelValue", text);
916
+ emit("update:modelValue", extractText(payload));
813
917
  };
814
918
  const onFocus = (payload) => {
815
919
  emit("focus", payload);
@@ -869,7 +973,8 @@ var VSwitch = (0, import_runtime_core6.defineComponent)({
869
973
  emits: ["update:modelValue", "change"],
870
974
  setup(props, { emit }) {
871
975
  const onChange = (payload) => {
872
- const value = typeof payload === "boolean" ? payload : !!(payload?.value ?? payload);
976
+ const nextValue = typeof payload === "object" && payload !== null && "value" in payload ? payload.value : payload;
977
+ const value = typeof nextValue === "boolean" ? nextValue : Boolean(nextValue);
873
978
  emit("update:modelValue", value);
874
979
  emit("change", value);
875
980
  };
@@ -1033,9 +1138,9 @@ var VImage = (0, import_runtime_core9.defineComponent)({
1033
1138
  loading.value = false;
1034
1139
  emit("load");
1035
1140
  };
1036
- const onError = (e) => {
1141
+ const onError = (event) => {
1037
1142
  loading.value = false;
1038
- emit("error", e);
1143
+ emit("error", event);
1039
1144
  };
1040
1145
  expose({ loading });
1041
1146
  return () => (0, import_runtime_core9.h)(
@@ -1109,6 +1214,20 @@ var VSlider = (0, import_runtime_core12.defineComponent)({
1109
1214
 
1110
1215
  // src/components/VList.ts
1111
1216
  var import_runtime_core13 = require("@vue/runtime-core");
1217
+
1218
+ // src/composables/usePlatform.ts
1219
+ function usePlatform() {
1220
+ const platform = typeof __PLATFORM__ !== "undefined" ? __PLATFORM__ : "ios";
1221
+ const isIOS = platform === "ios";
1222
+ const isAndroid = platform === "android";
1223
+ const isMacOS = platform === "macos";
1224
+ const isApple = isIOS || isMacOS;
1225
+ const isDesktop = isMacOS;
1226
+ const isMobile = isIOS || isAndroid;
1227
+ return { platform, isIOS, isAndroid, isMacOS, isApple, isDesktop, isMobile };
1228
+ }
1229
+
1230
+ // src/components/VList.ts
1112
1231
  var VList = (0, import_runtime_core13.defineComponent)({
1113
1232
  name: "VList",
1114
1233
  props: {
@@ -1149,13 +1268,27 @@ var VList = (0, import_runtime_core13.defineComponent)({
1149
1268
  },
1150
1269
  emits: ["scroll", "endReached"],
1151
1270
  setup(props, { slots, emit }) {
1271
+ const { isAndroid } = usePlatform();
1152
1272
  let lastScrollEmit = 0;
1273
+ let endReachedFired = false;
1153
1274
  const onScroll = (e) => {
1154
1275
  const now = Date.now();
1155
1276
  if (now - lastScrollEmit >= 16) {
1156
1277
  lastScrollEmit = now;
1157
1278
  emit("scroll", e);
1158
1279
  }
1280
+ if (props.horizontal && !isAndroid) {
1281
+ const contentWidth = e.contentWidth ?? 0;
1282
+ const layoutWidth = e.layoutWidth ?? 0;
1283
+ const distanceFromEnd = contentWidth - layoutWidth - (e.x ?? 0);
1284
+ const threshold = layoutWidth * 0.2;
1285
+ if (contentWidth > layoutWidth && distanceFromEnd < threshold && !endReachedFired) {
1286
+ endReachedFired = true;
1287
+ emit("endReached");
1288
+ } else if (distanceFromEnd >= threshold) {
1289
+ endReachedFired = false;
1290
+ }
1291
+ }
1159
1292
  };
1160
1293
  return () => {
1161
1294
  const items = props.data ?? [];
@@ -1201,6 +1334,31 @@ var VList = (0, import_runtime_core13.defineComponent)({
1201
1334
  (0, import_runtime_core13.h)("VView", { key: "__footer__", style: { flexShrink: 0 } }, slots.footer())
1202
1335
  );
1203
1336
  }
1337
+ if (props.horizontal && !isAndroid) {
1338
+ return (0, import_runtime_core13.h)(
1339
+ "VScrollView",
1340
+ {
1341
+ style: props.style,
1342
+ horizontal: true,
1343
+ showsVerticalScrollIndicator: false,
1344
+ showsHorizontalScrollIndicator: props.showsScrollIndicator,
1345
+ bounces: props.bounces,
1346
+ onScroll
1347
+ },
1348
+ [
1349
+ (0, import_runtime_core13.h)(
1350
+ "VView",
1351
+ {
1352
+ style: {
1353
+ flexDirection: "row",
1354
+ alignItems: "stretch"
1355
+ }
1356
+ },
1357
+ children
1358
+ )
1359
+ ]
1360
+ );
1361
+ }
1204
1362
  return (0, import_runtime_core13.h)(
1205
1363
  "VList",
1206
1364
  {
@@ -1304,9 +1462,9 @@ var VAlertDialog = (0, import_runtime_core15.defineComponent)({
1304
1462
  title: props.title,
1305
1463
  message: props.message,
1306
1464
  buttons: resolvedButtons,
1307
- onConfirm: (e) => emit("confirm", e),
1465
+ onConfirm: (event) => emit("confirm", event),
1308
1466
  onCancel: () => emit("cancel"),
1309
- onAction: (e) => emit("action", e)
1467
+ onAction: (event) => emit("action", event)
1310
1468
  });
1311
1469
  };
1312
1470
  }
@@ -1355,9 +1513,9 @@ var VWebView = (0, import_runtime_core17.defineComponent)({
1355
1513
  source: sanitizedSource.value,
1356
1514
  style: props.style,
1357
1515
  javaScriptEnabled: props.javaScriptEnabled,
1358
- onLoad: (e) => emit("load", e),
1359
- onError: (e) => emit("error", e),
1360
- onMessage: (e) => emit("message", e)
1516
+ onLoad: (event) => emit("load", event),
1517
+ onError: (event) => emit("error", event),
1518
+ onMessage: (event) => emit("message", event)
1361
1519
  });
1362
1520
  }
1363
1521
  });
@@ -1666,7 +1824,8 @@ var VCheckbox = (0, import_runtime_core25.defineComponent)({
1666
1824
  emits: ["update:modelValue", "change"],
1667
1825
  setup(props, { emit }) {
1668
1826
  const onChange = (payload) => {
1669
- const value = typeof payload === "boolean" ? payload : !!(payload?.value ?? payload);
1827
+ const nextValue = typeof payload === "object" && payload !== null && "value" in payload ? payload.value : payload;
1828
+ const value = typeof nextValue === "boolean" ? nextValue : Boolean(nextValue);
1670
1829
  emit("update:modelValue", value);
1671
1830
  emit("change", value);
1672
1831
  };
@@ -1686,6 +1845,10 @@ var VCheckbox = (0, import_runtime_core25.defineComponent)({
1686
1845
 
1687
1846
  // src/components/VRadio.ts
1688
1847
  var import_runtime_core26 = require("@vue/runtime-core");
1848
+ function extractRadioValue(payload) {
1849
+ const nextValue = typeof payload === "object" && payload !== null && "value" in payload ? payload.value : payload;
1850
+ return typeof nextValue === "string" ? nextValue : void 0;
1851
+ }
1689
1852
  var VRadio = (0, import_runtime_core26.defineComponent)({
1690
1853
  name: "VRadio",
1691
1854
  props: {
@@ -1708,7 +1871,7 @@ var VRadio = (0, import_runtime_core26.defineComponent)({
1708
1871
  emits: ["update:modelValue", "change"],
1709
1872
  setup(props, { emit }) {
1710
1873
  const onChange = (payload) => {
1711
- const value = payload?.value ?? payload;
1874
+ const value = extractRadioValue(payload);
1712
1875
  emit("update:modelValue", value);
1713
1876
  emit("change", value);
1714
1877
  };
@@ -1726,6 +1889,10 @@ var VRadio = (0, import_runtime_core26.defineComponent)({
1726
1889
 
1727
1890
  // src/components/VDropdown.ts
1728
1891
  var import_runtime_core27 = require("@vue/runtime-core");
1892
+ function extractDropdownValue(payload) {
1893
+ const nextValue = typeof payload === "object" && payload !== null && "value" in payload ? payload.value : payload;
1894
+ return typeof nextValue === "string" ? nextValue : void 0;
1895
+ }
1729
1896
  var VDropdown = (0, import_runtime_core27.defineComponent)({
1730
1897
  name: "VDropdown",
1731
1898
  props: {
@@ -1752,7 +1919,7 @@ var VDropdown = (0, import_runtime_core27.defineComponent)({
1752
1919
  emits: ["update:modelValue", "change"],
1753
1920
  setup(props, { emit }) {
1754
1921
  const onChange = (payload) => {
1755
- const value = payload?.value ?? payload;
1922
+ const value = extractDropdownValue(payload);
1756
1923
  emit("update:modelValue", value);
1757
1924
  emit("change", value);
1758
1925
  };
@@ -1794,79 +1961,1023 @@ var VVideo = (0, import_runtime_core28.defineComponent)({
1794
1961
  setup(props, { emit }) {
1795
1962
  return () => (0, import_runtime_core28.h)("VVideo", {
1796
1963
  ...props,
1797
- onReady: (e) => emit("ready", e),
1964
+ onReady: (event) => emit("ready", event),
1798
1965
  onPlay: () => emit("play"),
1799
1966
  onPause: () => emit("pause"),
1800
1967
  onEnd: () => emit("end"),
1801
- onError: (e) => emit("error", e),
1802
- onProgress: (e) => emit("progress", e)
1968
+ onError: (event) => emit("error", event),
1969
+ onProgress: (event) => emit("progress", event)
1803
1970
  });
1804
1971
  }
1805
1972
  });
1806
1973
 
1807
- // src/directives/vShow.ts
1808
- var vShow = {
1809
- beforeMount(el, { value }) {
1810
- NativeBridge.updateProp(el.id, "hidden", !value);
1974
+ // src/components/VFlatList.ts
1975
+ var import_runtime_core29 = require("@vue/runtime-core");
1976
+ function getDefaultItemKey(item, index) {
1977
+ if (typeof item === "object" && item !== null) {
1978
+ const keyedItem = item;
1979
+ return keyedItem.id ?? keyedItem.key ?? index;
1980
+ }
1981
+ return index;
1982
+ }
1983
+ function resolveFlexValue(style) {
1984
+ return typeof style?.flex === "number" ? style.flex : 1;
1985
+ }
1986
+ var VFlatList = (0, import_runtime_core29.defineComponent)({
1987
+ name: "VFlatList",
1988
+ props: {
1989
+ /** Array of data items to render. */
1990
+ data: {
1991
+ type: Array,
1992
+ required: true
1993
+ },
1994
+ /**
1995
+ * Render function for each item. Receives { item, index } and returns a VNode.
1996
+ * If not provided, the `#item` slot is used instead.
1997
+ */
1998
+ renderItem: {
1999
+ type: Function,
2000
+ default: void 0
2001
+ },
2002
+ /** Extract a unique key from each item. Defaults to item.id, item.key, or index. */
2003
+ keyExtractor: {
2004
+ type: Function,
2005
+ default: getDefaultItemKey
2006
+ },
2007
+ /** Fixed height for each item in points. Required for virtualization math. */
2008
+ itemHeight: {
2009
+ type: Number,
2010
+ required: true
2011
+ },
2012
+ /**
2013
+ * Number of viewport-heights to render above and below the visible area.
2014
+ * Higher values reduce blank flashes during fast scrolling but use more memory.
2015
+ * Default: 3 (3 viewports above + 3 below = 7 total viewports of items).
2016
+ */
2017
+ windowSize: {
2018
+ type: Number,
2019
+ default: 3
2020
+ },
2021
+ /** Style for the outer scroll container. */
2022
+ style: {
2023
+ type: Object,
2024
+ default: () => ({})
2025
+ },
2026
+ /** Show vertical scroll indicator. Default: true */
2027
+ showsScrollIndicator: {
2028
+ type: Boolean,
2029
+ default: true
2030
+ },
2031
+ /** Enable bounce at scroll boundaries. Default: true */
2032
+ bounces: {
2033
+ type: Boolean,
2034
+ default: true
2035
+ },
2036
+ /** Height of the header slot in points. Used to offset items below the header. */
2037
+ headerHeight: {
2038
+ type: Number,
2039
+ default: 0
2040
+ },
2041
+ /**
2042
+ * How far from the end (in viewport fractions) to trigger endReached.
2043
+ * Default: 0.5 (trigger when within 50% of a viewport from the bottom).
2044
+ */
2045
+ endReachedThreshold: {
2046
+ type: Number,
2047
+ default: 0.5
2048
+ }
1811
2049
  },
1812
- updated(el, { value, oldValue }) {
1813
- if (value === oldValue) return;
1814
- NativeBridge.updateProp(el.id, "hidden", !value);
2050
+ emits: ["scroll", "endReached"],
2051
+ setup(props, { slots, emit }) {
2052
+ const scrollOffset = (0, import_runtime_core29.ref)(0);
2053
+ const viewportHeight = (0, import_runtime_core29.ref)(0);
2054
+ let endReachedFired = false;
2055
+ const hasHeader = (0, import_runtime_core29.computed)(() => !!slots.header);
2056
+ const totalHeight = (0, import_runtime_core29.computed)(() => {
2057
+ const itemsHeight = (props.data?.length ?? 0) * props.itemHeight;
2058
+ return itemsHeight + (hasHeader.value ? props.headerHeight : 0);
2059
+ });
2060
+ const visibleRange = (0, import_runtime_core29.computed)(() => {
2061
+ const vh = viewportHeight.value || props.itemHeight * 20;
2062
+ const buffer = vh * props.windowSize;
2063
+ const startPx = Math.max(0, scrollOffset.value - buffer);
2064
+ const endPx = scrollOffset.value + vh + buffer;
2065
+ const startIdx = Math.floor(startPx / props.itemHeight);
2066
+ const endIdx = Math.min(
2067
+ Math.ceil(endPx / props.itemHeight),
2068
+ props.data?.length ?? 0
2069
+ );
2070
+ return { start: startIdx, end: endIdx };
2071
+ });
2072
+ function onScroll(event) {
2073
+ scrollOffset.value = event.y ?? 0;
2074
+ if (event.layoutHeight && event.layoutHeight > 0) {
2075
+ viewportHeight.value = event.layoutHeight;
2076
+ }
2077
+ emit("scroll", event);
2078
+ const contentLength = totalHeight.value;
2079
+ const offset = scrollOffset.value;
2080
+ const vh = viewportHeight.value || props.itemHeight * 20;
2081
+ const distanceFromEnd = contentLength - vh - offset;
2082
+ const threshold = vh * props.endReachedThreshold;
2083
+ if (distanceFromEnd < threshold && !endReachedFired) {
2084
+ endReachedFired = true;
2085
+ emit("endReached");
2086
+ } else if (distanceFromEnd >= threshold) {
2087
+ endReachedFired = false;
2088
+ }
2089
+ }
2090
+ return () => {
2091
+ const items = props.data ?? [];
2092
+ const { start, end } = visibleRange.value;
2093
+ const children = [];
2094
+ for (let i = start; i < end; i++) {
2095
+ const item = items[i];
2096
+ if (item === void 0) continue;
2097
+ const key = props.keyExtractor(item, i);
2098
+ const itemContent = props.renderItem ? [props.renderItem({ item, index: i })] : slots.item?.({ item, index: i }) ?? [];
2099
+ children.push(
2100
+ (0, import_runtime_core29.h)(
2101
+ "VView",
2102
+ {
2103
+ key,
2104
+ style: {
2105
+ position: "absolute",
2106
+ top: (hasHeader.value ? props.headerHeight : 0) + i * props.itemHeight,
2107
+ left: 0,
2108
+ right: 0,
2109
+ height: props.itemHeight
2110
+ }
2111
+ },
2112
+ itemContent
2113
+ )
2114
+ );
2115
+ }
2116
+ if (slots.header) {
2117
+ children.unshift(
2118
+ (0, import_runtime_core29.h)("VView", { key: "__vfl_header__", style: { position: "absolute", top: 0, left: 0, right: 0 } }, slots.header())
2119
+ );
2120
+ }
2121
+ if (items.length === 0 && slots.empty) {
2122
+ return (0, import_runtime_core29.h)(
2123
+ "VScrollView",
2124
+ {
2125
+ style: { ...props.style, flex: resolveFlexValue(props.style) },
2126
+ showsVerticalScrollIndicator: props.showsScrollIndicator,
2127
+ bounces: props.bounces
2128
+ },
2129
+ [(0, import_runtime_core29.h)("VView", { style: { flex: 1 } }, slots.empty())]
2130
+ );
2131
+ }
2132
+ const innerContainer = (0, import_runtime_core29.h)(
2133
+ "VView",
2134
+ {
2135
+ key: "__vfl_container__",
2136
+ style: {
2137
+ height: totalHeight.value,
2138
+ width: "100%"
2139
+ }
2140
+ },
2141
+ children
2142
+ );
2143
+ return (0, import_runtime_core29.h)(
2144
+ "VScrollView",
2145
+ {
2146
+ style: { ...props.style, flex: resolveFlexValue(props.style) },
2147
+ showsVerticalScrollIndicator: props.showsScrollIndicator,
2148
+ bounces: props.bounces,
2149
+ onScroll
2150
+ },
2151
+ [innerContainer]
2152
+ );
2153
+ };
1815
2154
  }
1816
- };
2155
+ });
1817
2156
 
1818
- // src/errorBoundary.ts
1819
- var import_runtime_core29 = require("@vue/runtime-core");
1820
- var ErrorBoundary = (0, import_runtime_core29.defineComponent)({
1821
- name: "ErrorBoundary",
2157
+ // src/components/VTabBar.ts
2158
+ var import_runtime_core30 = require("@vue/runtime-core");
2159
+ var VTabBar = (0, import_runtime_core30.defineComponent)({
2160
+ name: "VTabBar",
1822
2161
  props: {
1823
- onError: Function,
1824
- resetKeys: {
2162
+ /** Array of tab configurations */
2163
+ tabs: {
1825
2164
  type: Array,
1826
- default: () => []
2165
+ required: true
2166
+ },
2167
+ /** Currently active tab ID */
2168
+ activeTab: {
2169
+ type: String,
2170
+ required: true
2171
+ },
2172
+ /** Position: 'top' | 'bottom' */
2173
+ position: {
2174
+ type: String,
2175
+ default: "bottom"
1827
2176
  }
1828
2177
  },
1829
- setup(props, { slots }) {
1830
- const error = (0, import_runtime_core29.ref)(null);
1831
- const errorInfo = (0, import_runtime_core29.ref)("");
1832
- (0, import_runtime_core29.onErrorCaptured)((err, _instance, info) => {
1833
- const normalizedError = err instanceof Error ? err : new Error(String(err));
1834
- error.value = normalizedError;
1835
- errorInfo.value = info;
1836
- if (props.onError) {
1837
- props.onError(normalizedError, info);
1838
- }
1839
- return false;
2178
+ emits: ["change"],
2179
+ setup(props, { emit }) {
2180
+ const activeTab = (0, import_runtime_core30.ref)(props.activeTab);
2181
+ (0, import_runtime_core30.watch)(() => props.activeTab, (newVal) => {
2182
+ activeTab.value = newVal;
1840
2183
  });
1841
- function reset() {
1842
- error.value = null;
1843
- errorInfo.value = "";
2184
+ const switchTab = (tabId) => {
2185
+ activeTab.value = tabId;
2186
+ emit("change", tabId);
2187
+ };
2188
+ return () => (0, import_runtime_core30.h)(VView, {
2189
+ style: {
2190
+ position: "absolute",
2191
+ [props.position]: 0,
2192
+ left: 0,
2193
+ right: 0,
2194
+ backgroundColor: "#fff",
2195
+ borderTopWidth: 1,
2196
+ borderTopColor: "#e0e0e0",
2197
+ flexDirection: "row",
2198
+ height: 60
2199
+ }
2200
+ }, () => props.tabs.map((tab) => {
2201
+ const isActive = activeTab.value === tab.id;
2202
+ return (0, import_runtime_core30.h)(VPressable, {
2203
+ key: tab.id,
2204
+ style: {
2205
+ flex: 1,
2206
+ justifyContent: "center",
2207
+ alignItems: "center"
2208
+ },
2209
+ onPress: () => switchTab(tab.id),
2210
+ accessibilityLabel: tab.label,
2211
+ accessibilityRole: "tab",
2212
+ accessibilityState: { selected: isActive }
2213
+ }, () => [
2214
+ tab.icon ? (0, import_runtime_core30.h)(VText, { style: { fontSize: 24, marginBottom: 4 } }, () => tab.icon) : null,
2215
+ (0, import_runtime_core30.h)(VText, {
2216
+ style: {
2217
+ fontSize: 12,
2218
+ fontWeight: isActive ? "600" : "400",
2219
+ color: isActive ? "#007AFF" : "#8E8E93"
2220
+ }
2221
+ }, () => tab.label),
2222
+ tab.badge ? (0, import_runtime_core30.h)(VView, {
2223
+ style: {
2224
+ position: "absolute",
2225
+ top: 8,
2226
+ right: "25%",
2227
+ backgroundColor: "#FF3B30",
2228
+ borderRadius: 10,
2229
+ minWidth: 20,
2230
+ height: 20,
2231
+ justifyContent: "center",
2232
+ alignItems: "center"
2233
+ }
2234
+ }, () => (0, import_runtime_core30.h)(VText, {
2235
+ style: {
2236
+ color: "#fff",
2237
+ fontSize: 12,
2238
+ fontWeight: "600",
2239
+ paddingHorizontal: 6
2240
+ }
2241
+ }, () => String(tab.badge))) : null
2242
+ ]);
2243
+ }));
2244
+ }
2245
+ });
2246
+
2247
+ // src/components/VDrawer.ts
2248
+ var import_runtime_core31 = require("@vue/runtime-core");
2249
+ var drawerContextKey = /* @__PURE__ */ Symbol("VDrawerContext");
2250
+ var VDrawer = (0, import_runtime_core31.defineComponent)({
2251
+ name: "VDrawer",
2252
+ props: {
2253
+ /** Whether the drawer is open */
2254
+ open: {
2255
+ type: Boolean,
2256
+ default: false
2257
+ },
2258
+ /** Drawer position: 'left' | 'right' */
2259
+ position: {
2260
+ type: String,
2261
+ default: "left"
2262
+ },
2263
+ /** Drawer width */
2264
+ width: {
2265
+ type: Number,
2266
+ default: 280
2267
+ },
2268
+ /** Close on item press */
2269
+ closeOnPress: {
2270
+ type: Boolean,
2271
+ default: true
1844
2272
  }
1845
- (0, import_runtime_core29.watch)(
1846
- () => props.resetKeys,
1847
- () => {
1848
- if (error.value) {
1849
- reset();
1850
- }
1851
- },
1852
- { deep: true }
1853
- );
2273
+ },
2274
+ emits: ["update:open", "close"],
2275
+ setup(props, { attrs, slots, emit }) {
2276
+ const isOpen = (0, import_runtime_core31.ref)(props.open);
2277
+ (0, import_runtime_core31.watch)(() => props.open, (value) => {
2278
+ isOpen.value = value;
2279
+ });
2280
+ const closeDrawer = () => {
2281
+ isOpen.value = false;
2282
+ emit("update:open", false);
2283
+ emit("close");
2284
+ };
2285
+ (0, import_runtime_core31.provide)(drawerContextKey, {
2286
+ close: closeDrawer,
2287
+ shouldCloseOnPress: () => props.closeOnPress
2288
+ });
1854
2289
  return () => {
1855
- if (error.value && slots.fallback) {
1856
- return slots.fallback({ error: error.value, errorInfo: errorInfo.value, reset });
2290
+ if (!isOpen.value && !slots.default) {
2291
+ return null;
2292
+ }
2293
+ const overlayStyle = {
2294
+ position: "absolute",
2295
+ top: 0,
2296
+ left: 0,
2297
+ right: 0,
2298
+ bottom: 0,
2299
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
2300
+ opacity: isOpen.value ? 1 : 0,
2301
+ zIndex: 999
2302
+ };
2303
+ const drawerStyle = {
2304
+ position: "absolute",
2305
+ top: 0,
2306
+ [props.position]: 0,
2307
+ width: props.width,
2308
+ height: "100%",
2309
+ backgroundColor: "#fff",
2310
+ transform: [
2311
+ { translateX: isOpen.value ? 0 : props.position === "left" ? -props.width : props.width }
2312
+ ],
2313
+ zIndex: 1e3
2314
+ };
2315
+ const drawerProps = {
2316
+ ...attrs,
2317
+ style: {
2318
+ ...drawerStyle,
2319
+ ...attrs.style && typeof attrs.style === "object" && !Array.isArray(attrs.style) ? attrs.style : {}
2320
+ }
2321
+ };
2322
+ const drawerChildren = [];
2323
+ if (slots.header) {
2324
+ drawerChildren.push(...slots.header());
2325
+ }
2326
+ if (slots.default) {
2327
+ drawerChildren.push(...slots.default({ close: closeDrawer }) ?? []);
2328
+ }
2329
+ return [
2330
+ // Overlay
2331
+ isOpen.value ? (0, import_runtime_core31.h)(VPressable, {
2332
+ style: overlayStyle,
2333
+ onPress: closeDrawer,
2334
+ accessibilityLabel: "Close menu"
2335
+ }) : null,
2336
+ // Drawer
2337
+ (0, import_runtime_core31.h)(VView, drawerProps, () => drawerChildren)
2338
+ ];
2339
+ };
2340
+ }
2341
+ });
2342
+ var VDrawerItem = (0, import_runtime_core31.defineComponent)({
2343
+ name: "VDrawerItem",
2344
+ props: {
2345
+ /** Icon (emoji or icon name) */
2346
+ icon: {
2347
+ type: String,
2348
+ default: ""
2349
+ },
2350
+ /** Label text */
2351
+ label: {
2352
+ type: String,
2353
+ required: true
2354
+ },
2355
+ /** Badge count */
2356
+ badge: {
2357
+ type: [Number, String],
2358
+ default: null
2359
+ },
2360
+ /** Disabled state */
2361
+ disabled: {
2362
+ type: Boolean,
2363
+ default: false
2364
+ }
2365
+ },
2366
+ emits: ["press"],
2367
+ setup(props, { slots, emit }) {
2368
+ const drawer = (0, import_runtime_core31.inject)(drawerContextKey, null);
2369
+ const handlePress = () => {
2370
+ if (props.disabled) return;
2371
+ emit("press");
2372
+ if (drawer?.shouldCloseOnPress()) {
2373
+ drawer.close();
1857
2374
  }
1858
- return slots.default?.();
1859
2375
  };
2376
+ return () => (0, import_runtime_core31.h)(VPressable, {
2377
+ style: {
2378
+ flexDirection: "row",
2379
+ alignItems: "center",
2380
+ padding: 16,
2381
+ borderBottomWidth: 1,
2382
+ borderBottomColor: "#f0f0f0",
2383
+ opacity: props.disabled ? 0.5 : 1
2384
+ },
2385
+ onPress: handlePress,
2386
+ disabled: props.disabled,
2387
+ accessibilityLabel: props.label,
2388
+ accessibilityRole: "menuitem",
2389
+ accessibilityState: { disabled: props.disabled }
2390
+ }, () => {
2391
+ const children = [];
2392
+ if (props.icon) {
2393
+ children.push(
2394
+ (0, import_runtime_core31.h)(VText, {
2395
+ style: {
2396
+ fontSize: 24,
2397
+ marginRight: 16,
2398
+ width: 32,
2399
+ textAlign: "center"
2400
+ }
2401
+ }, () => props.icon)
2402
+ );
2403
+ }
2404
+ children.push(
2405
+ (0, import_runtime_core31.h)(VText, {
2406
+ style: {
2407
+ flex: 1,
2408
+ fontSize: 16,
2409
+ color: props.disabled ? "#999" : "#333"
2410
+ }
2411
+ }, () => props.label)
2412
+ );
2413
+ if (props.badge) {
2414
+ children.push(
2415
+ (0, import_runtime_core31.h)(VView, {
2416
+ style: {
2417
+ backgroundColor: "#007AFF",
2418
+ borderRadius: 12,
2419
+ minWidth: 24,
2420
+ height: 24,
2421
+ justifyContent: "center",
2422
+ alignItems: "center",
2423
+ paddingHorizontal: 8
2424
+ }
2425
+ }, () => (0, import_runtime_core31.h)(VText, {
2426
+ style: {
2427
+ color: "#fff",
2428
+ fontSize: 12,
2429
+ fontWeight: "600"
2430
+ }
2431
+ }, () => String(props.badge)))
2432
+ );
2433
+ }
2434
+ if (slots.default) {
2435
+ children.push(...slots.default() ?? []);
2436
+ }
2437
+ return children;
2438
+ });
2439
+ }
2440
+ });
2441
+ var VDrawerSection = (0, import_runtime_core31.defineComponent)({
2442
+ name: "VDrawerSection",
2443
+ props: {
2444
+ /** Section title */
2445
+ title: {
2446
+ type: String,
2447
+ default: ""
2448
+ }
2449
+ },
2450
+ setup(props, { slots }) {
2451
+ return () => (0, import_runtime_core31.h)(VView, {
2452
+ style: {
2453
+ paddingVertical: 8,
2454
+ paddingHorizontal: 16,
2455
+ backgroundColor: "#f9f9f9",
2456
+ borderBottomWidth: 1,
2457
+ borderBottomColor: "#e0e0e0"
2458
+ }
2459
+ }, () => {
2460
+ const children = [];
2461
+ if (props.title) {
2462
+ children.push(
2463
+ (0, import_runtime_core31.h)(VText, {
2464
+ style: {
2465
+ fontSize: 13,
2466
+ fontWeight: "600",
2467
+ color: "#666",
2468
+ textTransform: "uppercase",
2469
+ letterSpacing: 0.5
2470
+ }
2471
+ }, () => props.title)
2472
+ );
2473
+ }
2474
+ if (slots.default) {
2475
+ children.push(...slots.default() ?? []);
2476
+ }
2477
+ return children;
2478
+ });
1860
2479
  }
1861
2480
  });
2481
+ VDrawer.Item = VDrawerItem;
2482
+ VDrawer.Section = VDrawerSection;
1862
2483
 
1863
- // src/index.ts
1864
- __reExport(index_exports, require("@vue/runtime-core"), module.exports);
2484
+ // src/components/VTransition.ts
2485
+ var import_runtime_core32 = require("@vue/runtime-core");
1865
2486
 
1866
- // src/stylesheet.ts
1867
- var validStyleProperties = /* @__PURE__ */ new Set([
1868
- // Layout (Yoga / Flexbox)
1869
- "flex",
2487
+ // src/composables/useAnimation.ts
2488
+ var Easing = {
2489
+ linear: "linear",
2490
+ ease: "ease",
2491
+ easeIn: "easeIn",
2492
+ easeOut: "easeOut",
2493
+ easeInOut: "easeInOut"
2494
+ };
2495
+ function hasViewId(value) {
2496
+ return typeof value === "object" && value !== null && "id" in value && typeof value.id === "number";
2497
+ }
2498
+ function isAnimationRef(target) {
2499
+ return typeof target === "object" && target !== null && "value" in target;
2500
+ }
2501
+ function resolveViewId(target) {
2502
+ if (typeof target === "number") return target;
2503
+ if (isAnimationRef(target)) {
2504
+ const val = target.value;
2505
+ if (hasViewId(val)) return val.id;
2506
+ throw new Error("[VueNative] Animation target ref has no .value.id \u2014 is the ref attached to a component?");
2507
+ }
2508
+ if (hasViewId(target)) return target.id;
2509
+ throw new Error("[VueNative] Invalid animation target. Pass a number, template ref, or NativeNode.");
2510
+ }
2511
+ function useAnimation() {
2512
+ function timing(target, toStyles, config = {}) {
2513
+ return NativeBridge.invokeNativeModule("Animation", "timing", [resolveViewId(target), toStyles, config]);
2514
+ }
2515
+ function spring(target, toStyles, config = {}) {
2516
+ return NativeBridge.invokeNativeModule("Animation", "spring", [resolveViewId(target), toStyles, config]);
2517
+ }
2518
+ function keyframe(target, steps, config = {}) {
2519
+ return NativeBridge.invokeNativeModule("Animation", "keyframe", [resolveViewId(target), steps, config]);
2520
+ }
2521
+ function sequence(animations) {
2522
+ return NativeBridge.invokeNativeModule("Animation", "sequence", [animations]);
2523
+ }
2524
+ function parallel(animations) {
2525
+ return NativeBridge.invokeNativeModule("Animation", "parallel", [animations]);
2526
+ }
2527
+ function fadeOut(target, duration = 300) {
2528
+ return timing(target, { opacity: 0 }, { duration });
2529
+ }
2530
+ function fadeIn(target, duration = 300) {
2531
+ return timing(target, { opacity: 1 }, { duration });
2532
+ }
2533
+ function slideInFromRight(target, duration = 300) {
2534
+ return timing(target, { translateX: 0 }, { duration, easing: "easeOut" });
2535
+ }
2536
+ function slideOutToRight(target, duration = 300) {
2537
+ return timing(target, { translateX: 400 }, { duration, easing: "easeIn" });
2538
+ }
2539
+ function resolveId(target) {
2540
+ return resolveViewId(target);
2541
+ }
2542
+ return {
2543
+ timing,
2544
+ spring,
2545
+ keyframe,
2546
+ sequence,
2547
+ parallel,
2548
+ fadeIn,
2549
+ fadeOut,
2550
+ slideInFromRight,
2551
+ slideOutToRight,
2552
+ resolveId,
2553
+ Easing
2554
+ };
2555
+ }
2556
+
2557
+ // src/components/VTransition.ts
2558
+ var DefaultDuration = 300;
2559
+ function resolveAnimationTarget(el) {
2560
+ if (!el) return void 0;
2561
+ if (typeof el === "number") return el;
2562
+ if (typeof el === "object" && "id" in el) return el.id;
2563
+ return void 0;
2564
+ }
2565
+ var VTransition = (0, import_runtime_core32.defineComponent)({
2566
+ name: "VTransition",
2567
+ props: {
2568
+ name: { type: String, default: "" },
2569
+ appear: { type: Boolean, default: false },
2570
+ persist: { type: Boolean, default: false },
2571
+ mode: { type: String, default: "default" },
2572
+ css: { type: Boolean, default: true },
2573
+ type: { type: String, default: "transition" },
2574
+ enterClass: { type: String, default: "" },
2575
+ leaveClass: { type: String, default: "" },
2576
+ enterActiveClass: { type: String, default: "" },
2577
+ leaveActiveClass: { type: String, default: "" },
2578
+ enterToClass: { type: String, default: "" },
2579
+ leaveToClass: { type: String, default: "" },
2580
+ enterFromClass: { type: String, default: "" },
2581
+ leaveFromClass: { type: String, default: "" },
2582
+ appearClass: { type: String, default: "" },
2583
+ appearActiveClass: { type: String, default: "" },
2584
+ appearToClass: { type: String, default: "" },
2585
+ duration: [Number, Object]
2586
+ },
2587
+ setup(transitionProps, { slots, expose }) {
2588
+ const { timing } = useAnimation();
2589
+ const isAppearing = (0, import_runtime_core32.ref)(false);
2590
+ const isLeaving = (0, import_runtime_core32.ref)(false);
2591
+ const hasEntered = (0, import_runtime_core32.ref)(!transitionProps.appear);
2592
+ function getElementFromVNode(vnode) {
2593
+ try {
2594
+ const el = vnode.el;
2595
+ if (!el) return void 0;
2596
+ return resolveAnimationTarget(el);
2597
+ } catch {
2598
+ return void 0;
2599
+ }
2600
+ }
2601
+ async function doEnter(el) {
2602
+ const viewId = getElementFromVNode(el);
2603
+ if (!viewId) return;
2604
+ isAppearing.value = true;
2605
+ const enterDuration = typeof transitionProps.duration === "object" ? transitionProps.duration.enter ?? DefaultDuration : transitionProps.duration ?? DefaultDuration;
2606
+ const enterStyles = { opacity: 1 };
2607
+ try {
2608
+ await timing(viewId, { opacity: 0 }, { duration: 0 });
2609
+ await timing(viewId, enterStyles, { duration: enterDuration, easing: "easeOut" });
2610
+ isAppearing.value = false;
2611
+ hasEntered.value = true;
2612
+ } catch (e) {
2613
+ console.warn("[VueNative Transition] enter animation failed:", e);
2614
+ isAppearing.value = false;
2615
+ hasEntered.value = true;
2616
+ }
2617
+ }
2618
+ async function doLeave(el) {
2619
+ const viewId = getElementFromVNode(el);
2620
+ if (!viewId) return;
2621
+ isLeaving.value = true;
2622
+ const leaveDuration = typeof transitionProps.duration === "object" ? transitionProps.duration.leave ?? DefaultDuration : transitionProps.duration ?? DefaultDuration;
2623
+ try {
2624
+ await timing(viewId, { opacity: 0 }, { duration: leaveDuration, easing: "easeIn" });
2625
+ } catch (e) {
2626
+ console.warn("[VueNative Transition] leave animation failed:", e);
2627
+ } finally {
2628
+ isLeaving.value = false;
2629
+ }
2630
+ }
2631
+ function onEnter(_el, done) {
2632
+ if (!hasEntered.value || transitionProps.appear) {
2633
+ doEnter(_el).then(() => done());
2634
+ } else {
2635
+ done();
2636
+ }
2637
+ }
2638
+ function onLeave(el, done) {
2639
+ doLeave(el).then(() => done());
2640
+ }
2641
+ function onAfterEnter() {
2642
+ }
2643
+ function onAfterLeave() {
2644
+ }
2645
+ function onEnterCancelled() {
2646
+ isAppearing.value = false;
2647
+ }
2648
+ function onLeaveCancelled() {
2649
+ isLeaving.value = false;
2650
+ }
2651
+ function onAppear(el, done) {
2652
+ isAppearing.value = true;
2653
+ doEnter(el).then(() => done());
2654
+ }
2655
+ function onAfterAppear() {
2656
+ isAppearing.value = false;
2657
+ }
2658
+ expose({
2659
+ onEnter,
2660
+ onLeave,
2661
+ onAfterEnter,
2662
+ onAfterLeave,
2663
+ onEnterCancelled,
2664
+ onLeaveCancelled,
2665
+ onAppear,
2666
+ onAfterAppear,
2667
+ isAppearing,
2668
+ isLeaving,
2669
+ hasEntered
2670
+ });
2671
+ return () => {
2672
+ const children = slots.default?.() ?? [];
2673
+ const hasDefault = children.length > 0;
2674
+ if (!hasDefault) {
2675
+ return (0, import_runtime_core32.h)("", {}, []);
2676
+ }
2677
+ let finalChildren = children;
2678
+ if (transitionProps.mode === "out-in") {
2679
+ if (isLeaving.value) {
2680
+ finalChildren = [children[children.length - 1]];
2681
+ } else if (!hasEntered.value) {
2682
+ finalChildren = [];
2683
+ }
2684
+ }
2685
+ if (transitionProps.mode === "in-out") {
2686
+ if (isAppearing.value && children.length > 1) {
2687
+ finalChildren = [children[0]];
2688
+ }
2689
+ }
2690
+ return (0, import_runtime_core32.h)("Transition", {
2691
+ name: transitionProps.name || "v",
2692
+ appear: transitionProps.appear,
2693
+ persist: transitionProps.persist || transitionProps.name === "persist",
2694
+ css: transitionProps.css,
2695
+ type: transitionProps.type,
2696
+ onEnter,
2697
+ onLeave,
2698
+ onAfterEnter,
2699
+ onAfterLeave,
2700
+ onEnterCancelled,
2701
+ onLeaveCancelled,
2702
+ onAppear,
2703
+ onAfterAppear
2704
+ }, () => finalChildren);
2705
+ };
2706
+ }
2707
+ });
2708
+ var VTransitionGroup = (0, import_runtime_core32.defineComponent)({
2709
+ name: "VTransitionGroup",
2710
+ props: {
2711
+ tag: { type: String, default: void 0 },
2712
+ name: { type: String, default: "v" },
2713
+ appear: { type: Boolean, default: false },
2714
+ persist: { type: Boolean, default: false },
2715
+ moveClass: { type: String, default: "" },
2716
+ duration: { type: Number, default: void 0 }
2717
+ },
2718
+ setup(groupProps, { slots, expose }) {
2719
+ const { timing } = useAnimation();
2720
+ function onMove(_el) {
2721
+ }
2722
+ function onEnter(el, done) {
2723
+ const viewId = resolveAnimationTarget(el);
2724
+ if (!viewId) {
2725
+ done();
2726
+ return;
2727
+ }
2728
+ timing(viewId, { opacity: 1 }, { duration: groupProps.duration ?? 300, easing: "easeOut" }).then(() => done()).catch(() => done());
2729
+ }
2730
+ function onLeave(el, done) {
2731
+ const viewId = resolveAnimationTarget(el);
2732
+ if (!viewId) {
2733
+ done();
2734
+ return;
2735
+ }
2736
+ timing(viewId, { opacity: 0 }, { duration: groupProps.duration ?? 300, easing: "easeIn" }).then(() => done()).catch(() => done());
2737
+ }
2738
+ expose({
2739
+ onEnter,
2740
+ onLeave,
2741
+ onMove
2742
+ });
2743
+ return () => {
2744
+ const children = slots.default?.() ?? [];
2745
+ return (0, import_runtime_core32.h)("TransitionGroup", {
2746
+ tag: groupProps.tag,
2747
+ name: groupProps.name,
2748
+ appear: groupProps.appear,
2749
+ persist: groupProps.persist,
2750
+ moveClass: groupProps.moveClass,
2751
+ onEnter,
2752
+ onLeave,
2753
+ onMove
2754
+ }, () => children);
2755
+ };
2756
+ }
2757
+ });
2758
+
2759
+ // src/components/KeepAlive.ts
2760
+ var import_runtime_core33 = require("@vue/runtime-core");
2761
+ function matches(pattern, name) {
2762
+ if (!pattern) return false;
2763
+ if (typeof pattern === "string") {
2764
+ return pattern === name;
2765
+ }
2766
+ if (pattern instanceof RegExp) {
2767
+ return pattern.test(name);
2768
+ }
2769
+ if (Array.isArray(pattern)) {
2770
+ return pattern.includes(name);
2771
+ }
2772
+ return false;
2773
+ }
2774
+ function getComponentName(vnode) {
2775
+ const component = vnode.type;
2776
+ if (typeof component === "object" && component !== null && "name" in component) {
2777
+ return component.name;
2778
+ }
2779
+ if (typeof component === "function") {
2780
+ return component.name;
2781
+ }
2782
+ return void 0;
2783
+ }
2784
+ var KeepAlive = (0, import_runtime_core33.defineComponent)({
2785
+ name: "KeepAlive",
2786
+ props: {
2787
+ include: [String, RegExp, Array],
2788
+ exclude: [String, RegExp, Array],
2789
+ max: [Number, String]
2790
+ },
2791
+ setup(props, { slots }) {
2792
+ const cache = /* @__PURE__ */ new Map();
2793
+ const keys = /* @__PURE__ */ new Set();
2794
+ const maxCacheSize = typeof props.max === "string" ? parseInt(props.max, 10) : props.max;
2795
+ function pruneCache(filter) {
2796
+ cache.forEach((_, key) => {
2797
+ if (!filter(key)) {
2798
+ cache.delete(key);
2799
+ keys.delete(key);
2800
+ }
2801
+ });
2802
+ }
2803
+ function pruneCacheEntry(key) {
2804
+ cache.delete(key);
2805
+ keys.delete(key);
2806
+ }
2807
+ (0, import_runtime_core33.watch)(
2808
+ () => [props.include, props.exclude],
2809
+ () => {
2810
+ if (!props.include && !props.exclude) return;
2811
+ pruneCache((name) => {
2812
+ if (props.include && !matches(props.include, name)) return false;
2813
+ if (props.exclude && matches(props.exclude, name)) return false;
2814
+ return true;
2815
+ });
2816
+ }
2817
+ );
2818
+ (0, import_runtime_core33.onUnmounted)(() => {
2819
+ cache.clear();
2820
+ keys.clear();
2821
+ });
2822
+ return () => {
2823
+ const children = slots.default?.() ?? [];
2824
+ if (!children.length) return children;
2825
+ const vnode = children[0];
2826
+ const name = getComponentName(vnode) ?? String(vnode.type);
2827
+ const key = name;
2828
+ if (props.include && !matches(props.include, name)) {
2829
+ return vnode;
2830
+ }
2831
+ if (props.exclude && matches(props.exclude, name)) {
2832
+ return vnode;
2833
+ }
2834
+ const cached = cache.get(key);
2835
+ if (cached) {
2836
+ keys.delete(key);
2837
+ keys.add(key);
2838
+ return cached.vnode;
2839
+ }
2840
+ if (maxCacheSize && cache.size >= maxCacheSize) {
2841
+ const firstKey = keys.values().next().value;
2842
+ if (firstKey) {
2843
+ pruneCacheEntry(firstKey);
2844
+ }
2845
+ }
2846
+ cache.set(key, { vnode, key });
2847
+ keys.add(key);
2848
+ return vnode;
2849
+ };
2850
+ }
2851
+ });
2852
+ KeepAlive.isKeepAlive = true;
2853
+
2854
+ // src/components/VSuspense.ts
2855
+ var import_runtime_core34 = require("@vue/runtime-core");
2856
+ var suspenseContextKey = /* @__PURE__ */ Symbol("suspense");
2857
+ var VSuspense = (0, import_runtime_core34.defineComponent)({
2858
+ name: "Suspense",
2859
+ props: {
2860
+ timeout: { type: Number, default: 3e4 }
2861
+ },
2862
+ setup(_props, { slots }) {
2863
+ const hasError = (0, import_runtime_core34.ref)(false);
2864
+ const error = (0, import_runtime_core34.shallowRef)(null);
2865
+ const pendingCount = (0, import_runtime_core34.ref)(0);
2866
+ const context = {
2867
+ hasError,
2868
+ error,
2869
+ pendingCount,
2870
+ resolve: () => {
2871
+ pendingCount.value--;
2872
+ },
2873
+ reject: (err) => {
2874
+ hasError.value = true;
2875
+ error.value = err;
2876
+ }
2877
+ };
2878
+ (0, import_runtime_core34.provide)(suspenseContextKey, context);
2879
+ return () => {
2880
+ if (hasError.value) {
2881
+ return slots.fallback?.({ error: error.value }) ?? null;
2882
+ }
2883
+ const defaultSlots = slots.default?.() ?? [];
2884
+ return defaultSlots;
2885
+ };
2886
+ }
2887
+ });
2888
+
2889
+ // src/components/index.ts
2890
+ var builtInComponents = {
2891
+ VView,
2892
+ VText,
2893
+ VButton,
2894
+ VInput,
2895
+ VSwitch,
2896
+ VActivityIndicator,
2897
+ VScrollView,
2898
+ VImage,
2899
+ VKeyboardAvoiding,
2900
+ VSafeArea,
2901
+ VSlider,
2902
+ VList,
2903
+ VModal,
2904
+ VAlertDialog,
2905
+ VStatusBar,
2906
+ VWebView,
2907
+ VProgressBar,
2908
+ VPicker,
2909
+ VSegmentedControl,
2910
+ VActionSheet,
2911
+ VRefreshControl,
2912
+ VPressable,
2913
+ VSectionList,
2914
+ VCheckbox,
2915
+ VRadio,
2916
+ VDropdown,
2917
+ VVideo,
2918
+ VFlatList,
2919
+ VTabBar,
2920
+ VDrawer,
2921
+ VDrawerItem,
2922
+ VDrawerSection,
2923
+ VTransition,
2924
+ VTransitionGroup,
2925
+ KeepAlive,
2926
+ VSuspense
2927
+ };
2928
+
2929
+ // src/errorBoundary.ts
2930
+ var import_runtime_core35 = require("@vue/runtime-core");
2931
+ var ErrorBoundary = (0, import_runtime_core35.defineComponent)({
2932
+ name: "ErrorBoundary",
2933
+ props: {
2934
+ onError: Function,
2935
+ resetKeys: {
2936
+ type: Array,
2937
+ default: () => []
2938
+ }
2939
+ },
2940
+ setup(props, { slots }) {
2941
+ const error = (0, import_runtime_core35.ref)(null);
2942
+ const errorInfo = (0, import_runtime_core35.ref)("");
2943
+ (0, import_runtime_core35.onErrorCaptured)((err, _instance, info) => {
2944
+ const normalizedError = err instanceof Error ? err : new Error(String(err));
2945
+ error.value = normalizedError;
2946
+ errorInfo.value = info;
2947
+ if (props.onError) {
2948
+ props.onError(normalizedError, info);
2949
+ }
2950
+ return false;
2951
+ });
2952
+ function reset() {
2953
+ error.value = null;
2954
+ errorInfo.value = "";
2955
+ }
2956
+ (0, import_runtime_core35.watch)(
2957
+ () => props.resetKeys,
2958
+ () => {
2959
+ if (error.value) {
2960
+ reset();
2961
+ }
2962
+ },
2963
+ { deep: true }
2964
+ );
2965
+ return () => {
2966
+ if (error.value && slots.fallback) {
2967
+ return slots.fallback({ error: error.value, errorInfo: errorInfo.value, reset });
2968
+ }
2969
+ return slots.default?.();
2970
+ };
2971
+ }
2972
+ });
2973
+
2974
+ // src/index.ts
2975
+ __reExport(index_exports, require("@vue/runtime-core"), module.exports);
2976
+
2977
+ // src/stylesheet.ts
2978
+ var validStyleProperties = /* @__PURE__ */ new Set([
2979
+ // Layout (Yoga / Flexbox)
2980
+ "flex",
1870
2981
  "flexDirection",
1871
2982
  "flexWrap",
1872
2983
  "flexGrow",
@@ -1978,11 +3089,78 @@ function createStyleSheet(styles) {
1978
3089
  }
1979
3090
  const result = {};
1980
3091
  for (const key in styles) {
1981
- result[key] = Object.freeze({ ...styles[key] });
3092
+ const styleKey = key;
3093
+ result[styleKey] = Object.freeze({ ...styles[styleKey] });
1982
3094
  }
1983
3095
  return Object.freeze(result);
1984
3096
  }
1985
3097
 
3098
+ // src/directives/vShow.ts
3099
+ var vShow = {
3100
+ beforeMount(el, { value }) {
3101
+ try {
3102
+ NativeBridge.updateProp(el.id, "hidden", !value);
3103
+ } catch (err) {
3104
+ console.error("[VueNative] v-show beforeMount error:", err);
3105
+ }
3106
+ },
3107
+ updated(el, { value, oldValue }) {
3108
+ if (value === oldValue) return;
3109
+ try {
3110
+ NativeBridge.updateProp(el.id, "hidden", !value);
3111
+ } catch (err) {
3112
+ console.error("[VueNative] v-show updated error:", err);
3113
+ }
3114
+ }
3115
+ };
3116
+
3117
+ // src/directives/vModel.ts
3118
+ function getModelValue(event) {
3119
+ const modelEvent = event;
3120
+ return modelEvent?.value ?? modelEvent?.target?.value ?? event;
3121
+ }
3122
+ var vModel = {
3123
+ beforeMount(el, binding, vnode) {
3124
+ const { value, modifiers } = binding;
3125
+ const { lazy, number, trim } = modifiers || {};
3126
+ NativeBridge.updateProp(el.id, "value", value);
3127
+ const assign = vnode.dirs?.[0]?.value;
3128
+ if (typeof assign !== "function") {
3129
+ console.warn(
3130
+ "[VueNative] v-model directive requires the vnode to have an assign function. This usually happens when using v-model on native elements rendered by Vue, not custom components with modelValue props."
3131
+ );
3132
+ return;
3133
+ }
3134
+ const eventName = lazy ? "change" : "input";
3135
+ NativeBridge.addEventListener(el.id, eventName, (event) => {
3136
+ let newValue = getModelValue(event);
3137
+ if (trim && typeof newValue === "string") {
3138
+ newValue = newValue.trim();
3139
+ }
3140
+ if (number) {
3141
+ newValue = Number(newValue);
3142
+ }
3143
+ assign(newValue);
3144
+ });
3145
+ },
3146
+ updated(el, { value, oldValue, modifiers }, vnode) {
3147
+ if (value === oldValue) return;
3148
+ const _assign = vnode.dirs?.[0]?.value;
3149
+ let newValue = value;
3150
+ if (modifiers?.trim && typeof value === "string") {
3151
+ newValue = value.trim();
3152
+ }
3153
+ if (modifiers?.number) {
3154
+ newValue = Number(value);
3155
+ }
3156
+ NativeBridge.updateProp(el.id, "value", newValue);
3157
+ },
3158
+ beforeUnmount(el, _binding, _vnode) {
3159
+ NativeBridge.removeEventListener(el.id, "input");
3160
+ NativeBridge.removeEventListener(el.id, "change");
3161
+ }
3162
+ };
3163
+
1986
3164
  // src/composables/useHaptics.ts
1987
3165
  function useHaptics() {
1988
3166
  function vibrate(style = "medium") {
@@ -2036,9 +3214,9 @@ function useAsyncStorage() {
2036
3214
  }
2037
3215
 
2038
3216
  // src/composables/useClipboard.ts
2039
- var import_runtime_core30 = require("@vue/runtime-core");
3217
+ var import_runtime_core36 = require("@vue/runtime-core");
2040
3218
  function useClipboard() {
2041
- const content = (0, import_runtime_core30.ref)("");
3219
+ const content = (0, import_runtime_core36.ref)("");
2042
3220
  function copy(text) {
2043
3221
  return NativeBridge.invokeNativeModule("Clipboard", "copy", [text]).then(() => void 0);
2044
3222
  }
@@ -2052,16 +3230,16 @@ function useClipboard() {
2052
3230
  }
2053
3231
 
2054
3232
  // src/composables/useDeviceInfo.ts
2055
- var import_runtime_core31 = require("@vue/runtime-core");
3233
+ var import_runtime_core37 = require("@vue/runtime-core");
2056
3234
  function useDeviceInfo() {
2057
- const model = (0, import_runtime_core31.ref)("");
2058
- const systemVersion = (0, import_runtime_core31.ref)("");
2059
- const systemName = (0, import_runtime_core31.ref)("");
2060
- const name = (0, import_runtime_core31.ref)("");
2061
- const screenWidth = (0, import_runtime_core31.ref)(0);
2062
- const screenHeight = (0, import_runtime_core31.ref)(0);
2063
- const scale = (0, import_runtime_core31.ref)(1);
2064
- const isLoaded = (0, import_runtime_core31.ref)(false);
3235
+ const model = (0, import_runtime_core37.ref)("");
3236
+ const systemVersion = (0, import_runtime_core37.ref)("");
3237
+ const systemName = (0, import_runtime_core37.ref)("");
3238
+ const name = (0, import_runtime_core37.ref)("");
3239
+ const screenWidth = (0, import_runtime_core37.ref)(0);
3240
+ const screenHeight = (0, import_runtime_core37.ref)(0);
3241
+ const scale = (0, import_runtime_core37.ref)(1);
3242
+ const isLoaded = (0, import_runtime_core37.ref)(false);
2065
3243
  async function fetchInfo() {
2066
3244
  const info = await NativeBridge.invokeNativeModule("DeviceInfo", "getInfo", []);
2067
3245
  model.value = info.model ?? "";
@@ -2073,7 +3251,7 @@ function useDeviceInfo() {
2073
3251
  scale.value = info.scale ?? 1;
2074
3252
  isLoaded.value = true;
2075
3253
  }
2076
- (0, import_runtime_core31.onMounted)(() => {
3254
+ (0, import_runtime_core37.onMounted)(() => {
2077
3255
  fetchInfo();
2078
3256
  });
2079
3257
  return {
@@ -2090,10 +3268,10 @@ function useDeviceInfo() {
2090
3268
  }
2091
3269
 
2092
3270
  // src/composables/useKeyboard.ts
2093
- var import_runtime_core32 = require("@vue/runtime-core");
3271
+ var import_runtime_core38 = require("@vue/runtime-core");
2094
3272
  function useKeyboard() {
2095
- const isVisible = (0, import_runtime_core32.ref)(false);
2096
- const height = (0, import_runtime_core32.ref)(0);
3273
+ const isVisible = (0, import_runtime_core38.ref)(false);
3274
+ const height = (0, import_runtime_core38.ref)(0);
2097
3275
  function dismiss() {
2098
3276
  return NativeBridge.invokeNativeModule("Keyboard", "dismiss", []).then(() => void 0);
2099
3277
  }
@@ -2106,61 +3284,11 @@ function useKeyboard() {
2106
3284
  return { isVisible, height, dismiss, getHeight };
2107
3285
  }
2108
3286
 
2109
- // src/composables/useAnimation.ts
2110
- var Easing = {
2111
- linear: "linear",
2112
- ease: "ease",
2113
- easeIn: "easeIn",
2114
- easeOut: "easeOut",
2115
- easeInOut: "easeInOut"
2116
- };
2117
- function useAnimation() {
2118
- function timing(viewId, toStyles, config = {}) {
2119
- return NativeBridge.invokeNativeModule("Animation", "timing", [viewId, toStyles, config]);
2120
- }
2121
- function spring(viewId, toStyles, config = {}) {
2122
- return NativeBridge.invokeNativeModule("Animation", "spring", [viewId, toStyles, config]);
2123
- }
2124
- function keyframe(viewId, steps, config = {}) {
2125
- return NativeBridge.invokeNativeModule("Animation", "keyframe", [viewId, steps, config]);
2126
- }
2127
- function sequence(animations) {
2128
- return NativeBridge.invokeNativeModule("Animation", "sequence", [animations]);
2129
- }
2130
- function parallel(animations) {
2131
- return NativeBridge.invokeNativeModule("Animation", "parallel", [animations]);
2132
- }
2133
- function fadeOut(viewId, duration = 300) {
2134
- return timing(viewId, { opacity: 0 }, { duration });
2135
- }
2136
- function fadeIn(viewId, duration = 300) {
2137
- return timing(viewId, { opacity: 1 }, { duration });
2138
- }
2139
- function slideInFromRight(viewId, duration = 300) {
2140
- return timing(viewId, { translateX: 0 }, { duration, easing: "easeOut" });
2141
- }
2142
- function slideOutToRight(viewId, duration = 300) {
2143
- return timing(viewId, { translateX: 400 }, { duration, easing: "easeIn" });
2144
- }
2145
- return {
2146
- timing,
2147
- spring,
2148
- keyframe,
2149
- sequence,
2150
- parallel,
2151
- fadeIn,
2152
- fadeOut,
2153
- slideInFromRight,
2154
- slideOutToRight,
2155
- Easing
2156
- };
2157
- }
2158
-
2159
3287
  // src/composables/useNetwork.ts
2160
- var import_runtime_core33 = require("@vue/runtime-core");
3288
+ var import_runtime_core39 = require("@vue/runtime-core");
2161
3289
  function useNetwork() {
2162
- const isConnected = (0, import_runtime_core33.ref)(true);
2163
- const connectionType = (0, import_runtime_core33.ref)("unknown");
3290
+ const isConnected = (0, import_runtime_core39.ref)(true);
3291
+ const connectionType = (0, import_runtime_core39.ref)("unknown");
2164
3292
  let lastEventTime = 0;
2165
3293
  const unsubscribe = NativeBridge.onGlobalEvent("network:change", (payload) => {
2166
3294
  lastEventTime = Date.now();
@@ -2175,14 +3303,14 @@ function useNetwork() {
2175
3303
  }
2176
3304
  }).catch(() => {
2177
3305
  });
2178
- (0, import_runtime_core33.onUnmounted)(unsubscribe);
3306
+ (0, import_runtime_core39.onUnmounted)(unsubscribe);
2179
3307
  return { isConnected, connectionType };
2180
3308
  }
2181
3309
 
2182
3310
  // src/composables/useAppState.ts
2183
- var import_runtime_core34 = require("@vue/runtime-core");
3311
+ var import_runtime_core40 = require("@vue/runtime-core");
2184
3312
  function useAppState() {
2185
- const state = (0, import_runtime_core34.ref)("active");
3313
+ const state = (0, import_runtime_core40.ref)("active");
2186
3314
  NativeBridge.invokeNativeModule("AppState", "getState").then((s) => {
2187
3315
  state.value = s;
2188
3316
  }).catch(() => {
@@ -2190,7 +3318,7 @@ function useAppState() {
2190
3318
  const unsubscribe = NativeBridge.onGlobalEvent("appState:change", (payload) => {
2191
3319
  state.value = payload.state;
2192
3320
  });
2193
- (0, import_runtime_core34.onUnmounted)(unsubscribe);
3321
+ (0, import_runtime_core40.onUnmounted)(unsubscribe);
2194
3322
  return { state };
2195
3323
  }
2196
3324
 
@@ -2225,10 +3353,10 @@ function usePermissions() {
2225
3353
  }
2226
3354
 
2227
3355
  // src/composables/useGeolocation.ts
2228
- var import_runtime_core35 = require("@vue/runtime-core");
3356
+ var import_runtime_core41 = require("@vue/runtime-core");
2229
3357
  function useGeolocation() {
2230
- const coords = (0, import_runtime_core35.ref)(null);
2231
- const error = (0, import_runtime_core35.ref)(null);
3358
+ const coords = (0, import_runtime_core41.ref)(null);
3359
+ const error = (0, import_runtime_core41.ref)(null);
2232
3360
  let watchId = null;
2233
3361
  async function getCurrentPosition() {
2234
3362
  try {
@@ -2253,7 +3381,7 @@ function useGeolocation() {
2253
3381
  const unsubscribeError = NativeBridge.onGlobalEvent("location:error", (payload) => {
2254
3382
  error.value = payload.message;
2255
3383
  });
2256
- (0, import_runtime_core35.onUnmounted)(() => {
3384
+ (0, import_runtime_core41.onUnmounted)(() => {
2257
3385
  unsubscribe();
2258
3386
  unsubscribeError();
2259
3387
  if (watchId !== null) clearWatch(watchId);
@@ -2273,7 +3401,7 @@ function useGeolocation() {
2273
3401
  }
2274
3402
 
2275
3403
  // src/composables/useCamera.ts
2276
- var import_runtime_core36 = require("@vue/runtime-core");
3404
+ var import_runtime_core42 = require("@vue/runtime-core");
2277
3405
  function useCamera() {
2278
3406
  const qrCleanups = [];
2279
3407
  async function launchCamera(options = {}) {
@@ -2296,7 +3424,7 @@ function useCamera() {
2296
3424
  qrCleanups.push(unsubscribe);
2297
3425
  return unsubscribe;
2298
3426
  }
2299
- (0, import_runtime_core36.onUnmounted)(() => {
3427
+ (0, import_runtime_core42.onUnmounted)(() => {
2300
3428
  NativeBridge.invokeNativeModule("Camera", "stopQRScan").catch(() => {
2301
3429
  });
2302
3430
  qrCleanups.forEach((fn) => fn());
@@ -2306,10 +3434,10 @@ function useCamera() {
2306
3434
  }
2307
3435
 
2308
3436
  // src/composables/useNotifications.ts
2309
- var import_runtime_core37 = require("@vue/runtime-core");
3437
+ var import_runtime_core43 = require("@vue/runtime-core");
2310
3438
  function useNotifications() {
2311
- const isGranted = (0, import_runtime_core37.ref)(false);
2312
- const pushToken = (0, import_runtime_core37.ref)(null);
3439
+ const isGranted = (0, import_runtime_core43.ref)(false);
3440
+ const pushToken = (0, import_runtime_core43.ref)(null);
2313
3441
  async function requestPermission() {
2314
3442
  const granted = await NativeBridge.invokeNativeModule("Notifications", "requestPermission");
2315
3443
  isGranted.value = granted;
@@ -2329,7 +3457,7 @@ function useNotifications() {
2329
3457
  }
2330
3458
  function onNotification(handler) {
2331
3459
  const unsubscribe = NativeBridge.onGlobalEvent("notification:received", handler);
2332
- (0, import_runtime_core37.onUnmounted)(unsubscribe);
3460
+ (0, import_runtime_core43.onUnmounted)(unsubscribe);
2333
3461
  return unsubscribe;
2334
3462
  }
2335
3463
  async function registerForPush() {
@@ -2343,12 +3471,12 @@ function useNotifications() {
2343
3471
  pushToken.value = payload.token;
2344
3472
  handler(payload.token);
2345
3473
  });
2346
- (0, import_runtime_core37.onUnmounted)(unsubscribe);
3474
+ (0, import_runtime_core43.onUnmounted)(unsubscribe);
2347
3475
  return unsubscribe;
2348
3476
  }
2349
3477
  function onPushReceived(handler) {
2350
3478
  const unsubscribe = NativeBridge.onGlobalEvent("push:received", handler);
2351
- (0, import_runtime_core37.onUnmounted)(unsubscribe);
3479
+ (0, import_runtime_core43.onUnmounted)(unsubscribe);
2352
3480
  return unsubscribe;
2353
3481
  }
2354
3482
  return {
@@ -2384,7 +3512,10 @@ function useBiometry() {
2384
3512
  }
2385
3513
 
2386
3514
  // src/composables/useHttp.ts
2387
- var import_runtime_core38 = require("@vue/runtime-core");
3515
+ var import_runtime_core44 = require("@vue/runtime-core");
3516
+ function isQueryRequestOptions(value) {
3517
+ return "params" in value || "headers" in value;
3518
+ }
2388
3519
  function useHttp(config = {}) {
2389
3520
  if (config.pins && Object.keys(config.pins).length > 0) {
2390
3521
  const configurePins = globalThis.__VN_configurePins;
@@ -2394,39 +3525,70 @@ function useHttp(config = {}) {
2394
3525
  NativeBridge.invokeNativeModule("Http", "configurePins", [config.pins]);
2395
3526
  }
2396
3527
  }
2397
- const loading = (0, import_runtime_core38.ref)(false);
2398
- const error = (0, import_runtime_core38.ref)(null);
3528
+ const loading = (0, import_runtime_core44.ref)(false);
3529
+ const error = (0, import_runtime_core44.ref)(null);
2399
3530
  let isMounted = true;
2400
- (0, import_runtime_core38.onUnmounted)(() => {
3531
+ (0, import_runtime_core44.onUnmounted)(() => {
2401
3532
  isMounted = false;
2402
3533
  });
3534
+ const BODY_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH"]);
3535
+ function parseResponseHeaders(response) {
3536
+ const result = {};
3537
+ if (!response.headers) return result;
3538
+ try {
3539
+ if (typeof response.headers.forEach === "function") {
3540
+ response.headers.forEach((value, key) => {
3541
+ result[key] = value;
3542
+ });
3543
+ } else if (typeof response.headers.entries === "function") {
3544
+ for (const [key, value] of response.headers.entries()) {
3545
+ result[key] = value;
3546
+ }
3547
+ }
3548
+ } catch {
3549
+ }
3550
+ return result;
3551
+ }
2403
3552
  async function request(method, url, options = {}) {
2404
3553
  const fullUrl = config.baseURL ? `${config.baseURL}${url}` : url;
2405
3554
  loading.value = true;
2406
3555
  error.value = null;
3556
+ let controller;
3557
+ let timeoutId;
3558
+ if (config.timeout && config.timeout > 0 && typeof AbortController !== "undefined") {
3559
+ controller = new AbortController();
3560
+ timeoutId = setTimeout(() => controller.abort(), config.timeout);
3561
+ }
2407
3562
  try {
3563
+ const upperMethod = method.toUpperCase();
2408
3564
  const mergedHeaders = {
2409
- "Content-Type": "application/json",
2410
3565
  ...config.headers ?? {},
2411
3566
  ...options.headers ?? {}
2412
3567
  };
3568
+ if (BODY_METHODS.has(upperMethod) && !mergedHeaders["Content-Type"]) {
3569
+ mergedHeaders["Content-Type"] = "application/json";
3570
+ }
2413
3571
  const fetchOptions = {
2414
- method: method.toUpperCase(),
3572
+ method: upperMethod,
2415
3573
  headers: mergedHeaders
2416
3574
  };
3575
+ if (controller) {
3576
+ fetchOptions.signal = controller.signal;
3577
+ }
2417
3578
  if (options.body !== void 0) {
2418
3579
  fetchOptions.body = JSON.stringify(options.body);
2419
3580
  }
2420
3581
  const response = await fetch(fullUrl, fetchOptions);
2421
3582
  const data = await response.json();
3583
+ const responseHeaders = parseResponseHeaders(response);
2422
3584
  if (!isMounted) {
2423
- return { data, status: response.status, ok: response.ok, headers: {} };
3585
+ return { data, status: response.status, ok: response.ok, headers: responseHeaders };
2424
3586
  }
2425
3587
  return {
2426
3588
  data,
2427
3589
  status: response.status,
2428
3590
  ok: response.ok,
2429
- headers: {}
3591
+ headers: responseHeaders
2430
3592
  };
2431
3593
  } catch (e) {
2432
3594
  const msg = e instanceof Error ? e.message : String(e);
@@ -2435,6 +3597,9 @@ function useHttp(config = {}) {
2435
3597
  }
2436
3598
  throw e;
2437
3599
  } finally {
3600
+ if (timeoutId !== void 0) {
3601
+ clearTimeout(timeoutId);
3602
+ }
2438
3603
  if (isMounted) {
2439
3604
  loading.value = false;
2440
3605
  }
@@ -2449,30 +3614,24 @@ function useHttp(config = {}) {
2449
3614
  loading,
2450
3615
  error,
2451
3616
  get: (url, options) => {
2452
- if (options && !("params" in options) && !("headers" in options)) {
2453
- return request("GET", url, { headers: options });
2454
- }
2455
- const opts = options;
2456
- return request("GET", buildUrl(url, opts?.params), { headers: opts?.headers });
3617
+ const normalizedOptions = options ? isQueryRequestOptions(options) ? options : { headers: options } : void 0;
3618
+ return request("GET", buildUrl(url, normalizedOptions?.params), { headers: normalizedOptions?.headers });
2457
3619
  },
2458
3620
  post: (url, body, headers) => request("POST", url, { body, headers }),
2459
3621
  put: (url, body, headers) => request("PUT", url, { body, headers }),
2460
3622
  patch: (url, body, headers) => request("PATCH", url, { body, headers }),
2461
3623
  delete: (url, options) => {
2462
- if (options && !("params" in options) && !("headers" in options)) {
2463
- return request("DELETE", url, { headers: options });
2464
- }
2465
- const opts = options;
2466
- return request("DELETE", buildUrl(url, opts?.params), { headers: opts?.headers });
3624
+ const normalizedOptions = options ? isQueryRequestOptions(options) ? options : { headers: options } : void 0;
3625
+ return request("DELETE", buildUrl(url, normalizedOptions?.params), { headers: normalizedOptions?.headers });
2467
3626
  }
2468
3627
  };
2469
3628
  }
2470
3629
 
2471
3630
  // src/composables/useColorScheme.ts
2472
- var import_runtime_core39 = require("@vue/runtime-core");
3631
+ var import_runtime_core45 = require("@vue/runtime-core");
2473
3632
  function useColorScheme() {
2474
- const colorScheme = (0, import_runtime_core39.ref)("light");
2475
- const isDark = (0, import_runtime_core39.ref)(false);
3633
+ const colorScheme = (0, import_runtime_core45.ref)("light");
3634
+ const isDark = (0, import_runtime_core45.ref)(false);
2476
3635
  const unsubscribe = NativeBridge.onGlobalEvent(
2477
3636
  "colorScheme:change",
2478
3637
  (payload) => {
@@ -2480,15 +3639,15 @@ function useColorScheme() {
2480
3639
  isDark.value = payload.colorScheme === "dark";
2481
3640
  }
2482
3641
  );
2483
- (0, import_runtime_core39.onUnmounted)(unsubscribe);
3642
+ (0, import_runtime_core45.onUnmounted)(unsubscribe);
2484
3643
  return { colorScheme, isDark };
2485
3644
  }
2486
3645
 
2487
3646
  // src/composables/useBackHandler.ts
2488
- var import_runtime_core40 = require("@vue/runtime-core");
3647
+ var import_runtime_core46 = require("@vue/runtime-core");
2489
3648
  function useBackHandler(handler) {
2490
3649
  let unsubscribe = null;
2491
- (0, import_runtime_core40.onMounted)(() => {
3650
+ (0, import_runtime_core46.onMounted)(() => {
2492
3651
  unsubscribe = NativeBridge.onGlobalEvent("hardware:backPress", () => {
2493
3652
  const handled = handler();
2494
3653
  if (!handled) {
@@ -2497,7 +3656,7 @@ function useBackHandler(handler) {
2497
3656
  }
2498
3657
  });
2499
3658
  });
2500
- (0, import_runtime_core40.onUnmounted)(() => {
3659
+ (0, import_runtime_core46.onUnmounted)(() => {
2501
3660
  unsubscribe?.();
2502
3661
  unsubscribe = null;
2503
3662
  });
@@ -2521,11 +3680,11 @@ function useSecureStorage() {
2521
3680
  }
2522
3681
 
2523
3682
  // src/composables/useI18n.ts
2524
- var import_runtime_core41 = require("@vue/runtime-core");
3683
+ var import_runtime_core47 = require("@vue/runtime-core");
2525
3684
  function useI18n() {
2526
- const isRTL = (0, import_runtime_core41.ref)(false);
2527
- const locale = (0, import_runtime_core41.ref)("en");
2528
- (0, import_runtime_core41.onMounted)(async () => {
3685
+ const isRTL = (0, import_runtime_core47.ref)(false);
3686
+ const locale = (0, import_runtime_core47.ref)("en");
3687
+ (0, import_runtime_core47.onMounted)(async () => {
2529
3688
  try {
2530
3689
  const info = await NativeBridge.invokeNativeModule("DeviceInfo", "getDeviceInfo", []);
2531
3690
  locale.value = info?.locale || "en";
@@ -2536,21 +3695,13 @@ function useI18n() {
2536
3695
  return { isRTL, locale };
2537
3696
  }
2538
3697
 
2539
- // src/composables/usePlatform.ts
2540
- function usePlatform() {
2541
- const platform = typeof __PLATFORM__ !== "undefined" ? __PLATFORM__ : "ios";
2542
- const isIOS = platform === "ios";
2543
- const isAndroid = platform === "android";
2544
- return { platform, isIOS, isAndroid };
2545
- }
2546
-
2547
3698
  // src/composables/useDimensions.ts
2548
- var import_runtime_core42 = require("@vue/runtime-core");
3699
+ var import_runtime_core48 = require("@vue/runtime-core");
2549
3700
  function useDimensions() {
2550
- const width = (0, import_runtime_core42.ref)(0);
2551
- const height = (0, import_runtime_core42.ref)(0);
2552
- const scale = (0, import_runtime_core42.ref)(1);
2553
- (0, import_runtime_core42.onMounted)(async () => {
3701
+ const width = (0, import_runtime_core48.ref)(0);
3702
+ const height = (0, import_runtime_core48.ref)(0);
3703
+ const scale = (0, import_runtime_core48.ref)(1);
3704
+ (0, import_runtime_core48.onMounted)(async () => {
2554
3705
  try {
2555
3706
  const info = await NativeBridge.invokeNativeModule("DeviceInfo", "getInfo", []);
2556
3707
  width.value = info?.screenWidth || 0;
@@ -2564,12 +3715,12 @@ function useDimensions() {
2564
3715
  if (payload.height != null) height.value = payload.height;
2565
3716
  if (payload.scale != null) scale.value = payload.scale;
2566
3717
  });
2567
- (0, import_runtime_core42.onUnmounted)(cleanup);
3718
+ (0, import_runtime_core48.onUnmounted)(cleanup);
2568
3719
  return { width, height, scale };
2569
3720
  }
2570
3721
 
2571
3722
  // src/composables/useWebSocket.ts
2572
- var import_runtime_core43 = require("@vue/runtime-core");
3723
+ var import_runtime_core49 = require("@vue/runtime-core");
2573
3724
  var connectionCounter = 0;
2574
3725
  function useWebSocket(url, options = {}) {
2575
3726
  const {
@@ -2579,9 +3730,9 @@ function useWebSocket(url, options = {}) {
2579
3730
  reconnectInterval = 1e3
2580
3731
  } = options;
2581
3732
  const connectionId = `ws_${++connectionCounter}_${Date.now()}`;
2582
- const status = (0, import_runtime_core43.ref)("CLOSED");
2583
- const lastMessage = (0, import_runtime_core43.ref)(null);
2584
- const error = (0, import_runtime_core43.ref)(null);
3733
+ const status = (0, import_runtime_core49.ref)("CLOSED");
3734
+ const lastMessage = (0, import_runtime_core49.ref)(null);
3735
+ const error = (0, import_runtime_core49.ref)(null);
2585
3736
  let reconnectAttempts = 0;
2586
3737
  let reconnectTimer = null;
2587
3738
  const MAX_PENDING_MESSAGES = 100;
@@ -2666,7 +3817,7 @@ function useWebSocket(url, options = {}) {
2666
3817
  if (autoConnect) {
2667
3818
  open();
2668
3819
  }
2669
- (0, import_runtime_core43.onUnmounted)(() => {
3820
+ (0, import_runtime_core49.onUnmounted)(() => {
2670
3821
  if (reconnectTimer) {
2671
3822
  clearTimeout(reconnectTimer);
2672
3823
  }
@@ -2735,12 +3886,12 @@ function useFileSystem() {
2735
3886
  }
2736
3887
 
2737
3888
  // src/composables/useSensors.ts
2738
- var import_runtime_core44 = require("@vue/runtime-core");
3889
+ var import_runtime_core50 = require("@vue/runtime-core");
2739
3890
  function useAccelerometer(options = {}) {
2740
- const x = (0, import_runtime_core44.ref)(0);
2741
- const y = (0, import_runtime_core44.ref)(0);
2742
- const z = (0, import_runtime_core44.ref)(0);
2743
- const isAvailable = (0, import_runtime_core44.ref)(false);
3891
+ const x = (0, import_runtime_core50.ref)(0);
3892
+ const y = (0, import_runtime_core50.ref)(0);
3893
+ const z = (0, import_runtime_core50.ref)(0);
3894
+ const isAvailable = (0, import_runtime_core50.ref)(false);
2744
3895
  let running = false;
2745
3896
  let unsubscribe = null;
2746
3897
  NativeBridge.invokeNativeModule("Sensors", "isAvailable", ["accelerometer"]).then((result) => {
@@ -2768,16 +3919,16 @@ function useAccelerometer(options = {}) {
2768
3919
  NativeBridge.invokeNativeModule("Sensors", "stopAccelerometer").catch(() => {
2769
3920
  });
2770
3921
  }
2771
- (0, import_runtime_core44.onUnmounted)(() => {
3922
+ (0, import_runtime_core50.onUnmounted)(() => {
2772
3923
  stop();
2773
3924
  });
2774
3925
  return { x, y, z, isAvailable, start, stop };
2775
3926
  }
2776
3927
  function useGyroscope(options = {}) {
2777
- const x = (0, import_runtime_core44.ref)(0);
2778
- const y = (0, import_runtime_core44.ref)(0);
2779
- const z = (0, import_runtime_core44.ref)(0);
2780
- const isAvailable = (0, import_runtime_core44.ref)(false);
3928
+ const x = (0, import_runtime_core50.ref)(0);
3929
+ const y = (0, import_runtime_core50.ref)(0);
3930
+ const z = (0, import_runtime_core50.ref)(0);
3931
+ const isAvailable = (0, import_runtime_core50.ref)(false);
2781
3932
  let running = false;
2782
3933
  let unsubscribe = null;
2783
3934
  NativeBridge.invokeNativeModule("Sensors", "isAvailable", ["gyroscope"]).then((result) => {
@@ -2805,20 +3956,31 @@ function useGyroscope(options = {}) {
2805
3956
  NativeBridge.invokeNativeModule("Sensors", "stopGyroscope").catch(() => {
2806
3957
  });
2807
3958
  }
2808
- (0, import_runtime_core44.onUnmounted)(() => {
3959
+ (0, import_runtime_core50.onUnmounted)(() => {
2809
3960
  stop();
2810
3961
  });
2811
3962
  return { x, y, z, isAvailable, start, stop };
2812
3963
  }
2813
3964
 
2814
3965
  // src/composables/useAudio.ts
2815
- var import_runtime_core45 = require("@vue/runtime-core");
3966
+ var import_runtime_core51 = require("@vue/runtime-core");
3967
+ function asRecord(value) {
3968
+ return typeof value === "object" && value !== null ? value : null;
3969
+ }
3970
+ function getNumberProp(record, key) {
3971
+ const value = record?.[key];
3972
+ return typeof value === "number" ? value : void 0;
3973
+ }
3974
+ function getStringProp(record, key) {
3975
+ const value = record?.[key];
3976
+ return typeof value === "string" ? value : void 0;
3977
+ }
2816
3978
  function useAudio() {
2817
- const duration = (0, import_runtime_core45.ref)(0);
2818
- const position = (0, import_runtime_core45.ref)(0);
2819
- const isPlaying = (0, import_runtime_core45.ref)(false);
2820
- const isRecording = (0, import_runtime_core45.ref)(false);
2821
- const error = (0, import_runtime_core45.ref)(null);
3979
+ const duration = (0, import_runtime_core51.ref)(0);
3980
+ const position = (0, import_runtime_core51.ref)(0);
3981
+ const isPlaying = (0, import_runtime_core51.ref)(false);
3982
+ const isRecording = (0, import_runtime_core51.ref)(false);
3983
+ const error = (0, import_runtime_core51.ref)(null);
2822
3984
  const unsubProgress = NativeBridge.onGlobalEvent("audio:progress", (payload) => {
2823
3985
  position.value = payload.currentTime ?? 0;
2824
3986
  duration.value = payload.duration ?? 0;
@@ -2831,7 +3993,7 @@ function useAudio() {
2831
3993
  error.value = payload.message ?? "Unknown audio error";
2832
3994
  isPlaying.value = false;
2833
3995
  });
2834
- (0, import_runtime_core45.onUnmounted)(() => {
3996
+ (0, import_runtime_core51.onUnmounted)(() => {
2835
3997
  unsubProgress();
2836
3998
  unsubComplete();
2837
3999
  unsubError();
@@ -2844,9 +4006,10 @@ function useAudio() {
2844
4006
  });
2845
4007
  async function play(uri, options = {}) {
2846
4008
  error.value = null;
2847
- const result = await NativeBridge.invokeNativeModule("Audio", "play", [uri, options]);
2848
- if (result?.duration != null) {
2849
- duration.value = result.duration;
4009
+ const result = asRecord(await NativeBridge.invokeNativeModule("Audio", "play", [uri, options]));
4010
+ const audioDuration = getNumberProp(result, "duration");
4011
+ if (audioDuration !== void 0) {
4012
+ duration.value = audioDuration;
2850
4013
  }
2851
4014
  isPlaying.value = true;
2852
4015
  }
@@ -2872,14 +4035,17 @@ function useAudio() {
2872
4035
  }
2873
4036
  async function startRecording(options = {}) {
2874
4037
  error.value = null;
2875
- const result = await NativeBridge.invokeNativeModule("Audio", "startRecording", [options]);
4038
+ const result = asRecord(await NativeBridge.invokeNativeModule("Audio", "startRecording", [options]));
2876
4039
  isRecording.value = true;
2877
- return result?.uri ?? "";
4040
+ return getStringProp(result, "uri") ?? "";
2878
4041
  }
2879
4042
  async function stopRecording() {
2880
- const result = await NativeBridge.invokeNativeModule("Audio", "stopRecording", []);
4043
+ const result = asRecord(await NativeBridge.invokeNativeModule("Audio", "stopRecording", []));
2881
4044
  isRecording.value = false;
2882
- return { uri: result?.uri ?? "", duration: result?.duration ?? 0 };
4045
+ return {
4046
+ uri: getStringProp(result, "uri") ?? "",
4047
+ duration: getNumberProp(result, "duration") ?? 0
4048
+ };
2883
4049
  }
2884
4050
  async function pauseRecording() {
2885
4051
  await NativeBridge.invokeNativeModule("Audio", "pauseRecording", []);
@@ -2910,9 +4076,9 @@ function useAudio() {
2910
4076
  }
2911
4077
 
2912
4078
  // src/composables/useDatabase.ts
2913
- var import_runtime_core46 = require("@vue/runtime-core");
4079
+ var import_runtime_core52 = require("@vue/runtime-core");
2914
4080
  function useDatabase(name = "default") {
2915
- const isOpen = (0, import_runtime_core46.ref)(false);
4081
+ const isOpen = (0, import_runtime_core52.ref)(false);
2916
4082
  let opened = false;
2917
4083
  async function ensureOpen() {
2918
4084
  if (opened) return;
@@ -2954,7 +4120,7 @@ function useDatabase(name = "default") {
2954
4120
  opened = false;
2955
4121
  isOpen.value = false;
2956
4122
  }
2957
- (0, import_runtime_core46.onUnmounted)(() => {
4123
+ (0, import_runtime_core52.onUnmounted)(() => {
2958
4124
  if (opened) {
2959
4125
  NativeBridge.invokeNativeModule("Database", "close", [name]).catch(() => {
2960
4126
  });
@@ -2966,12 +4132,12 @@ function useDatabase(name = "default") {
2966
4132
  }
2967
4133
 
2968
4134
  // src/composables/usePerformance.ts
2969
- var import_runtime_core47 = require("@vue/runtime-core");
4135
+ var import_runtime_core53 = require("@vue/runtime-core");
2970
4136
  function usePerformance() {
2971
- const isProfiling = (0, import_runtime_core47.ref)(false);
2972
- const fps = (0, import_runtime_core47.ref)(0);
2973
- const memoryMB = (0, import_runtime_core47.ref)(0);
2974
- const bridgeOps = (0, import_runtime_core47.ref)(0);
4137
+ const isProfiling = (0, import_runtime_core53.ref)(false);
4138
+ const fps = (0, import_runtime_core53.ref)(0);
4139
+ const memoryMB = (0, import_runtime_core53.ref)(0);
4140
+ const bridgeOps = (0, import_runtime_core53.ref)(0);
2975
4141
  let unsubscribe = null;
2976
4142
  function handleMetrics(payload) {
2977
4143
  fps.value = payload.fps ?? 0;
@@ -2996,7 +4162,7 @@ function usePerformance() {
2996
4162
  async function getMetrics() {
2997
4163
  return NativeBridge.invokeNativeModule("Performance", "getMetrics", []);
2998
4164
  }
2999
- (0, import_runtime_core47.onUnmounted)(() => {
4165
+ (0, import_runtime_core53.onUnmounted)(() => {
3000
4166
  if (isProfiling.value) {
3001
4167
  NativeBridge.invokeNativeModule("Performance", "stopProfiling", []).catch(() => {
3002
4168
  });
@@ -3019,10 +4185,10 @@ function usePerformance() {
3019
4185
  }
3020
4186
 
3021
4187
  // src/composables/useSharedElementTransition.ts
3022
- var import_runtime_core48 = require("@vue/runtime-core");
4188
+ var import_runtime_core54 = require("@vue/runtime-core");
3023
4189
  var sharedElementRegistry = /* @__PURE__ */ new Map();
3024
4190
  function useSharedElementTransition(elementId) {
3025
- const viewId = (0, import_runtime_core48.ref)(null);
4191
+ const viewId = (0, import_runtime_core54.ref)(null);
3026
4192
  function register(nativeViewId) {
3027
4193
  viewId.value = nativeViewId;
3028
4194
  sharedElementRegistry.set(elementId, nativeViewId);
@@ -3031,7 +4197,7 @@ function useSharedElementTransition(elementId) {
3031
4197
  viewId.value = null;
3032
4198
  sharedElementRegistry.delete(elementId);
3033
4199
  }
3034
- (0, import_runtime_core48.onUnmounted)(() => {
4200
+ (0, import_runtime_core54.onUnmounted)(() => {
3035
4201
  unregister();
3036
4202
  });
3037
4203
  return {
@@ -3055,11 +4221,19 @@ function clearSharedElementRegistry() {
3055
4221
  }
3056
4222
 
3057
4223
  // src/composables/useIAP.ts
3058
- var import_runtime_core49 = require("@vue/runtime-core");
4224
+ var import_runtime_core55 = require("@vue/runtime-core");
4225
+ function getErrorMessage(error) {
4226
+ if (error instanceof Error) return error.message;
4227
+ if (typeof error === "object" && error !== null && "message" in error) {
4228
+ const message = error.message;
4229
+ if (typeof message === "string") return message;
4230
+ }
4231
+ return String(error);
4232
+ }
3059
4233
  function useIAP() {
3060
- const products = (0, import_runtime_core49.ref)([]);
3061
- const isReady = (0, import_runtime_core49.ref)(false);
3062
- const error = (0, import_runtime_core49.ref)(null);
4234
+ const products = (0, import_runtime_core55.ref)([]);
4235
+ const isReady = (0, import_runtime_core55.ref)(false);
4236
+ const error = (0, import_runtime_core55.ref)(null);
3063
4237
  const cleanups = [];
3064
4238
  const unsubscribe = NativeBridge.onGlobalEvent("iap:transactionUpdate", (payload) => {
3065
4239
  if (payload.state === "failed" && payload.error) {
@@ -3070,7 +4244,7 @@ function useIAP() {
3070
4244
  NativeBridge.invokeNativeModule("IAP", "initialize").then(() => {
3071
4245
  isReady.value = true;
3072
4246
  }).catch((err) => {
3073
- error.value = String(err);
4247
+ error.value = getErrorMessage(err);
3074
4248
  });
3075
4249
  async function getProducts(skus) {
3076
4250
  error.value = null;
@@ -3080,7 +4254,7 @@ function useIAP() {
3080
4254
  products.value = productList;
3081
4255
  return productList;
3082
4256
  } catch (err) {
3083
- error.value = String(err);
4257
+ error.value = getErrorMessage(err);
3084
4258
  return [];
3085
4259
  }
3086
4260
  }
@@ -3089,7 +4263,7 @@ function useIAP() {
3089
4263
  try {
3090
4264
  return await NativeBridge.invokeNativeModule("IAP", "purchase", [sku]);
3091
4265
  } catch (err) {
3092
- error.value = String(err);
4266
+ error.value = getErrorMessage(err);
3093
4267
  return null;
3094
4268
  }
3095
4269
  }
@@ -3098,7 +4272,7 @@ function useIAP() {
3098
4272
  try {
3099
4273
  return await NativeBridge.invokeNativeModule("IAP", "restorePurchases");
3100
4274
  } catch (err) {
3101
- error.value = String(err);
4275
+ error.value = getErrorMessage(err);
3102
4276
  return [];
3103
4277
  }
3104
4278
  }
@@ -3107,7 +4281,7 @@ function useIAP() {
3107
4281
  try {
3108
4282
  return await NativeBridge.invokeNativeModule("IAP", "getActiveSubscriptions");
3109
4283
  } catch (err) {
3110
- error.value = String(err);
4284
+ error.value = getErrorMessage(err);
3111
4285
  return [];
3112
4286
  }
3113
4287
  }
@@ -3116,7 +4290,7 @@ function useIAP() {
3116
4290
  cleanups.push(unsub);
3117
4291
  return unsub;
3118
4292
  }
3119
- (0, import_runtime_core49.onUnmounted)(() => {
4293
+ (0, import_runtime_core55.onUnmounted)(() => {
3120
4294
  cleanups.forEach((fn) => fn());
3121
4295
  cleanups.length = 0;
3122
4296
  });
@@ -3133,11 +4307,32 @@ function useIAP() {
3133
4307
  }
3134
4308
 
3135
4309
  // src/composables/useAppleSignIn.ts
3136
- var import_runtime_core50 = require("@vue/runtime-core");
4310
+ var import_runtime_core56 = require("@vue/runtime-core");
4311
+ function getErrorMessage2(error) {
4312
+ if (error instanceof Error) return error.message;
4313
+ if (typeof error === "object" && error !== null && "message" in error) {
4314
+ const message = error.message;
4315
+ if (typeof message === "string") return message;
4316
+ }
4317
+ return String(error);
4318
+ }
4319
+ function normalizeSocialUser(value, provider) {
4320
+ if (typeof value !== "object" || value === null) return null;
4321
+ const payload = value;
4322
+ if (typeof payload.userId !== "string") return null;
4323
+ return {
4324
+ userId: payload.userId,
4325
+ email: typeof payload.email === "string" ? payload.email : void 0,
4326
+ fullName: typeof payload.fullName === "string" ? payload.fullName : void 0,
4327
+ identityToken: typeof payload.identityToken === "string" ? payload.identityToken : void 0,
4328
+ authorizationCode: typeof payload.authorizationCode === "string" ? payload.authorizationCode : void 0,
4329
+ provider
4330
+ };
4331
+ }
3137
4332
  function useAppleSignIn() {
3138
- const user = (0, import_runtime_core50.ref)(null);
3139
- const isAuthenticated = (0, import_runtime_core50.ref)(false);
3140
- const error = (0, import_runtime_core50.ref)(null);
4333
+ const user = (0, import_runtime_core56.ref)(null);
4334
+ const isAuthenticated = (0, import_runtime_core56.ref)(false);
4335
+ const error = (0, import_runtime_core56.ref)(null);
3141
4336
  const cleanups = [];
3142
4337
  const unsubscribe = NativeBridge.onGlobalEvent("auth:appleCredentialRevoked", () => {
3143
4338
  user.value = null;
@@ -3145,8 +4340,9 @@ function useAppleSignIn() {
3145
4340
  });
3146
4341
  cleanups.push(unsubscribe);
3147
4342
  NativeBridge.invokeNativeModule("SocialAuth", "getCurrentUser", ["apple"]).then((result) => {
3148
- if (result && result.userId) {
3149
- user.value = { ...result, provider: "apple" };
4343
+ const currentUser = normalizeSocialUser(result, "apple");
4344
+ if (currentUser) {
4345
+ user.value = currentUser;
3150
4346
  isAuthenticated.value = true;
3151
4347
  }
3152
4348
  }).catch(() => {
@@ -3155,12 +4351,15 @@ function useAppleSignIn() {
3155
4351
  error.value = null;
3156
4352
  try {
3157
4353
  const result = await NativeBridge.invokeNativeModule("SocialAuth", "signInWithApple");
3158
- const socialUser = { ...result, provider: "apple" };
4354
+ const socialUser = normalizeSocialUser(result, "apple");
4355
+ if (!socialUser) {
4356
+ throw new Error("Invalid Apple Sign In response.");
4357
+ }
3159
4358
  user.value = socialUser;
3160
4359
  isAuthenticated.value = true;
3161
4360
  return { success: true, user: socialUser };
3162
4361
  } catch (err) {
3163
- const message = String(err);
4362
+ const message = getErrorMessage2(err);
3164
4363
  error.value = message;
3165
4364
  return { success: false, error: message };
3166
4365
  }
@@ -3172,10 +4371,10 @@ function useAppleSignIn() {
3172
4371
  user.value = null;
3173
4372
  isAuthenticated.value = false;
3174
4373
  } catch (err) {
3175
- error.value = String(err);
4374
+ error.value = getErrorMessage2(err);
3176
4375
  }
3177
4376
  }
3178
- (0, import_runtime_core50.onUnmounted)(() => {
4377
+ (0, import_runtime_core56.onUnmounted)(() => {
3179
4378
  cleanups.forEach((fn) => fn());
3180
4379
  cleanups.length = 0;
3181
4380
  });
@@ -3183,15 +4382,37 @@ function useAppleSignIn() {
3183
4382
  }
3184
4383
 
3185
4384
  // src/composables/useGoogleSignIn.ts
3186
- var import_runtime_core51 = require("@vue/runtime-core");
4385
+ var import_runtime_core57 = require("@vue/runtime-core");
4386
+ function getErrorMessage3(error) {
4387
+ if (error instanceof Error) return error.message;
4388
+ if (typeof error === "object" && error !== null && "message" in error) {
4389
+ const message = error.message;
4390
+ if (typeof message === "string") return message;
4391
+ }
4392
+ return String(error);
4393
+ }
4394
+ function normalizeSocialUser2(value) {
4395
+ if (typeof value !== "object" || value === null) return null;
4396
+ const payload = value;
4397
+ if (typeof payload.userId !== "string") return null;
4398
+ return {
4399
+ userId: payload.userId,
4400
+ email: typeof payload.email === "string" ? payload.email : void 0,
4401
+ fullName: typeof payload.fullName === "string" ? payload.fullName : void 0,
4402
+ identityToken: typeof payload.identityToken === "string" ? payload.identityToken : void 0,
4403
+ authorizationCode: typeof payload.authorizationCode === "string" ? payload.authorizationCode : void 0,
4404
+ provider: "google"
4405
+ };
4406
+ }
3187
4407
  function useGoogleSignIn(clientId) {
3188
- const user = (0, import_runtime_core51.ref)(null);
3189
- const isAuthenticated = (0, import_runtime_core51.ref)(false);
3190
- const error = (0, import_runtime_core51.ref)(null);
4408
+ const user = (0, import_runtime_core57.ref)(null);
4409
+ const isAuthenticated = (0, import_runtime_core57.ref)(false);
4410
+ const error = (0, import_runtime_core57.ref)(null);
3191
4411
  const cleanups = [];
3192
4412
  NativeBridge.invokeNativeModule("SocialAuth", "getCurrentUser", ["google"]).then((result) => {
3193
- if (result && result.userId) {
3194
- user.value = { ...result, provider: "google" };
4413
+ const currentUser = normalizeSocialUser2(result);
4414
+ if (currentUser) {
4415
+ user.value = currentUser;
3195
4416
  isAuthenticated.value = true;
3196
4417
  }
3197
4418
  }).catch(() => {
@@ -3200,12 +4421,15 @@ function useGoogleSignIn(clientId) {
3200
4421
  error.value = null;
3201
4422
  try {
3202
4423
  const result = await NativeBridge.invokeNativeModule("SocialAuth", "signInWithGoogle", [clientId]);
3203
- const socialUser = { ...result, provider: "google" };
4424
+ const socialUser = normalizeSocialUser2(result);
4425
+ if (!socialUser) {
4426
+ throw new Error("Invalid Google Sign In response.");
4427
+ }
3204
4428
  user.value = socialUser;
3205
4429
  isAuthenticated.value = true;
3206
4430
  return { success: true, user: socialUser };
3207
4431
  } catch (err) {
3208
- const message = String(err);
4432
+ const message = getErrorMessage3(err);
3209
4433
  error.value = message;
3210
4434
  return { success: false, error: message };
3211
4435
  }
@@ -3217,10 +4441,10 @@ function useGoogleSignIn(clientId) {
3217
4441
  user.value = null;
3218
4442
  isAuthenticated.value = false;
3219
4443
  } catch (err) {
3220
- error.value = String(err);
4444
+ error.value = getErrorMessage3(err);
3221
4445
  }
3222
4446
  }
3223
- (0, import_runtime_core51.onUnmounted)(() => {
4447
+ (0, import_runtime_core57.onUnmounted)(() => {
3224
4448
  cleanups.forEach((fn) => fn());
3225
4449
  cleanups.length = 0;
3226
4450
  });
@@ -3228,17 +4452,17 @@ function useGoogleSignIn(clientId) {
3228
4452
  }
3229
4453
 
3230
4454
  // src/composables/useBackgroundTask.ts
3231
- var import_runtime_core52 = require("@vue/runtime-core");
4455
+ var import_runtime_core58 = require("@vue/runtime-core");
3232
4456
  function useBackgroundTask() {
3233
4457
  const taskHandlers = /* @__PURE__ */ new Map();
3234
- const defaultHandler = (0, import_runtime_core52.ref)(null);
4458
+ const defaultHandler = (0, import_runtime_core58.ref)(null);
3235
4459
  const unsubscribe = NativeBridge.onGlobalEvent("background:taskExecute", (payload) => {
3236
4460
  const handler = taskHandlers.get(payload.taskId) || defaultHandler.value;
3237
4461
  if (handler) {
3238
4462
  handler(payload.taskId);
3239
4463
  }
3240
4464
  });
3241
- (0, import_runtime_core52.onUnmounted)(unsubscribe);
4465
+ (0, import_runtime_core58.onUnmounted)(unsubscribe);
3242
4466
  function registerTask(taskId) {
3243
4467
  return NativeBridge.invokeNativeModule("BackgroundTask", "registerTask", [taskId]).then(() => void 0);
3244
4468
  }
@@ -3277,20 +4501,28 @@ function useBackgroundTask() {
3277
4501
  }
3278
4502
 
3279
4503
  // src/composables/useOTAUpdate.ts
3280
- var import_runtime_core53 = require("@vue/runtime-core");
4504
+ var import_runtime_core59 = require("@vue/runtime-core");
4505
+ function getErrorMessage4(error) {
4506
+ if (error instanceof Error) return error.message;
4507
+ if (typeof error === "object" && error !== null && "message" in error) {
4508
+ const message = error.message;
4509
+ if (typeof message === "string") return message;
4510
+ }
4511
+ return String(error);
4512
+ }
3281
4513
  function useOTAUpdate(serverUrl) {
3282
- const currentVersion = (0, import_runtime_core53.ref)("embedded");
3283
- const availableVersion = (0, import_runtime_core53.ref)(null);
3284
- const downloadProgress = (0, import_runtime_core53.ref)(0);
3285
- const isChecking = (0, import_runtime_core53.ref)(false);
3286
- const isDownloading = (0, import_runtime_core53.ref)(false);
3287
- const status = (0, import_runtime_core53.ref)("idle");
3288
- const error = (0, import_runtime_core53.ref)(null);
4514
+ const currentVersion = (0, import_runtime_core59.ref)("embedded");
4515
+ const availableVersion = (0, import_runtime_core59.ref)(null);
4516
+ const downloadProgress = (0, import_runtime_core59.ref)(0);
4517
+ const isChecking = (0, import_runtime_core59.ref)(false);
4518
+ const isDownloading = (0, import_runtime_core59.ref)(false);
4519
+ const status = (0, import_runtime_core59.ref)("idle");
4520
+ const error = (0, import_runtime_core59.ref)(null);
3289
4521
  let lastUpdateInfo = null;
3290
4522
  const unsubscribe = NativeBridge.onGlobalEvent("ota:downloadProgress", (payload) => {
3291
4523
  downloadProgress.value = payload.progress;
3292
4524
  });
3293
- (0, import_runtime_core53.onUnmounted)(unsubscribe);
4525
+ (0, import_runtime_core59.onUnmounted)(unsubscribe);
3294
4526
  NativeBridge.invokeNativeModule("OTA", "getCurrentVersion", []).then((info) => {
3295
4527
  currentVersion.value = info.version;
3296
4528
  }).catch(() => {
@@ -3310,7 +4542,7 @@ function useOTAUpdate(serverUrl) {
3310
4542
  status.value = info.updateAvailable ? "idle" : "idle";
3311
4543
  return info;
3312
4544
  } catch (err) {
3313
- error.value = err?.message || String(err);
4545
+ error.value = getErrorMessage4(err);
3314
4546
  status.value = "error";
3315
4547
  throw err;
3316
4548
  } finally {
@@ -3336,7 +4568,7 @@ function useOTAUpdate(serverUrl) {
3336
4568
  } catch (err) {
3337
4569
  await NativeBridge.invokeNativeModule("OTA", "cleanupPartialDownload", []).catch(() => {
3338
4570
  });
3339
- error.value = err?.message || String(err);
4571
+ error.value = getErrorMessage4(err);
3340
4572
  status.value = "error";
3341
4573
  throw err;
3342
4574
  } finally {
@@ -3352,7 +4584,7 @@ function useOTAUpdate(serverUrl) {
3352
4584
  await NativeBridge.invokeNativeModule("OTA", "verifyBundle", []);
3353
4585
  } catch (err) {
3354
4586
  status.value = "error";
3355
- error.value = "Bundle verification failed: " + (err?.message || String(err));
4587
+ error.value = "Bundle verification failed: " + getErrorMessage4(err);
3356
4588
  throw err;
3357
4589
  }
3358
4590
  try {
@@ -3362,7 +4594,7 @@ function useOTAUpdate(serverUrl) {
3362
4594
  availableVersion.value = null;
3363
4595
  status.value = "idle";
3364
4596
  } catch (err) {
3365
- error.value = err?.message || String(err);
4597
+ error.value = getErrorMessage4(err);
3366
4598
  status.value = "error";
3367
4599
  throw err;
3368
4600
  }
@@ -3375,7 +4607,7 @@ function useOTAUpdate(serverUrl) {
3375
4607
  currentVersion.value = info.version;
3376
4608
  status.value = "idle";
3377
4609
  } catch (err) {
3378
- error.value = err?.message || String(err);
4610
+ error.value = getErrorMessage4(err);
3379
4611
  status.value = "error";
3380
4612
  throw err;
3381
4613
  }
@@ -3402,13 +4634,21 @@ function useOTAUpdate(serverUrl) {
3402
4634
  }
3403
4635
 
3404
4636
  // src/composables/useBluetooth.ts
3405
- var import_runtime_core54 = require("@vue/runtime-core");
4637
+ var import_runtime_core60 = require("@vue/runtime-core");
4638
+ function getErrorMessage5(error) {
4639
+ if (error instanceof Error) return error.message;
4640
+ if (typeof error === "object" && error !== null && "message" in error) {
4641
+ const message = error.message;
4642
+ if (typeof message === "string") return message;
4643
+ }
4644
+ return String(error);
4645
+ }
3406
4646
  function useBluetooth() {
3407
- const devices = (0, import_runtime_core54.ref)([]);
3408
- const connectedDevice = (0, import_runtime_core54.ref)(null);
3409
- const isScanning = (0, import_runtime_core54.ref)(false);
3410
- const isAvailable = (0, import_runtime_core54.ref)(false);
3411
- const error = (0, import_runtime_core54.ref)(null);
4647
+ const devices = (0, import_runtime_core60.ref)([]);
4648
+ const connectedDevice = (0, import_runtime_core60.ref)(null);
4649
+ const isScanning = (0, import_runtime_core60.ref)(false);
4650
+ const isAvailable = (0, import_runtime_core60.ref)(false);
4651
+ const error = (0, import_runtime_core60.ref)(null);
3412
4652
  const cleanups = [];
3413
4653
  NativeBridge.invokeNativeModule("Bluetooth", "getState").then((state) => {
3414
4654
  isAvailable.value = state === "poweredOn";
@@ -3447,7 +4687,7 @@ function useBluetooth() {
3447
4687
  try {
3448
4688
  await NativeBridge.invokeNativeModule("Bluetooth", "startScan", [serviceUUIDs]);
3449
4689
  } catch (e) {
3450
- error.value = e?.message || String(e);
4690
+ error.value = getErrorMessage5(e);
3451
4691
  isScanning.value = false;
3452
4692
  }
3453
4693
  }
@@ -3487,7 +4727,7 @@ function useBluetooth() {
3487
4727
  ]);
3488
4728
  };
3489
4729
  }
3490
- (0, import_runtime_core54.onUnmounted)(() => {
4730
+ (0, import_runtime_core60.onUnmounted)(() => {
3491
4731
  if (isScanning.value) {
3492
4732
  NativeBridge.invokeNativeModule("Bluetooth", "stopScan").catch(() => {
3493
4733
  });
@@ -3512,17 +4752,25 @@ function useBluetooth() {
3512
4752
  }
3513
4753
 
3514
4754
  // src/composables/useCalendar.ts
3515
- var import_runtime_core55 = require("@vue/runtime-core");
4755
+ var import_runtime_core61 = require("@vue/runtime-core");
4756
+ function getErrorMessage6(error) {
4757
+ if (error instanceof Error) return error.message;
4758
+ if (typeof error === "object" && error !== null && "message" in error) {
4759
+ const message = error.message;
4760
+ if (typeof message === "string") return message;
4761
+ }
4762
+ return String(error);
4763
+ }
3516
4764
  function useCalendar() {
3517
- const hasAccess = (0, import_runtime_core55.ref)(false);
3518
- const error = (0, import_runtime_core55.ref)(null);
4765
+ const hasAccess = (0, import_runtime_core61.ref)(false);
4766
+ const error = (0, import_runtime_core61.ref)(null);
3519
4767
  async function requestAccess() {
3520
4768
  try {
3521
4769
  const result = await NativeBridge.invokeNativeModule("Calendar", "requestAccess");
3522
4770
  hasAccess.value = result.granted;
3523
4771
  return result.granted;
3524
4772
  } catch (e) {
3525
- error.value = e?.message || String(e);
4773
+ error.value = getErrorMessage6(e);
3526
4774
  return false;
3527
4775
  }
3528
4776
  }
@@ -3548,17 +4796,25 @@ function useCalendar() {
3548
4796
  }
3549
4797
 
3550
4798
  // src/composables/useContacts.ts
3551
- var import_runtime_core56 = require("@vue/runtime-core");
4799
+ var import_runtime_core62 = require("@vue/runtime-core");
4800
+ function getErrorMessage7(error) {
4801
+ if (error instanceof Error) return error.message;
4802
+ if (typeof error === "object" && error !== null && "message" in error) {
4803
+ const message = error.message;
4804
+ if (typeof message === "string") return message;
4805
+ }
4806
+ return String(error);
4807
+ }
3552
4808
  function useContacts() {
3553
- const hasAccess = (0, import_runtime_core56.ref)(false);
3554
- const error = (0, import_runtime_core56.ref)(null);
4809
+ const hasAccess = (0, import_runtime_core62.ref)(false);
4810
+ const error = (0, import_runtime_core62.ref)(null);
3555
4811
  async function requestAccess() {
3556
4812
  try {
3557
4813
  const result = await NativeBridge.invokeNativeModule("Contacts", "requestAccess");
3558
4814
  hasAccess.value = result.granted;
3559
4815
  return result.granted;
3560
4816
  } catch (e) {
3561
- error.value = e?.message || String(e);
4817
+ error.value = getErrorMessage7(e);
3562
4818
  return false;
3563
4819
  }
3564
4820
  }
@@ -3577,39 +4833,494 @@ function useContacts() {
3577
4833
  return { requestAccess, getContacts, getContact, createContact, deleteContact, hasAccess, error };
3578
4834
  }
3579
4835
 
4836
+ // src/composables/useWindow.ts
4837
+ function useWindow() {
4838
+ const { isMacOS } = usePlatform();
4839
+ async function setTitle(title) {
4840
+ if (!isMacOS) return;
4841
+ await NativeBridge.invokeNativeModule("Window", "setTitle", [title]);
4842
+ }
4843
+ async function setSize(width, height) {
4844
+ if (!isMacOS) return;
4845
+ await NativeBridge.invokeNativeModule("Window", "setSize", [width, height]);
4846
+ }
4847
+ async function center() {
4848
+ if (!isMacOS) return;
4849
+ await NativeBridge.invokeNativeModule("Window", "center", []);
4850
+ }
4851
+ async function minimize() {
4852
+ if (!isMacOS) return;
4853
+ await NativeBridge.invokeNativeModule("Window", "minimize", []);
4854
+ }
4855
+ async function toggleFullScreen() {
4856
+ if (!isMacOS) return;
4857
+ await NativeBridge.invokeNativeModule("Window", "toggleFullScreen", []);
4858
+ }
4859
+ async function close() {
4860
+ if (!isMacOS) return;
4861
+ await NativeBridge.invokeNativeModule("Window", "close", []);
4862
+ }
4863
+ async function getInfo() {
4864
+ if (!isMacOS) return null;
4865
+ return await NativeBridge.invokeNativeModule("Window", "getInfo", []);
4866
+ }
4867
+ return { setTitle, setSize, center, minimize, toggleFullScreen, close, getInfo };
4868
+ }
4869
+
4870
+ // src/composables/useMenu.ts
4871
+ function useMenu() {
4872
+ const { isMacOS } = usePlatform();
4873
+ async function setAppMenu(sections) {
4874
+ if (!isMacOS) return;
4875
+ await NativeBridge.invokeNativeModule("Menu", "setAppMenu", [sections]);
4876
+ }
4877
+ async function showContextMenu(items) {
4878
+ if (!isMacOS) return;
4879
+ await NativeBridge.invokeNativeModule("Menu", "showContextMenu", [items]);
4880
+ }
4881
+ function onMenuItemClick(callback) {
4882
+ if (!isMacOS) return () => {
4883
+ };
4884
+ return NativeBridge.onGlobalEvent("menu:itemClick", (payload) => {
4885
+ callback(payload.id ?? "", payload.title ?? "");
4886
+ });
4887
+ }
4888
+ return { setAppMenu, showContextMenu, onMenuItemClick };
4889
+ }
4890
+
4891
+ // src/composables/useFileDialog.ts
4892
+ function useFileDialog() {
4893
+ const { isMacOS } = usePlatform();
4894
+ async function openFile(options) {
4895
+ if (!isMacOS) return null;
4896
+ return await NativeBridge.invokeNativeModule("FileDialog", "openFile", [options || {}]);
4897
+ }
4898
+ async function openDirectory(options) {
4899
+ if (!isMacOS) return null;
4900
+ return await NativeBridge.invokeNativeModule("FileDialog", "openDirectory", [options || {}]);
4901
+ }
4902
+ async function saveFile(options) {
4903
+ if (!isMacOS) return null;
4904
+ return await NativeBridge.invokeNativeModule("FileDialog", "saveFile", [options || {}]);
4905
+ }
4906
+ return { openFile, openDirectory, saveFile };
4907
+ }
4908
+
4909
+ // src/composables/useDragDrop.ts
4910
+ var import_runtime_core63 = require("@vue/runtime-core");
4911
+ function useDragDrop() {
4912
+ const { isMacOS } = usePlatform();
4913
+ const isDragging = (0, import_runtime_core63.ref)(false);
4914
+ async function enableDropZone() {
4915
+ if (!isMacOS) return;
4916
+ await NativeBridge.invokeNativeModule("DragDrop", "enableDropZone", []);
4917
+ }
4918
+ function onDrop(callback) {
4919
+ if (!isMacOS) return () => {
4920
+ };
4921
+ return NativeBridge.onGlobalEvent("dragdrop:drop", (payload) => {
4922
+ const files = Array.isArray(payload.files) ? payload.files.filter((file) => typeof file === "string") : [];
4923
+ callback(files);
4924
+ });
4925
+ }
4926
+ function onDragEnter(callback) {
4927
+ if (!isMacOS) return () => {
4928
+ };
4929
+ return NativeBridge.onGlobalEvent("dragdrop:enter", () => {
4930
+ isDragging.value = true;
4931
+ callback();
4932
+ });
4933
+ }
4934
+ function onDragLeave(callback) {
4935
+ if (!isMacOS) return () => {
4936
+ };
4937
+ return NativeBridge.onGlobalEvent("dragdrop:leave", () => {
4938
+ isDragging.value = false;
4939
+ callback();
4940
+ });
4941
+ }
4942
+ return { enableDropZone, onDrop, onDragEnter, onDragLeave, isDragging: (0, import_runtime_core63.readonly)(isDragging) };
4943
+ }
4944
+
4945
+ // src/composables/useTeleport.ts
4946
+ function useTeleport(target) {
4947
+ const teleport = (node) => {
4948
+ NativeBridge.teleportTo(target, node.id);
4949
+ };
4950
+ return { teleport };
4951
+ }
4952
+
4953
+ // src/composables/useGesture.ts
4954
+ var import_runtime_core64 = require("@vue/runtime-core");
4955
+ function hasViewId2(value) {
4956
+ return typeof value === "object" && value !== null && "id" in value && typeof value.id === "number";
4957
+ }
4958
+ function isGestureRef(target) {
4959
+ return typeof target === "object" && target !== null && "value" in target;
4960
+ }
4961
+ function resolveViewId2(target) {
4962
+ if (typeof target === "number") return target;
4963
+ if (isGestureRef(target)) {
4964
+ const val = target.value;
4965
+ if (hasViewId2(val)) return val.id;
4966
+ throw new Error("[useGesture] Target ref has no .value.id \u2014 is the ref attached to a component?");
4967
+ }
4968
+ if (hasViewId2(target)) return target.id;
4969
+ throw new Error("[useGesture] Invalid target. Pass a number, template ref, or NativeNode.");
4970
+ }
4971
+ var GestureManager = class {
4972
+ constructor() {
4973
+ this.nodeId = null;
4974
+ this.handlers = /* @__PURE__ */ new Map();
4975
+ this.disposables = [];
4976
+ }
4977
+ attach(target) {
4978
+ this.nodeId = resolveViewId2(target);
4979
+ }
4980
+ on(event, callback, config) {
4981
+ if (!this.nodeId) {
4982
+ console.warn("[useGesture] Cannot add listener: not attached to a view. Call attach() first or use a ref.");
4983
+ return () => {
4984
+ };
4985
+ }
4986
+ if (!this.handlers.has(event)) {
4987
+ this.handlers.set(event, /* @__PURE__ */ new Set());
4988
+ }
4989
+ this.handlers.get(event).add(callback);
4990
+ NativeBridge.addEventListener(this.nodeId, event, (payload) => {
4991
+ if (config?.enabled === false) return;
4992
+ callback(payload);
4993
+ });
4994
+ const dispose = () => {
4995
+ this.handlers.get(event)?.delete(callback);
4996
+ if (this.nodeId) {
4997
+ NativeBridge.removeEventListener(this.nodeId, event);
4998
+ }
4999
+ };
5000
+ this.disposables.push(dispose);
5001
+ return dispose;
5002
+ }
5003
+ detach() {
5004
+ for (const dispose of this.disposables) {
5005
+ dispose();
5006
+ }
5007
+ this.disposables = [];
5008
+ this.handlers.clear();
5009
+ this.nodeId = null;
5010
+ }
5011
+ };
5012
+ function useGesture(target, options = {}) {
5013
+ const pan = (0, import_runtime_core64.ref)(null);
5014
+ const pinch = (0, import_runtime_core64.ref)(null);
5015
+ const rotate = (0, import_runtime_core64.ref)(null);
5016
+ const swipeLeft = (0, import_runtime_core64.ref)(null);
5017
+ const swipeRight = (0, import_runtime_core64.ref)(null);
5018
+ const swipeUp = (0, import_runtime_core64.ref)(null);
5019
+ const swipeDown = (0, import_runtime_core64.ref)(null);
5020
+ const press = (0, import_runtime_core64.ref)(null);
5021
+ const longPress = (0, import_runtime_core64.ref)(null);
5022
+ const doubleTap = (0, import_runtime_core64.ref)(null);
5023
+ const forceTouch = (0, import_runtime_core64.ref)(null);
5024
+ const hover = (0, import_runtime_core64.ref)(null);
5025
+ const gestureState = (0, import_runtime_core64.ref)(null);
5026
+ const activeGesture = (0, import_runtime_core64.ref)(null);
5027
+ const isGesturing = (0, import_runtime_core64.ref)(false);
5028
+ const manager = new GestureManager();
5029
+ const cleanupFns = [];
5030
+ function attach(t) {
5031
+ manager.attach(t);
5032
+ setupListeners();
5033
+ }
5034
+ function detach() {
5035
+ for (const fn of cleanupFns) fn();
5036
+ cleanupFns.length = 0;
5037
+ manager.detach();
5038
+ pan.value = null;
5039
+ pinch.value = null;
5040
+ rotate.value = null;
5041
+ swipeLeft.value = null;
5042
+ swipeRight.value = null;
5043
+ swipeUp.value = null;
5044
+ swipeDown.value = null;
5045
+ press.value = null;
5046
+ longPress.value = null;
5047
+ doubleTap.value = null;
5048
+ forceTouch.value = null;
5049
+ hover.value = null;
5050
+ gestureState.value = null;
5051
+ activeGesture.value = null;
5052
+ isGesturing.value = false;
5053
+ }
5054
+ function normalizeConfig(opt) {
5055
+ return typeof opt === "boolean" ? { enabled: opt } : opt ?? {};
5056
+ }
5057
+ function on(event, callback) {
5058
+ return manager.on(event, callback);
5059
+ }
5060
+ function setupListeners() {
5061
+ if (options.pan) {
5062
+ const cfg = normalizeConfig(options.pan);
5063
+ const dispose = manager.on("pan", (state) => {
5064
+ pan.value = state;
5065
+ gestureState.value = state;
5066
+ activeGesture.value = "pan";
5067
+ isGesturing.value = state.state === "began" || state.state === "changed";
5068
+ }, cfg);
5069
+ cleanupFns.push(dispose);
5070
+ }
5071
+ if (options.pinch) {
5072
+ const cfg = normalizeConfig(options.pinch);
5073
+ const dispose = manager.on("pinch", (state) => {
5074
+ pinch.value = state;
5075
+ gestureState.value = state;
5076
+ activeGesture.value = "pinch";
5077
+ isGesturing.value = state.state === "began" || state.state === "changed";
5078
+ }, cfg);
5079
+ cleanupFns.push(dispose);
5080
+ }
5081
+ if (options.rotate) {
5082
+ const cfg = normalizeConfig(options.rotate);
5083
+ const dispose = manager.on("rotate", (state) => {
5084
+ rotate.value = state;
5085
+ gestureState.value = state;
5086
+ activeGesture.value = "rotate";
5087
+ isGesturing.value = state.state === "began" || state.state === "changed";
5088
+ }, cfg);
5089
+ cleanupFns.push(dispose);
5090
+ }
5091
+ if (options.swipeLeft) {
5092
+ const cfg = normalizeConfig(options.swipeLeft);
5093
+ const dispose = manager.on("swipeLeft", (state) => {
5094
+ swipeLeft.value = state;
5095
+ gestureState.value = state;
5096
+ activeGesture.value = "swipeLeft";
5097
+ isGesturing.value = false;
5098
+ }, cfg);
5099
+ cleanupFns.push(dispose);
5100
+ }
5101
+ if (options.swipeRight) {
5102
+ const cfg = normalizeConfig(options.swipeRight);
5103
+ const dispose = manager.on("swipeRight", (state) => {
5104
+ swipeRight.value = state;
5105
+ gestureState.value = state;
5106
+ activeGesture.value = "swipeRight";
5107
+ isGesturing.value = false;
5108
+ }, cfg);
5109
+ cleanupFns.push(dispose);
5110
+ }
5111
+ if (options.swipeUp) {
5112
+ const cfg = normalizeConfig(options.swipeUp);
5113
+ const dispose = manager.on("swipeUp", (state) => {
5114
+ swipeUp.value = state;
5115
+ gestureState.value = state;
5116
+ activeGesture.value = "swipeUp";
5117
+ isGesturing.value = false;
5118
+ }, cfg);
5119
+ cleanupFns.push(dispose);
5120
+ }
5121
+ if (options.swipeDown) {
5122
+ const cfg = normalizeConfig(options.swipeDown);
5123
+ const dispose = manager.on("swipeDown", (state) => {
5124
+ swipeDown.value = state;
5125
+ gestureState.value = state;
5126
+ activeGesture.value = "swipeDown";
5127
+ isGesturing.value = false;
5128
+ }, cfg);
5129
+ cleanupFns.push(dispose);
5130
+ }
5131
+ if (options.press) {
5132
+ const cfg = normalizeConfig(options.press);
5133
+ const dispose = manager.on("press", (state) => {
5134
+ press.value = state;
5135
+ gestureState.value = state;
5136
+ activeGesture.value = "press";
5137
+ isGesturing.value = false;
5138
+ }, cfg);
5139
+ cleanupFns.push(dispose);
5140
+ }
5141
+ if (options.longPress) {
5142
+ const cfg = normalizeConfig(options.longPress);
5143
+ const dispose = manager.on("longPress", (state) => {
5144
+ longPress.value = state;
5145
+ gestureState.value = state;
5146
+ activeGesture.value = "longPress";
5147
+ isGesturing.value = false;
5148
+ }, cfg);
5149
+ cleanupFns.push(dispose);
5150
+ }
5151
+ if (options.doubleTap) {
5152
+ const cfg = normalizeConfig(options.doubleTap);
5153
+ const dispose = manager.on("doubleTap", (state) => {
5154
+ doubleTap.value = state;
5155
+ gestureState.value = state;
5156
+ activeGesture.value = "doubleTap";
5157
+ isGesturing.value = false;
5158
+ }, cfg);
5159
+ cleanupFns.push(dispose);
5160
+ }
5161
+ if (options.forceTouch) {
5162
+ const cfg = normalizeConfig(options.forceTouch);
5163
+ const dispose = manager.on("forceTouch", (state) => {
5164
+ forceTouch.value = state;
5165
+ gestureState.value = state;
5166
+ activeGesture.value = "forceTouch";
5167
+ isGesturing.value = state.stage > 0;
5168
+ }, cfg);
5169
+ cleanupFns.push(dispose);
5170
+ }
5171
+ if (options.hover) {
5172
+ const cfg = normalizeConfig(options.hover);
5173
+ const dispose = manager.on("hover", (state) => {
5174
+ hover.value = state;
5175
+ gestureState.value = state;
5176
+ activeGesture.value = "hover";
5177
+ isGesturing.value = state.state !== "exited";
5178
+ }, cfg);
5179
+ cleanupFns.push(dispose);
5180
+ }
5181
+ }
5182
+ (0, import_runtime_core64.onUnmounted)(() => {
5183
+ detach();
5184
+ });
5185
+ if (target !== void 0) {
5186
+ attach(target);
5187
+ }
5188
+ return {
5189
+ pan,
5190
+ pinch,
5191
+ rotate,
5192
+ swipeLeft,
5193
+ swipeRight,
5194
+ swipeUp,
5195
+ swipeDown,
5196
+ press,
5197
+ longPress,
5198
+ doubleTap,
5199
+ forceTouch,
5200
+ hover,
5201
+ gestureState,
5202
+ activeGesture,
5203
+ isGesturing,
5204
+ attach,
5205
+ detach,
5206
+ on
5207
+ };
5208
+ }
5209
+ function useComposedGestures(target, options = {}) {
5210
+ const pan = (0, import_runtime_core64.ref)(null);
5211
+ const pinch = (0, import_runtime_core64.ref)(null);
5212
+ const rotate = (0, import_runtime_core64.ref)(null);
5213
+ const gestureState = (0, import_runtime_core64.ref)(null);
5214
+ const activeGesture = (0, import_runtime_core64.ref)(null);
5215
+ const isGesturing = (0, import_runtime_core64.ref)(false);
5216
+ const isPinchingAndRotating = (0, import_runtime_core64.ref)(false);
5217
+ const isPanningAndPinching = (0, import_runtime_core64.ref)(false);
5218
+ const manager = new GestureManager();
5219
+ manager.attach(target);
5220
+ const panConfig = typeof options.pan === "object" ? options.pan : {};
5221
+ const pinchConfig = typeof options.pinch === "object" ? options.pinch : {};
5222
+ const rotateConfig = typeof options.rotate === "object" ? options.rotate : {};
5223
+ const cleanupFns = [];
5224
+ if (options.pan !== false) {
5225
+ cleanupFns.push(manager.on("pan", (state) => {
5226
+ pan.value = state;
5227
+ gestureState.value = state;
5228
+ activeGesture.value = "pan";
5229
+ isGesturing.value = state.state === "began" || state.state === "changed";
5230
+ isPanningAndPinching.value = pinch.value !== null && (state.state === "began" || state.state === "changed");
5231
+ }, panConfig));
5232
+ }
5233
+ if (options.pinch !== false) {
5234
+ cleanupFns.push(manager.on("pinch", (state) => {
5235
+ pinch.value = state;
5236
+ gestureState.value = state;
5237
+ activeGesture.value = "pinch";
5238
+ isGesturing.value = state.state === "began" || state.state === "changed";
5239
+ isPinchingAndRotating.value = rotate.value !== null && (state.state === "began" || state.state === "changed");
5240
+ isPanningAndPinching.value = pan.value !== null && (state.state === "began" || state.state === "changed");
5241
+ }, pinchConfig));
5242
+ }
5243
+ if (options.rotate !== false) {
5244
+ cleanupFns.push(manager.on("rotate", (state) => {
5245
+ rotate.value = state;
5246
+ gestureState.value = state;
5247
+ activeGesture.value = "rotate";
5248
+ isGesturing.value = state.state === "began" || state.state === "changed";
5249
+ isPinchingAndRotating.value = pinch.value !== null && (state.state === "began" || state.state === "changed");
5250
+ }, rotateConfig));
5251
+ }
5252
+ (0, import_runtime_core64.onUnmounted)(() => {
5253
+ for (const fn of cleanupFns) fn();
5254
+ manager.detach();
5255
+ });
5256
+ return {
5257
+ pan,
5258
+ pinch,
5259
+ rotate,
5260
+ gestureState,
5261
+ activeGesture,
5262
+ isGesturing,
5263
+ isPinchingAndRotating,
5264
+ isPanningAndPinching
5265
+ };
5266
+ }
5267
+
5268
+ // src/theme.ts
5269
+ var import_runtime_core65 = require("@vue/runtime-core");
5270
+ function createTheme(definition) {
5271
+ const key = /* @__PURE__ */ Symbol("vue-native-theme");
5272
+ const ThemeProvider = (0, import_runtime_core65.defineComponent)({
5273
+ name: "ThemeProvider",
5274
+ props: {
5275
+ initialColorScheme: {
5276
+ type: String,
5277
+ default: "light"
5278
+ }
5279
+ },
5280
+ setup(props, { slots }) {
5281
+ const colorScheme = (0, import_runtime_core65.ref)(props.initialColorScheme);
5282
+ const theme = (0, import_runtime_core65.computed)(() => {
5283
+ return colorScheme.value === "dark" ? definition.dark : definition.light;
5284
+ });
5285
+ const ctx = {
5286
+ theme,
5287
+ colorScheme,
5288
+ toggleColorScheme: () => {
5289
+ colorScheme.value = colorScheme.value === "light" ? "dark" : "light";
5290
+ },
5291
+ setColorScheme: (scheme) => {
5292
+ colorScheme.value = scheme;
5293
+ }
5294
+ };
5295
+ (0, import_runtime_core65.provide)(key, ctx);
5296
+ return () => slots.default?.();
5297
+ }
5298
+ });
5299
+ function useTheme() {
5300
+ const ctx = (0, import_runtime_core65.inject)(key);
5301
+ if (!ctx) {
5302
+ throw new Error(
5303
+ "[Vue Native] useTheme() was called outside of a <ThemeProvider>. Wrap your app root with <ThemeProvider> to provide theme context."
5304
+ );
5305
+ }
5306
+ return ctx;
5307
+ }
5308
+ return { ThemeProvider, useTheme };
5309
+ }
5310
+ function createDynamicStyleSheet(theme, factory) {
5311
+ return (0, import_runtime_core65.computed)(() => createStyleSheet(factory(theme.value)));
5312
+ }
5313
+
3580
5314
  // src/index.ts
3581
5315
  function createApp(rootComponent, rootProps) {
3582
5316
  const app = baseCreateApp(rootComponent, rootProps);
3583
- app.component("VView", VView);
3584
- app.component("VText", VText);
3585
- app.component("VButton", VButton);
3586
- app.component("VInput", VInput);
3587
- app.component("VSwitch", VSwitch);
3588
- app.component("VActivityIndicator", VActivityIndicator);
3589
- app.component("VScrollView", VScrollView);
3590
- app.component("VImage", VImage);
3591
- app.component("VKeyboardAvoiding", VKeyboardAvoiding);
3592
- app.component("VSafeArea", VSafeArea);
3593
- app.component("VSlider", VSlider);
3594
- app.component("VList", VList);
3595
- app.component("VModal", VModal);
3596
- app.component("VAlertDialog", VAlertDialog);
3597
- app.component("VStatusBar", VStatusBar);
3598
- app.component("VWebView", VWebView);
3599
- app.component("VProgressBar", VProgressBar);
3600
- app.component("VPicker", VPicker);
3601
- app.component("VSegmentedControl", VSegmentedControl);
3602
- app.component("VActionSheet", VActionSheet);
3603
- app.component("VRefreshControl", VRefreshControl);
3604
- app.component("VPressable", VPressable);
3605
- app.component("VSectionList", VSectionList);
3606
- app.component("VCheckbox", VCheckbox);
3607
- app.component("VRadio", VRadio);
3608
- app.component("VDropdown", VDropdown);
3609
- app.component("VVideo", VVideo);
5317
+ for (const [name, component] of Object.entries(builtInComponents)) {
5318
+ app.component(name, component);
5319
+ }
5320
+ app.component("VDrawer.Item", VDrawerItem);
5321
+ app.component("VDrawer.Section", VDrawerSection);
3610
5322
  app.component("ErrorBoundary", ErrorBoundary);
3611
5323
  app.component("VErrorBoundary", ErrorBoundary);
3612
- app.directive("show", vShow);
3613
5324
  app.config.errorHandler = (err, instance, info) => {
3614
5325
  const error = err instanceof Error ? err : new Error(String(err));
3615
5326
  const componentName = instance?.$options?.name || instance?.$.type?.name || "Anonymous";
@@ -3635,7 +5346,7 @@ function createApp(rootComponent, rootProps) {
3635
5346
  const root = createNativeNode("__ROOT__");
3636
5347
  NativeBridge.createNode(root.id, "__ROOT__");
3637
5348
  NativeBridge.setRootView(root.id);
3638
- const vnode = (0, import_runtime_core57.createVNode)(rootComponent, rootProps);
5349
+ const vnode = (0, import_runtime_core66.createVNode)(rootComponent, rootProps);
3639
5350
  vnode.appContext = app._context;
3640
5351
  render(vnode, root);
3641
5352
  return root;
@@ -3651,7 +5362,11 @@ function createApp(rootComponent, rootProps) {
3651
5362
  VAlertDialog,
3652
5363
  VButton,
3653
5364
  VCheckbox,
5365
+ VDrawer,
5366
+ VDrawerItem,
5367
+ VDrawerSection,
3654
5368
  VDropdown,
5369
+ VFlatList,
3655
5370
  VImage,
3656
5371
  VInput,
3657
5372
  VKeyboardAvoiding,
@@ -3669,16 +5384,20 @@ function createApp(rootComponent, rootProps) {
3669
5384
  VSlider,
3670
5385
  VStatusBar,
3671
5386
  VSwitch,
5387
+ VTabBar,
3672
5388
  VText,
3673
5389
  VVideo,
3674
5390
  VView,
3675
5391
  VWebView,
5392
+ builtInComponents,
3676
5393
  clearSharedElementRegistry,
3677
5394
  createApp,
3678
5395
  createCommentNode,
5396
+ createDynamicStyleSheet,
3679
5397
  createNativeNode,
3680
5398
  createStyleSheet,
3681
5399
  createTextNode,
5400
+ createTheme,
3682
5401
  getRegisteredSharedElements,
3683
5402
  getSharedElementViewId,
3684
5403
  measureViewFrame,
@@ -3698,12 +5417,16 @@ function createApp(rootComponent, rootProps) {
3698
5417
  useCamera,
3699
5418
  useClipboard,
3700
5419
  useColorScheme,
5420
+ useComposedGestures,
3701
5421
  useContacts,
3702
5422
  useDatabase,
3703
5423
  useDeviceInfo,
3704
5424
  useDimensions,
5425
+ useDragDrop,
5426
+ useFileDialog,
3705
5427
  useFileSystem,
3706
5428
  useGeolocation,
5429
+ useGesture,
3707
5430
  useGoogleSignIn,
3708
5431
  useGyroscope,
3709
5432
  useHaptics,
@@ -3712,6 +5435,7 @@ function createApp(rootComponent, rootProps) {
3712
5435
  useIAP,
3713
5436
  useKeyboard,
3714
5437
  useLinking,
5438
+ useMenu,
3715
5439
  useNetwork,
3716
5440
  useNotifications,
3717
5441
  useOTAUpdate,
@@ -3721,7 +5445,10 @@ function createApp(rootComponent, rootProps) {
3721
5445
  useSecureStorage,
3722
5446
  useShare,
3723
5447
  useSharedElementTransition,
5448
+ useTeleport,
3724
5449
  useWebSocket,
5450
+ useWindow,
5451
+ vModel,
3725
5452
  vShow,
3726
5453
  validStyleProperties,
3727
5454
  ...require("@vue/runtime-core")