@thelacanians/vue-native-cli 0.4.3 → 0.4.4

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.
Files changed (172) hide show
  1. package/dist/cli.js +34 -17
  2. package/native/android/README.md +205 -0
  3. package/native/android/VueNativeCore/build.gradle.kts +100 -0
  4. package/native/android/VueNativeCore/consumer-rules.pro +12 -0
  5. package/native/android/VueNativeCore/proguard-rules.pro +33 -0
  6. package/native/android/VueNativeCore/src/main/AndroidManifest.xml +17 -0
  7. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/ErrorOverlayView.kt +94 -0
  8. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/HotReloadManager.kt +105 -0
  9. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/JSPolyfills.kt +652 -0
  10. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/JSRuntime.kt +207 -0
  11. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/NativeBridge.kt +417 -0
  12. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/ComponentRegistry.kt +76 -0
  13. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VActionSheetFactory.kt +78 -0
  14. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VActivityIndicatorFactory.kt +46 -0
  15. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VAlertDialogFactory.kt +84 -0
  16. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VButtonFactory.kt +73 -0
  17. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VCheckboxFactory.kt +93 -0
  18. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VDropdownFactory.kt +125 -0
  19. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VImageFactory.kt +75 -0
  20. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VInputFactory.kt +210 -0
  21. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VKeyboardAvoidingFactory.kt +31 -0
  22. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VListFactory.kt +183 -0
  23. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VModalFactory.kt +105 -0
  24. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VPickerFactory.kt +57 -0
  25. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VPressableFactory.kt +109 -0
  26. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VProgressBarFactory.kt +43 -0
  27. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VRadioFactory.kt +103 -0
  28. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VRefreshControlFactory.kt +73 -0
  29. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VRootFactory.kt +39 -0
  30. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSafeAreaFactory.kt +48 -0
  31. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VScrollViewFactory.kt +105 -0
  32. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSectionListFactory.kt +144 -0
  33. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSegmentedControlFactory.kt +77 -0
  34. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSliderFactory.kt +74 -0
  35. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VStatusBarFactory.kt +52 -0
  36. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSwitchFactory.kt +62 -0
  37. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VTextFactory.kt +53 -0
  38. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VVideoFactory.kt +191 -0
  39. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VViewFactory.kt +48 -0
  40. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VWebViewFactory.kt +90 -0
  41. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/NativeComponentFactory.kt +40 -0
  42. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/VTextNodeView.kt +23 -0
  43. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Helpers/GestureHelper.kt +16 -0
  44. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Helpers/TouchableView.kt +105 -0
  45. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AnimationModule.kt +292 -0
  46. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AppStateModule.kt +41 -0
  47. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AsyncStorageModule.kt +59 -0
  48. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AudioModule.kt +331 -0
  49. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/BackgroundTaskModule.kt +166 -0
  50. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/BiometryModule.kt +56 -0
  51. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/BluetoothModule.kt +302 -0
  52. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/CalendarModule.kt +198 -0
  53. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/CameraModule.kt +64 -0
  54. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/ClipboardModule.kt +36 -0
  55. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/ContactsModule.kt +288 -0
  56. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/DatabaseModule.kt +229 -0
  57. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/DeviceInfoModule.kt +39 -0
  58. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/FileSystemModule.kt +193 -0
  59. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/GeolocationModule.kt +68 -0
  60. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/HapticsModule.kt +61 -0
  61. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/HttpModule.kt +111 -0
  62. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/IAPModule.kt +302 -0
  63. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/KeyboardModule.kt +26 -0
  64. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/LinkingModule.kt +43 -0
  65. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NativeModule.kt +27 -0
  66. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NativeModuleRegistry.kt +92 -0
  67. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NetworkModule.kt +75 -0
  68. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NotificationsModule.kt +181 -0
  69. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/OTAModule.kt +255 -0
  70. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/PerformanceModule.kt +147 -0
  71. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/PermissionsModule.kt +126 -0
  72. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/SecureStorageModule.kt +51 -0
  73. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/SensorsModule.kt +134 -0
  74. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/ShareModule.kt +36 -0
  75. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/SocialAuthModule.kt +160 -0
  76. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/WebSocketModule.kt +155 -0
  77. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Styling/StyleEngine.kt +802 -0
  78. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Tags.kt +43 -0
  79. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/VueNativeActivity.kt +169 -0
  80. package/native/android/VueNativeCore/src/main/res/values/ids.xml +8 -0
  81. package/native/android/app/build.gradle.kts +45 -0
  82. package/native/android/app/proguard-rules.pro +5 -0
  83. package/native/android/app/src/main/AndroidManifest.xml +25 -0
  84. package/native/android/app/src/main/assets/.gitkeep +0 -0
  85. package/native/android/app/src/main/kotlin/com/vuenative/example/counter/MainActivity.kt +14 -0
  86. package/native/android/app/src/main/res/layout/activity_main.xml +6 -0
  87. package/native/android/app/src/main/res/values/strings.xml +3 -0
  88. package/native/android/app/src/main/res/values/themes.xml +9 -0
  89. package/native/android/app/src/main/res/xml/network_security_config.xml +8 -0
  90. package/native/android/build.gradle.kts +6 -0
  91. package/native/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  92. package/native/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  93. package/native/android/gradle.properties +4 -0
  94. package/native/android/gradlew +87 -0
  95. package/native/android/gradlew.bat +48 -0
  96. package/native/android/settings.gradle.kts +20 -0
  97. package/native/ios/VueNativeCore/Package.resolved +23 -0
  98. package/native/ios/VueNativeCore/Package.swift +32 -0
  99. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/CertificatePinning.swift +132 -0
  100. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/ErrorOverlayView.swift +92 -0
  101. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/HotReloadManager.swift +147 -0
  102. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/JSPolyfills.swift +711 -0
  103. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/JSRuntime.swift +421 -0
  104. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/NativeBridge.swift +891 -0
  105. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/VueNativeViewController.swift +88 -0
  106. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/ComponentRegistry.swift +193 -0
  107. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VActionSheetFactory.swift +91 -0
  108. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VActivityIndicatorFactory.swift +74 -0
  109. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VAlertDialogFactory.swift +150 -0
  110. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VButtonFactory.swift +93 -0
  111. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VCheckboxFactory.swift +114 -0
  112. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VDropdownFactory.swift +112 -0
  113. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VImageFactory.swift +172 -0
  114. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VInputFactory.swift +357 -0
  115. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VKeyboardAvoidingFactory.swift +99 -0
  116. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VListFactory.swift +250 -0
  117. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VModalFactory.swift +112 -0
  118. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VPickerFactory.swift +96 -0
  119. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VPressableFactory.swift +168 -0
  120. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VProgressBarFactory.swift +39 -0
  121. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VRadioFactory.swift +167 -0
  122. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VRefreshControlFactory.swift +153 -0
  123. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSafeAreaFactory.swift +56 -0
  124. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VScrollViewFactory.swift +240 -0
  125. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSectionListFactory.swift +248 -0
  126. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSegmentedControlFactory.swift +73 -0
  127. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSliderFactory.swift +63 -0
  128. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VStatusBarFactory.swift +50 -0
  129. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSwitchFactory.swift +108 -0
  130. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VTextFactory.swift +290 -0
  131. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VVideoFactory.swift +246 -0
  132. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VViewFactory.swift +157 -0
  133. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VWebViewFactory.swift +172 -0
  134. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/NativeComponentFactory.swift +53 -0
  135. package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/GestureWrapper.swift +107 -0
  136. package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/TouchableView.swift +136 -0
  137. package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/UIColor+Hex.swift +80 -0
  138. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AnimationModule.swift +291 -0
  139. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AppStateModule.swift +65 -0
  140. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AsyncStorageModule.swift +68 -0
  141. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AudioModule.swift +366 -0
  142. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/BackgroundTaskModule.swift +135 -0
  143. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/BiometryModule.swift +61 -0
  144. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/BluetoothModule.swift +387 -0
  145. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/CalendarModule.swift +161 -0
  146. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/CameraModule.swift +318 -0
  147. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/ClipboardModule.swift +33 -0
  148. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/ContactsModule.swift +173 -0
  149. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/DatabaseModule.swift +259 -0
  150. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/DeviceInfoModule.swift +34 -0
  151. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/FileSystemModule.swift +233 -0
  152. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/GeolocationModule.swift +147 -0
  153. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/HapticsModule.swift +50 -0
  154. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/IAPModule.swift +194 -0
  155. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/KeyboardModule.swift +31 -0
  156. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/LinkingModule.swift +42 -0
  157. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NativeModule.swift +28 -0
  158. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NativeModuleRegistry.swift +78 -0
  159. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NetworkModule.swift +62 -0
  160. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NotificationsModule.swift +215 -0
  161. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/OTAModule.swift +281 -0
  162. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/PerformanceModule.swift +138 -0
  163. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/PermissionsModule.swift +190 -0
  164. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SecureStorageModule.swift +118 -0
  165. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SensorsModule.swift +103 -0
  166. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/ShareModule.swift +49 -0
  167. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SocialAuthModule.swift +240 -0
  168. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/WebSocketModule.swift +213 -0
  169. package/native/ios/VueNativeCore/Sources/VueNativeCore/Resources/vue-native-placeholder.js +8 -0
  170. package/native/ios/VueNativeCore/Sources/VueNativeCore/Styling/StyleEngine.swift +885 -0
  171. package/native/ios/VueNativeCore/Tests/VueNativeCoreTests/JSRuntimeTests.swift +362 -0
  172. package/package.json +3 -2
@@ -0,0 +1,73 @@
1
+ #if canImport(UIKit)
2
+ import UIKit
3
+ import FlexLayout
4
+ import ObjectiveC
5
+
6
+ private var segOnChangeKey: UInt8 = 0
7
+ private var segTargetKey: UInt8 = 1
8
+
9
+ final class VSegmentedControlFactory: NativeComponentFactory {
10
+
11
+ func createView() -> UIView {
12
+ let seg = UISegmentedControl()
13
+ _ = seg.flex
14
+ return seg
15
+ }
16
+
17
+ func updateProp(view: UIView, key: String, value: Any?) {
18
+ guard let seg = view as? UISegmentedControl else {
19
+ StyleEngine.apply(key: key, value: value, to: view)
20
+ return
21
+ }
22
+ switch key {
23
+ case "values":
24
+ guard let items = value as? [String] else { return }
25
+ seg.removeAllSegments()
26
+ for (i, item) in items.enumerated() {
27
+ seg.insertSegment(withTitle: item, at: i, animated: false)
28
+ }
29
+ case "selectedIndex":
30
+ let idx = (value as? Int) ?? (value as? NSNumber)?.intValue ?? 0
31
+ seg.selectedSegmentIndex = idx
32
+ case "tintColor":
33
+ if let str = value as? String { seg.selectedSegmentTintColor = UIColor.fromHex(str) }
34
+ case "enabled":
35
+ seg.isEnabled = (value as? Bool) ?? (value as? NSNumber)?.boolValue ?? true
36
+ default:
37
+ StyleEngine.apply(key: key, value: value, to: view)
38
+ }
39
+ }
40
+
41
+ func addEventListener(view: UIView, event: String, handler: @escaping (Any?) -> Void) {
42
+ guard event == "change", let seg = view as? UISegmentedControl else { return }
43
+ objc_setAssociatedObject(view, &segOnChangeKey, handler as AnyObject, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
44
+ let target = SegmentedTarget(view: view)
45
+ objc_setAssociatedObject(view, &segTargetKey, target, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
46
+ seg.addTarget(target, action: #selector(SegmentedTarget.handleChange(_:)), for: .valueChanged)
47
+ }
48
+
49
+ func removeEventListener(view: UIView, event: String) {
50
+ if event == "change" {
51
+ // Remove the UIControl target before clearing the reference
52
+ if let target = objc_getAssociatedObject(view, &segTargetKey) as? SegmentedTarget,
53
+ let seg = view as? UISegmentedControl {
54
+ seg.removeTarget(target, action: #selector(SegmentedTarget.handleChange(_:)), for: .valueChanged)
55
+ }
56
+ objc_setAssociatedObject(view, &segOnChangeKey, nil, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
57
+ objc_setAssociatedObject(view, &segTargetKey, nil, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
58
+ }
59
+ }
60
+ }
61
+
62
+ private final class SegmentedTarget: NSObject {
63
+ private weak var view: UIView?
64
+ init(view: UIView) { self.view = view }
65
+
66
+ @objc func handleChange(_ seg: UISegmentedControl) {
67
+ guard let view = view else { return }
68
+ if let handler = objc_getAssociatedObject(view, &segOnChangeKey) as? ((Any?) -> Void) {
69
+ handler(["selectedIndex": seg.selectedSegmentIndex, "value": seg.titleForSegment(at: seg.selectedSegmentIndex) ?? ""])
70
+ }
71
+ }
72
+ }
73
+ #endif
@@ -0,0 +1,63 @@
1
+ #if canImport(UIKit)
2
+ import UIKit
3
+ import FlexLayout
4
+ import ObjectiveC
5
+
6
+ /// Factory for VSlider — maps to UISlider.
7
+ final class VSliderFactory: NativeComponentFactory {
8
+
9
+ private static var onChangeKey: UInt8 = 0
10
+
11
+ func createView() -> UIView {
12
+ let slider = UISlider()
13
+ slider.minimumValue = 0
14
+ slider.maximumValue = 1
15
+ _ = slider.flex
16
+ return slider
17
+ }
18
+
19
+ func updateProp(view: UIView, key: String, value: Any?) {
20
+ guard let slider = view as? UISlider else {
21
+ StyleEngine.apply(key: key, value: value, to: view)
22
+ return
23
+ }
24
+ switch key {
25
+ case "value":
26
+ slider.value = Float(value as? Double ?? Double(value as? Float ?? 0))
27
+ case "minimumValue", "min":
28
+ slider.minimumValue = Float(value as? Double ?? 0)
29
+ case "maximumValue", "max":
30
+ slider.maximumValue = Float(value as? Double ?? 1)
31
+ case "minimumTrackTintColor":
32
+ slider.minimumTrackTintColor = UIColor.fromHex(value as? String ?? "")
33
+ case "maximumTrackTintColor":
34
+ slider.maximumTrackTintColor = UIColor.fromHex(value as? String ?? "")
35
+ default:
36
+ StyleEngine.apply(key: key, value: value, to: view)
37
+ }
38
+ }
39
+
40
+ func addEventListener(view: UIView, event: String, handler: @escaping (Any?) -> Void) {
41
+ guard event == "change", let slider = view as? UISlider else { return }
42
+ let target = SliderTarget(handler: handler)
43
+ slider.addTarget(target, action: #selector(SliderTarget.handleValueChanged(_:)), for: .valueChanged)
44
+ objc_setAssociatedObject(slider, &VSliderFactory.onChangeKey, target, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
45
+ }
46
+
47
+ func removeEventListener(view: UIView, event: String) {
48
+ guard event == "change", let slider = view as? UISlider else { return }
49
+ if let target = objc_getAssociatedObject(slider, &VSliderFactory.onChangeKey) as? SliderTarget {
50
+ slider.removeTarget(target, action: #selector(SliderTarget.handleValueChanged(_:)), for: .valueChanged)
51
+ }
52
+ objc_setAssociatedObject(slider, &VSliderFactory.onChangeKey, nil, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
53
+ }
54
+ }
55
+
56
+ private final class SliderTarget: NSObject {
57
+ let handler: (Any?) -> Void
58
+ init(handler: @escaping (Any?) -> Void) { self.handler = handler }
59
+ @objc func handleValueChanged(_ slider: UISlider) {
60
+ handler(Double(slider.value))
61
+ }
62
+ }
63
+ #endif
@@ -0,0 +1,50 @@
1
+ #if canImport(UIKit)
2
+ import UIKit
3
+
4
+ /// Factory for VStatusBar — a zero-size, hidden placeholder view that controls
5
+ /// the system status bar appearance by posting notifications to the root
6
+ /// view controller, which must observe them to update its `preferredStatusBarStyle`
7
+ /// and `prefersStatusBarHidden` overrides.
8
+ @MainActor
9
+ final class VStatusBarFactory: NativeComponentFactory {
10
+
11
+ func createView() -> UIView {
12
+ let v = UIView()
13
+ v.isHidden = true
14
+ return v
15
+ }
16
+
17
+ func updateProp(view: UIView, key: String, value: Any?) {
18
+ switch key {
19
+ case "barStyle":
20
+ guard let style = value as? String else { return }
21
+ DispatchQueue.main.async {
22
+ NotificationCenter.default.post(
23
+ name: Notification.Name("VueNativeStatusBarStyleChange"),
24
+ object: nil,
25
+ userInfo: ["style": style]
26
+ )
27
+ }
28
+ case "hidden":
29
+ let hidden = (value as? Bool) ?? (value as? NSNumber)?.boolValue ?? false
30
+ DispatchQueue.main.async {
31
+ NotificationCenter.default.post(
32
+ name: Notification.Name("VueNativeStatusBarHiddenChange"),
33
+ object: nil,
34
+ userInfo: ["hidden": hidden]
35
+ )
36
+ }
37
+ default:
38
+ break
39
+ }
40
+ }
41
+
42
+ func addEventListener(view: UIView, event: String, handler: @escaping (Any?) -> Void) {
43
+ // VStatusBar emits no events
44
+ }
45
+
46
+ func removeEventListener(view: UIView, event: String) {
47
+ // VStatusBar emits no events
48
+ }
49
+ }
50
+ #endif
@@ -0,0 +1,108 @@
1
+ #if canImport(UIKit)
2
+ import UIKit
3
+ import ObjectiveC
4
+ import FlexLayout
5
+
6
+ /// Factory for VSwitch — the boolean toggle switch component.
7
+ /// Maps to UISwitch with FlexLayout enabled.
8
+ /// Supports v-model via the `value` prop and `change` event.
9
+ final class VSwitchFactory: NativeComponentFactory {
10
+
11
+ private static var changeHandlerKey: UInt8 = 0
12
+
13
+ // MARK: - NativeComponentFactory
14
+
15
+ func createView() -> UIView {
16
+ let sw = UISwitch()
17
+ _ = sw.flex
18
+ return sw
19
+ }
20
+
21
+ func updateProp(view: UIView, key: String, value: Any?) {
22
+ guard let sw = view as? UISwitch else {
23
+ StyleEngine.apply(key: key, value: value, to: view)
24
+ return
25
+ }
26
+
27
+ switch key {
28
+ case "value":
29
+ let newValue: Bool
30
+ if let val = value as? Bool {
31
+ newValue = val
32
+ } else if let val = value as? Int {
33
+ newValue = val != 0
34
+ } else {
35
+ newValue = false
36
+ }
37
+ if sw.isOn != newValue {
38
+ sw.setOn(newValue, animated: true)
39
+ }
40
+
41
+ case "disabled":
42
+ if let disabled = value as? Bool {
43
+ sw.isEnabled = !disabled
44
+ } else if let disabled = value as? Int {
45
+ sw.isEnabled = disabled == 0
46
+ } else {
47
+ sw.isEnabled = true
48
+ }
49
+
50
+ case "onTintColor":
51
+ if let colorStr = value as? String {
52
+ sw.onTintColor = UIColor.fromHex(colorStr)
53
+ } else {
54
+ sw.onTintColor = nil
55
+ }
56
+
57
+ case "thumbTintColor":
58
+ if let colorStr = value as? String {
59
+ sw.thumbTintColor = UIColor.fromHex(colorStr)
60
+ } else {
61
+ sw.thumbTintColor = nil
62
+ }
63
+
64
+ default:
65
+ StyleEngine.apply(key: key, value: value, to: view)
66
+ }
67
+ }
68
+
69
+ func addEventListener(view: UIView, event: String, handler: @escaping (Any?) -> Void) {
70
+ guard let sw = view as? UISwitch, event == "change" else { return }
71
+
72
+ let proxy = SwitchActionProxy(handler: handler)
73
+ sw.addTarget(proxy, action: #selector(SwitchActionProxy.valueChanged(_:)), for: .valueChanged)
74
+ objc_setAssociatedObject(
75
+ sw,
76
+ &VSwitchFactory.changeHandlerKey,
77
+ proxy,
78
+ .OBJC_ASSOCIATION_RETAIN_NONATOMIC
79
+ )
80
+ }
81
+
82
+ func removeEventListener(view: UIView, event: String) {
83
+ guard let sw = view as? UISwitch, event == "change" else { return }
84
+
85
+ if let proxy = objc_getAssociatedObject(sw, &VSwitchFactory.changeHandlerKey) as? SwitchActionProxy {
86
+ sw.removeTarget(proxy, action: #selector(SwitchActionProxy.valueChanged(_:)), for: .valueChanged)
87
+ }
88
+ objc_setAssociatedObject(sw, &VSwitchFactory.changeHandlerKey, nil, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
89
+ }
90
+ }
91
+
92
+ // MARK: - SwitchActionProxy
93
+
94
+ /// Target-action proxy that routes UISwitch.valueChanged to a closure handler.
95
+ /// Stored as an associated object on the UISwitch.
96
+ final class SwitchActionProxy: NSObject {
97
+
98
+ let handler: (Any?) -> Void
99
+
100
+ init(handler: @escaping (Any?) -> Void) {
101
+ self.handler = handler
102
+ }
103
+
104
+ @objc func valueChanged(_ sender: UISwitch) {
105
+ handler(sender.isOn)
106
+ }
107
+ }
108
+ #endif
@@ -0,0 +1,290 @@
1
+ #if canImport(UIKit)
2
+ import UIKit
3
+ import FlexLayout
4
+
5
+ /// Factory for VText — the text display component.
6
+ /// Maps to a UILabel with FlexLayout enabled.
7
+ /// After any text or font change, calls flex.markDirty() to trigger Yoga remeasurement.
8
+ final class VTextFactory: NativeComponentFactory {
9
+
10
+ // MARK: - Font weight mapping
11
+
12
+ /// Maps CSS-like font weight strings to UIFont.Weight values.
13
+ static let fontWeightMap: [String: UIFont.Weight] = [
14
+ "100": .ultraLight,
15
+ "200": .thin,
16
+ "300": .light,
17
+ "400": .regular,
18
+ "normal": .regular,
19
+ "500": .medium,
20
+ "600": .semibold,
21
+ "semibold": .semibold,
22
+ "700": .bold,
23
+ "bold": .bold,
24
+ "800": .heavy,
25
+ "900": .black,
26
+ ]
27
+
28
+ // MARK: - Text alignment mapping
29
+
30
+ static let textAlignMap: [String: NSTextAlignment] = [
31
+ "left": .left,
32
+ "center": .center,
33
+ "right": .right,
34
+ "justify": .justified,
35
+ "auto": .natural,
36
+ ]
37
+
38
+ // MARK: - Associated object keys for stored state
39
+
40
+ private static var fontSizeKey: UInt8 = 0
41
+ private static var fontWeightKey: UInt8 = 0
42
+ private static var fontFamilyKey: UInt8 = 0
43
+
44
+ // MARK: - NativeComponentFactory
45
+
46
+ func createView() -> UIView {
47
+ let label = UILabel()
48
+ // Multi-line by default
49
+ label.numberOfLines = 0
50
+ // Accessing .flex automatically enables Yoga layout
51
+ _ = label.flex
52
+ return label
53
+ }
54
+
55
+ func updateProp(view: UIView, key: String, value: Any?) {
56
+ guard let label = view as? UILabel else { return }
57
+
58
+ switch key {
59
+ case "text":
60
+ if let text = value as? String {
61
+ label.text = text
62
+ } else {
63
+ label.text = nil
64
+ }
65
+ label.flex.markDirty()
66
+
67
+ case "numberOfLines":
68
+ if let lines = value as? Int {
69
+ label.numberOfLines = lines
70
+ } else if let lines = value as? Double {
71
+ label.numberOfLines = Int(lines)
72
+ } else {
73
+ label.numberOfLines = 0
74
+ }
75
+ label.flex.markDirty()
76
+
77
+ case "color":
78
+ if let colorStr = value as? String {
79
+ label.textColor = UIColor.fromHex(colorStr)
80
+ } else {
81
+ label.textColor = .label
82
+ }
83
+
84
+ case "fontSize":
85
+ let size: CGFloat
86
+ if let num = value as? Double {
87
+ size = CGFloat(num)
88
+ } else if let num = value as? Int {
89
+ size = CGFloat(num)
90
+ } else {
91
+ size = 17.0 // System default
92
+ }
93
+ storeFontSize(size, on: label)
94
+ rebuildFont(for: label)
95
+ label.flex.markDirty()
96
+
97
+ case "fontWeight":
98
+ if let str = value as? String {
99
+ storeFontWeight(str, on: label)
100
+ } else {
101
+ storeFontWeight(nil, on: label)
102
+ }
103
+ rebuildFont(for: label)
104
+ label.flex.markDirty()
105
+
106
+ case "fontFamily":
107
+ if let family = value as? String {
108
+ storeFontFamily(family, on: label)
109
+ } else {
110
+ storeFontFamily(nil, on: label)
111
+ }
112
+ rebuildFont(for: label)
113
+ label.flex.markDirty()
114
+
115
+ case "textAlign":
116
+ if let alignStr = value as? String {
117
+ label.textAlignment = VTextFactory.textAlignMap[alignStr] ?? .natural
118
+ } else {
119
+ label.textAlignment = .natural
120
+ }
121
+
122
+ case "lineBreakMode":
123
+ if let mode = value as? String {
124
+ switch mode {
125
+ case "clip": label.lineBreakMode = .byClipping
126
+ case "head": label.lineBreakMode = .byTruncatingHead
127
+ case "middle": label.lineBreakMode = .byTruncatingMiddle
128
+ case "tail": label.lineBreakMode = .byTruncatingTail
129
+ case "wordwrap": label.lineBreakMode = .byWordWrapping
130
+ default: label.lineBreakMode = .byTruncatingTail
131
+ }
132
+ }
133
+
134
+ case "fontStyle":
135
+ if let str = value as? String {
136
+ let currentSize = label.font.pointSize
137
+ if str == "italic" {
138
+ let descriptor = label.font.fontDescriptor.withSymbolicTraits(.traitItalic) ?? label.font.fontDescriptor
139
+ label.font = UIFont(descriptor: descriptor, size: currentSize)
140
+ } else {
141
+ var traits = label.font.fontDescriptor.symbolicTraits
142
+ traits.remove(.traitItalic)
143
+ if let descriptor = label.font.fontDescriptor.withSymbolicTraits(traits) {
144
+ label.font = UIFont(descriptor: descriptor, size: currentSize)
145
+ }
146
+ }
147
+ }
148
+ label.flex.markDirty()
149
+
150
+ case "lineHeight":
151
+ if let num = value as? Double {
152
+ let paragraphStyle = NSMutableParagraphStyle()
153
+ paragraphStyle.minimumLineHeight = CGFloat(num)
154
+ paragraphStyle.maximumLineHeight = CGFloat(num)
155
+ paragraphStyle.alignment = label.textAlignment
156
+ let text = label.text ?? ""
157
+ let attrs: [NSAttributedString.Key: Any] = [
158
+ .paragraphStyle: paragraphStyle,
159
+ .font: label.font as Any
160
+ ]
161
+ label.attributedText = NSAttributedString(string: text, attributes: attrs)
162
+ label.flex.markDirty()
163
+ }
164
+
165
+ case "letterSpacing":
166
+ if let num = value as? Double {
167
+ let text = label.text ?? ""
168
+ let attrs: [NSAttributedString.Key: Any] = [
169
+ .kern: CGFloat(num),
170
+ .font: label.font as Any
171
+ ]
172
+ label.attributedText = NSAttributedString(string: text, attributes: attrs)
173
+ label.flex.markDirty()
174
+ }
175
+
176
+ case "textDecorationLine":
177
+ if let str = value as? String {
178
+ let text = label.text ?? ""
179
+ var attrs: [NSAttributedString.Key: Any] = [.font: label.font as Any]
180
+ switch str {
181
+ case "underline":
182
+ attrs[.underlineStyle] = NSUnderlineStyle.single.rawValue
183
+ case "line-through", "lineThrough":
184
+ attrs[.strikethroughStyle] = NSUnderlineStyle.single.rawValue
185
+ case "underline line-through":
186
+ attrs[.underlineStyle] = NSUnderlineStyle.single.rawValue
187
+ attrs[.strikethroughStyle] = NSUnderlineStyle.single.rawValue
188
+ default:
189
+ break
190
+ }
191
+ label.attributedText = NSAttributedString(string: text, attributes: attrs)
192
+ label.flex.markDirty()
193
+ }
194
+
195
+ case "textTransform":
196
+ if let str = value as? String {
197
+ let original = label.text ?? ""
198
+ switch str {
199
+ case "uppercase": label.text = original.uppercased()
200
+ case "lowercase": label.text = original.lowercased()
201
+ case "capitalize": label.text = original.capitalized
202
+ default: break
203
+ }
204
+ label.flex.markDirty()
205
+ }
206
+
207
+ default:
208
+ // Delegate unknown props to StyleEngine for layout/visual styling
209
+ StyleEngine.apply(key: key, value: value, to: view)
210
+ }
211
+ }
212
+
213
+ func addEventListener(view: UIView, event: String, handler: @escaping (Any?) -> Void) {
214
+ // Tap/press support via gesture recognizer.
215
+ if event == "press" {
216
+ let wrapper = GestureWrapper(handler: handler)
217
+ let tap = UITapGestureRecognizer(
218
+ target: wrapper,
219
+ action: #selector(GestureWrapper.handleGesture(_:))
220
+ )
221
+ view.addGestureRecognizer(tap)
222
+ view.isUserInteractionEnabled = true
223
+ GestureStorage.store(wrapper, for: view, event: event)
224
+ }
225
+ }
226
+
227
+ func removeEventListener(view: UIView, event: String) {
228
+ if event == "press" {
229
+ GestureStorage.remove(for: view, event: event)
230
+ view.gestureRecognizers?.forEach { recognizer in
231
+ if recognizer is UITapGestureRecognizer {
232
+ view.removeGestureRecognizer(recognizer)
233
+ }
234
+ }
235
+ }
236
+ }
237
+
238
+ // MARK: - Font rebuilding
239
+
240
+ /// Rebuild the UIFont from stored fontSize, fontWeight, and fontFamily.
241
+ private func rebuildFont(for label: UILabel) {
242
+ let size = storedFontSize(on: label) ?? 17.0
243
+ let weightStr = storedFontWeight(on: label)
244
+ let family = storedFontFamily(on: label)
245
+
246
+ let weight = weightStr.flatMap { VTextFactory.fontWeightMap[$0] } ?? .regular
247
+
248
+ if let family = family, !family.isEmpty {
249
+ // Try to create a font with the specified family
250
+ if let customFont = UIFont(name: family, size: size) {
251
+ label.font = customFont
252
+ } else {
253
+ // Fallback: try as a font descriptor family
254
+ let descriptor = UIFontDescriptor()
255
+ .withFamily(family)
256
+ .addingAttributes([.traits: [UIFontDescriptor.TraitKey.weight: weight]])
257
+ label.font = UIFont(descriptor: descriptor, size: size)
258
+ }
259
+ } else {
260
+ label.font = UIFont.systemFont(ofSize: size, weight: weight)
261
+ }
262
+ }
263
+
264
+ // MARK: - Font state storage via associated objects
265
+
266
+ private func storeFontSize(_ size: CGFloat, on view: UIView) {
267
+ objc_setAssociatedObject(view, &VTextFactory.fontSizeKey, size, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
268
+ }
269
+
270
+ private func storedFontSize(on view: UIView) -> CGFloat? {
271
+ return objc_getAssociatedObject(view, &VTextFactory.fontSizeKey) as? CGFloat
272
+ }
273
+
274
+ private func storeFontWeight(_ weight: String?, on view: UIView) {
275
+ objc_setAssociatedObject(view, &VTextFactory.fontWeightKey, weight, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
276
+ }
277
+
278
+ private func storedFontWeight(on view: UIView) -> String? {
279
+ return objc_getAssociatedObject(view, &VTextFactory.fontWeightKey) as? String
280
+ }
281
+
282
+ private func storeFontFamily(_ family: String?, on view: UIView) {
283
+ objc_setAssociatedObject(view, &VTextFactory.fontFamilyKey, family, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
284
+ }
285
+
286
+ private func storedFontFamily(on view: UIView) -> String? {
287
+ return objc_getAssociatedObject(view, &VTextFactory.fontFamilyKey) as? String
288
+ }
289
+ }
290
+ #endif