@onekeyfe/react-native-native-list 3.0.105

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 (181) hide show
  1. package/README.md +342 -0
  2. package/android/CMakeLists.txt +20 -0
  3. package/android/build.gradle +105 -0
  4. package/android/gradle.properties +4 -0
  5. package/android/src/main/AndroidManifest.xml +1 -0
  6. package/android/src/main/cpp/cpp-adapter.cpp +6 -0
  7. package/android/src/main/java/com/onekey/nativelist/HybridNativeList.kt +125 -0
  8. package/android/src/main/java/com/onekey/nativelist/NativeListAdapter.kt +165 -0
  9. package/android/src/main/java/com/onekey/nativelist/NativeListModels.kt +147 -0
  10. package/android/src/main/java/com/onekey/nativelist/NativeListPackage.kt +25 -0
  11. package/android/src/main/java/com/onekey/nativelist/NativeListRowView.kt +2939 -0
  12. package/android/src/main/java/com/onekey/nativelist/NativeListView.kt +1794 -0
  13. package/common/fonts/Roobert-Bold.ttf +0 -0
  14. package/common/fonts/Roobert-Medium.ttf +0 -0
  15. package/common/fonts/Roobert-Regular.ttf +0 -0
  16. package/common/fonts/Roobert-SemiBold.ttf +0 -0
  17. package/docs/DESIGN.md +129 -0
  18. package/ios/HybridNativeList.swift +131 -0
  19. package/ios/NativeListCell.swift +2858 -0
  20. package/ios/NativeListDesignAssets.swift +110 -0
  21. package/ios/NativeListModels.swift +215 -0
  22. package/ios/RNCNativeListView.swift +1737 -0
  23. package/ios/Resources/NativeListIcons.xcassets/Contents.json +1 -0
  24. package/ios/Resources/NativeListIcons.xcassets/onekey_arrow_bottom.imageset/Contents.json +1 -0
  25. package/ios/Resources/NativeListIcons.xcassets/onekey_arrow_bottom.imageset/icon.svg +1 -0
  26. package/ios/Resources/NativeListIcons.xcassets/onekey_arrow_top.imageset/Contents.json +1 -0
  27. package/ios/Resources/NativeListIcons.xcassets/onekey_arrow_top.imageset/icon.svg +1 -0
  28. package/ios/Resources/NativeListIcons.xcassets/onekey_chart_trending_up.imageset/Contents.json +1 -0
  29. package/ios/Resources/NativeListIcons.xcassets/onekey_chart_trending_up.imageset/icon.svg +1 -0
  30. package/ios/Resources/NativeListIcons.xcassets/onekey_checkbox_checked.imageset/Contents.json +1 -0
  31. package/ios/Resources/NativeListIcons.xcassets/onekey_checkbox_checked.imageset/icon.svg +1 -0
  32. package/ios/Resources/NativeListIcons.xcassets/onekey_checkbox_indeterminate.imageset/Contents.json +1 -0
  33. package/ios/Resources/NativeListIcons.xcassets/onekey_checkbox_indeterminate.imageset/icon.svg +1 -0
  34. package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_bottom.imageset/Contents.json +1 -0
  35. package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_bottom.imageset/icon.svg +1 -0
  36. package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_grabber_ver.imageset/Contents.json +1 -0
  37. package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_grabber_ver.imageset/icon.svg +1 -0
  38. package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_right_small.imageset/Contents.json +1 -0
  39. package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_right_small.imageset/icon.svg +1 -0
  40. package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_top.imageset/Contents.json +1 -0
  41. package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_top.imageset/icon.svg +1 -0
  42. package/ios/Resources/NativeListIcons.xcassets/onekey_dot_hor.imageset/Contents.json +1 -0
  43. package/ios/Resources/NativeListIcons.xcassets/onekey_dot_hor.imageset/icon.svg +1 -0
  44. package/ios/Resources/NativeListIcons.xcassets/onekey_drag.imageset/Contents.json +1 -0
  45. package/ios/Resources/NativeListIcons.xcassets/onekey_drag.imageset/icon.svg +1 -0
  46. package/ios/Resources/NativeListIcons.xcassets/onekey_error_solid.imageset/Contents.json +1 -0
  47. package/ios/Resources/NativeListIcons.xcassets/onekey_error_solid.imageset/icon.svg +1 -0
  48. package/ios/Resources/NativeListIcons.xcassets/onekey_image_square_waves.imageset/Contents.json +1 -0
  49. package/ios/Resources/NativeListIcons.xcassets/onekey_image_square_waves.imageset/icon.svg +1 -0
  50. package/ios/Resources/NativeListIcons.xcassets/onekey_info_circle.imageset/Contents.json +1 -0
  51. package/ios/Resources/NativeListIcons.xcassets/onekey_info_circle.imageset/icon.svg +1 -0
  52. package/ios/Resources/NativeListIcons.xcassets/onekey_minus_circle.imageset/Contents.json +1 -0
  53. package/ios/Resources/NativeListIcons.xcassets/onekey_minus_circle.imageset/icon.svg +1 -0
  54. package/ios/Resources/NativeListIcons.xcassets/onekey_minus_circle_solid.imageset/Contents.json +1 -0
  55. package/ios/Resources/NativeListIcons.xcassets/onekey_minus_circle_solid.imageset/icon.svg +1 -0
  56. package/ios/Resources/NativeListIcons.xcassets/onekey_pencil.imageset/Contents.json +1 -0
  57. package/ios/Resources/NativeListIcons.xcassets/onekey_pencil.imageset/icon.svg +1 -0
  58. package/ios/Resources/NativeListIcons.xcassets/onekey_plus_circle.imageset/Contents.json +1 -0
  59. package/ios/Resources/NativeListIcons.xcassets/onekey_plus_circle.imageset/icon.svg +1 -0
  60. package/ios/Resources/NativeListIcons.xcassets/onekey_plus_small.imageset/Contents.json +1 -0
  61. package/ios/Resources/NativeListIcons.xcassets/onekey_plus_small.imageset/icon.svg +1 -0
  62. package/ios/Resources/NativeListIcons.xcassets/onekey_questionmark_solid.imageset/Contents.json +1 -0
  63. package/ios/Resources/NativeListIcons.xcassets/onekey_questionmark_solid.imageset/icon.svg +1 -0
  64. package/ios/Resources/NativeListIcons.xcassets/onekey_shield_exclamation.imageset/Contents.json +1 -0
  65. package/ios/Resources/NativeListIcons.xcassets/onekey_shield_exclamation.imageset/icon.svg +1 -0
  66. package/ios/Resources/NativeListIcons.xcassets/onekey_speaker_promote.imageset/Contents.json +1 -0
  67. package/ios/Resources/NativeListIcons.xcassets/onekey_speaker_promote.imageset/icon.svg +1 -0
  68. package/ios/Resources/NativeListIcons.xcassets/onekey_star.imageset/Contents.json +1 -0
  69. package/ios/Resources/NativeListIcons.xcassets/onekey_star.imageset/icon.svg +1 -0
  70. package/ios/Resources/NativeListIcons.xcassets/onekey_star_solid.imageset/Contents.json +1 -0
  71. package/ios/Resources/NativeListIcons.xcassets/onekey_star_solid.imageset/icon.svg +1 -0
  72. package/ios/Resources/NativeListIcons.xcassets/onekey_swap_hor.imageset/Contents.json +1 -0
  73. package/ios/Resources/NativeListIcons.xcassets/onekey_swap_hor.imageset/icon.svg +1 -0
  74. package/lib/module/NativeList.js +183 -0
  75. package/lib/module/NativeList.nitro.js +4 -0
  76. package/lib/module/NativeList.types.js +4 -0
  77. package/lib/module/NativeList.web.js +167 -0
  78. package/lib/module/index.js +6 -0
  79. package/lib/module/models.js +2 -0
  80. package/lib/module/package.json +1 -0
  81. package/lib/module/scrolling.js +121 -0
  82. package/lib/module/selection.js +85 -0
  83. package/lib/module/validation.js +562 -0
  84. package/lib/module/web/NativeListWebEngine.js +2238 -0
  85. package/lib/nitrogen/generated/.gitattributes +1 -0
  86. package/lib/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +76 -0
  87. package/lib/nitrogen/generated/android/c++/JHybridNativeListSpec.cpp +201 -0
  88. package/lib/nitrogen/generated/android/c++/JHybridNativeListSpec.hpp +84 -0
  89. package/lib/nitrogen/generated/android/c++/JNativeListScrollAlignment.hpp +64 -0
  90. package/lib/nitrogen/generated/android/c++/views/JHybridNativeListStateUpdater.cpp +104 -0
  91. package/lib/nitrogen/generated/android/c++/views/JHybridNativeListStateUpdater.hpp +54 -0
  92. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/Func_void_std__string.kt +78 -0
  93. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/HybridNativeListSpec.kt +177 -0
  94. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/NativeListScrollAlignment.kt +25 -0
  95. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/nativelistOnLoad.kt +35 -0
  96. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/views/HybridNativeListManager.kt +96 -0
  97. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/views/HybridNativeListStateUpdater.kt +23 -0
  98. package/lib/nitrogen/generated/android/nativelist+autolinking.cmake +83 -0
  99. package/lib/nitrogen/generated/android/nativelist+autolinking.gradle +27 -0
  100. package/lib/nitrogen/generated/android/nativelistOnLoad.cpp +58 -0
  101. package/lib/nitrogen/generated/android/nativelistOnLoad.hpp +34 -0
  102. package/lib/nitrogen/generated/ios/NativeListModule+autolinking.rb +62 -0
  103. package/lib/nitrogen/generated/ios/NativeListModule-Swift-Cxx-Bridge.cpp +41 -0
  104. package/lib/nitrogen/generated/ios/NativeListModule-Swift-Cxx-Bridge.hpp +91 -0
  105. package/lib/nitrogen/generated/ios/NativeListModule-Swift-Cxx-Umbrella.hpp +49 -0
  106. package/lib/nitrogen/generated/ios/NativeListModuleAutolinking.mm +33 -0
  107. package/lib/nitrogen/generated/ios/NativeListModuleAutolinking.swift +26 -0
  108. package/lib/nitrogen/generated/ios/c++/HybridNativeListSpecSwift.cpp +11 -0
  109. package/lib/nitrogen/generated/ios/c++/HybridNativeListSpecSwift.hpp +180 -0
  110. package/lib/nitrogen/generated/ios/c++/views/HybridNativeListComponent.mm +180 -0
  111. package/lib/nitrogen/generated/ios/swift/Func_void_std__string.swift +46 -0
  112. package/lib/nitrogen/generated/ios/swift/HybridNativeListSpec.swift +69 -0
  113. package/lib/nitrogen/generated/ios/swift/HybridNativeListSpec_cxx.swift +447 -0
  114. package/lib/nitrogen/generated/ios/swift/NativeListScrollAlignment.swift +48 -0
  115. package/lib/nitrogen/generated/shared/c++/HybridNativeListSpec.cpp +43 -0
  116. package/lib/nitrogen/generated/shared/c++/HybridNativeListSpec.hpp +87 -0
  117. package/lib/nitrogen/generated/shared/c++/NativeListScrollAlignment.hpp +84 -0
  118. package/lib/nitrogen/generated/shared/c++/views/HybridNativeListComponent.cpp +46 -0
  119. package/lib/nitrogen/generated/shared/c++/views/HybridNativeListComponent.hpp +103 -0
  120. package/lib/nitrogen/generated/shared/json/NativeListConfig.json +16 -0
  121. package/lib/typescript/package.json +1 -0
  122. package/lib/typescript/src/NativeList.d.ts +18 -0
  123. package/lib/typescript/src/NativeList.nitro.d.ts +29 -0
  124. package/lib/typescript/src/NativeList.types.d.ts +87 -0
  125. package/lib/typescript/src/NativeList.web.d.ts +19 -0
  126. package/lib/typescript/src/index.d.ts +7 -0
  127. package/lib/typescript/src/models.d.ts +456 -0
  128. package/lib/typescript/src/scrolling.d.ts +32 -0
  129. package/lib/typescript/src/selection.d.ts +27 -0
  130. package/lib/typescript/src/validation.d.ts +7 -0
  131. package/lib/typescript/src/web/NativeListWebEngine.d.ts +203 -0
  132. package/nitro.json +23 -0
  133. package/nitrogen/generated/.gitattributes +1 -0
  134. package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +76 -0
  135. package/nitrogen/generated/android/c++/JHybridNativeListSpec.cpp +201 -0
  136. package/nitrogen/generated/android/c++/JHybridNativeListSpec.hpp +84 -0
  137. package/nitrogen/generated/android/c++/JNativeListScrollAlignment.hpp +64 -0
  138. package/nitrogen/generated/android/c++/views/JHybridNativeListStateUpdater.cpp +104 -0
  139. package/nitrogen/generated/android/c++/views/JHybridNativeListStateUpdater.hpp +54 -0
  140. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/Func_void_std__string.kt +78 -0
  141. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/HybridNativeListSpec.kt +177 -0
  142. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/NativeListScrollAlignment.kt +25 -0
  143. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/nativelistOnLoad.kt +35 -0
  144. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/views/HybridNativeListManager.kt +96 -0
  145. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/views/HybridNativeListStateUpdater.kt +23 -0
  146. package/nitrogen/generated/android/nativelist+autolinking.cmake +83 -0
  147. package/nitrogen/generated/android/nativelist+autolinking.gradle +27 -0
  148. package/nitrogen/generated/android/nativelistOnLoad.cpp +58 -0
  149. package/nitrogen/generated/android/nativelistOnLoad.hpp +34 -0
  150. package/nitrogen/generated/ios/NativeListModule+autolinking.rb +62 -0
  151. package/nitrogen/generated/ios/NativeListModule-Swift-Cxx-Bridge.cpp +41 -0
  152. package/nitrogen/generated/ios/NativeListModule-Swift-Cxx-Bridge.hpp +91 -0
  153. package/nitrogen/generated/ios/NativeListModule-Swift-Cxx-Umbrella.hpp +49 -0
  154. package/nitrogen/generated/ios/NativeListModuleAutolinking.mm +33 -0
  155. package/nitrogen/generated/ios/NativeListModuleAutolinking.swift +26 -0
  156. package/nitrogen/generated/ios/c++/HybridNativeListSpecSwift.cpp +11 -0
  157. package/nitrogen/generated/ios/c++/HybridNativeListSpecSwift.hpp +180 -0
  158. package/nitrogen/generated/ios/c++/views/HybridNativeListComponent.mm +180 -0
  159. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +46 -0
  160. package/nitrogen/generated/ios/swift/HybridNativeListSpec.swift +69 -0
  161. package/nitrogen/generated/ios/swift/HybridNativeListSpec_cxx.swift +447 -0
  162. package/nitrogen/generated/ios/swift/NativeListScrollAlignment.swift +48 -0
  163. package/nitrogen/generated/shared/c++/HybridNativeListSpec.cpp +43 -0
  164. package/nitrogen/generated/shared/c++/HybridNativeListSpec.hpp +87 -0
  165. package/nitrogen/generated/shared/c++/NativeListScrollAlignment.hpp +84 -0
  166. package/nitrogen/generated/shared/c++/views/HybridNativeListComponent.cpp +46 -0
  167. package/nitrogen/generated/shared/c++/views/HybridNativeListComponent.hpp +103 -0
  168. package/nitrogen/generated/shared/json/NativeListConfig.json +16 -0
  169. package/package.json +126 -0
  170. package/react-native-native-list.podspec +38 -0
  171. package/react-native.config.js +19 -0
  172. package/src/NativeList.nitro.ts +48 -0
  173. package/src/NativeList.tsx +298 -0
  174. package/src/NativeList.types.ts +125 -0
  175. package/src/NativeList.web.tsx +258 -0
  176. package/src/index.ts +35 -0
  177. package/src/models.ts +604 -0
  178. package/src/scrolling.ts +189 -0
  179. package/src/selection.ts +159 -0
  180. package/src/validation.ts +877 -0
  181. package/src/web/NativeListWebEngine.ts +3767 -0
Binary file
Binary file
Binary file
package/docs/DESIGN.md ADDED
@@ -0,0 +1,129 @@
1
+ # Native List Design
2
+
3
+ ## Scope
4
+
5
+ `@onekeyfe/react-native-native-list` is a Nitro View, template-driven list for
6
+ React Native 0.86. The native view owns cell creation, recycling, layout,
7
+ selection feedback, image request cancellation, and scrolling. JavaScript sends
8
+ normalized plain data; rows never contain a `ReactNode`, function, or arbitrary
9
+ style object.
10
+
11
+ The component supports `identity`, `rail`, `activity`, `message`, `dataRow`,
12
+ `mediaTile`, `metricCard`, `sectionHeader`, `action`, and `system` rows.
13
+ `metricCard` supports a compact KPI template and the fixed `activity` and
14
+ `performance` Portfolio & PnL composites. Their bounded metric arrays and
15
+ progress value have dedicated native binders on both mobile platforms.
16
+
17
+ ## Public data boundary
18
+
19
+ The exported TypeScript model is a discriminated union. Every row has a stable
20
+ `key`, bounded text and accessory arrays, and a fixed `size`/`density` variant.
21
+ Business concepts such as asset, account, network, wallet, and settings map to
22
+ the same presentation templates instead of introducing business-specific row
23
+ types.
24
+
25
+ The wrapper validates and normalizes data before serializing it. A structural
26
+ change is one snapshot payload. Frequently changing fields use one batch patch
27
+ payload keyed by row key. Neither API performs one native call per row. The
28
+ native side rejects malformed or duplicate-key payloads without partially
29
+ applying them.
30
+
31
+ Section headers, footers, separators, empty rows, and fixed-footer descriptors
32
+ are represented as rows in one flattened native data source. `groupId` and
33
+ `groupPosition` preserve continuous card geometry without nesting lists inside
34
+ cells.
35
+
36
+ ## Native architecture
37
+
38
+ - iOS 15.5+: `UICollectionView`, `UICollectionViewDiffableDataSource`, and a
39
+ native flow layout.
40
+ - Android API 24+: `RecyclerView`, `ListAdapter`, and `DiffUtil.ItemCallback`.
41
+ - Web: a platform-resolved React host backed by a pure DOM engine. The engine
42
+ owns layout, viewport windowing, recycled row elements, selection feedback,
43
+ section-index navigation, and the same imperative API as mobile; React does
44
+ not create a component subtree per row.
45
+ - Nitro View: the generated HybridView host receives the initial snapshot as
46
+ one string and exposes HybridView methods for subsequent snapshots, patches,
47
+ selection reconciliation, and scrolling. Nitro callback props carry bounded
48
+ JSON payloads which the wrapper decodes into strict public event types.
49
+
50
+ `linear`, `sectioned`, `grid`, and `table` are observable native container
51
+ semantics. Linear is a full-width stream. Sectioned adds a visual break before
52
+ section-header rows and can pin those rows. Grid allocates native spans and
53
+ makes structural rows full-span. Table uses compact alternating rows and fixed
54
+ weighted/aligned columns. Orientation, refresh, load-more, visibility events,
55
+ empty state, fixed footer, and native reordering are capabilities, not row
56
+ types.
57
+
58
+ ## Section index
59
+
60
+ The mobile section index is an opt-in capability for vertical `sectioned`
61
+ snapshots. Indexed section headers carry a bounded `indexTitle`; their stable
62
+ row `key` is also the scroll target, so the feature needs no extra bridge event
63
+ or parallel identity. Headers without `indexTitle` remain in the list but are
64
+ omitted from the rail, which supports sparse alphabets and dynamic search
65
+ results. An enabled snapshot with no indexed headers hides the rail.
66
+
67
+ iOS and Android render a native trailing overlay, reserve a trailing content
68
+ gutter, follow RTL layout direction, highlight the visible section, and expose
69
+ the rail as one adjustable accessibility control. Touch-drag navigation scrolls
70
+ immediately, shows a centered title preview, and emits selection feedback when
71
+ the active entry changes unless `hapticsEnabled` is false. Web renders the same
72
+ explicit index entries as a DOM overlay with click and pointer-drag navigation.
73
+ Snapshot order is authoritative; no platform sorts, uppercases, or synthesizes
74
+ missing entries.
75
+
76
+ ## Selection ownership
77
+
78
+ Native state is authoritative for immediate visible feedback. `none`, `single`,
79
+ and `multiple` modes are supported. Row presses may toggle selection. Row,
80
+ section, and list actions update all affected keys in one native transaction and
81
+ emit one `selectionDelta` containing `addedKeys` and `removedKeys`.
82
+
83
+ Checkboxes support `checked`, `unchecked`, and `indeterminate`, plus `disabled`
84
+ and `loading`. Section and global three-state values are derived from selectable
85
+ descendants. JavaScript may later reconcile native state with one selection
86
+ snapshot or batch patch; reconciliation does not emit another delta.
87
+
88
+ ## Images and OneKeyImage
89
+
90
+ A React `OneKeyImage` component cannot be mounted inside a recycled native cell
91
+ without reintroducing a React subtree per row. Instead, OneKeyImage source data
92
+ is normalized into the list's bounded `ImageSource` descriptor. Each fixed image
93
+ slot embeds `OneKeyImageReusableView`, the native-only host exported by
94
+ `@onekeyfe/react-native-image`. This means iOS uses the same SDWebImage pipeline
95
+ and Android uses the same Glide pipeline as `OneKeyImage`, including its cache,
96
+ SVG/WebP/AVIF support, TOS sizing, animated-image safety, placeholders, and
97
+ recycling behavior.
98
+
99
+ `ImageSource` mirrors the serializable OneKeyImage request options: URI,
100
+ dimensions, headers, content fit, cache policy, autoplay, TOS optimization,
101
+ overscan, and loading strategy. Every bind supplies a stable row/slot recycling
102
+ key. Rebinding or recycling calls OneKeyImage's recycle hook, which cancels stale
103
+ work before the slot accepts its next source. Token/network overlays, double
104
+ activity visuals, and stacks of up to three sources all use the same fixed slot
105
+ pool.
106
+
107
+ ## Update and event policy
108
+
109
+ Snapshot application uses stable keys and platform diffing. A patch updates only
110
+ changed models and rebinds/reconfigures only the corresponding visible cells.
111
+ Selection-only changes use native payload updates and never require rebuilding
112
+ all JavaScript rows.
113
+
114
+ `visibleRangeChanged` is coalesced to at most once per animation frame and only
115
+ emitted when the first/last visible keys change. `endReached` is edge-triggered
116
+ per content generation. Other public events are `rowAction`, `selectionDelta`,
117
+ and `reorder`.
118
+
119
+ ## Height, layout, and performance constraints
120
+
121
+ Template sizes are fixed to a small set of variants. `message` body text is
122
+ bounded to four lines and uses a deterministic template height. System spacers
123
+ are explicit and bounded. Images have explicit sizes, and grid columns are fixed
124
+ per snapshot. This keeps layout work predictable for 1,000- and 5,000-row
125
+ workloads without an unbounded self-sizing pass.
126
+
127
+ The native list runs in the main UI runtime. OneKey's background and main
128
+ JavaScript heaps are not shared, so this API accepts normalized serializable data
129
+ and never depends on background-runtime object identity.
@@ -0,0 +1,131 @@
1
+ import Foundation
2
+ import UIKit
3
+
4
+ final class HybridNativeList: HybridNativeListSpec {
5
+ private let hostView = NativeListView(frame: .zero)
6
+
7
+ var view: UIView { hostView }
8
+
9
+ var snapshotJson: String = "" {
10
+ didSet {
11
+ guard snapshotJson != oldValue else { return }
12
+ runOnMain { [weak self] in
13
+ guard let self else { return }
14
+ self.hostView.applySnapshotJson(self.snapshotJson)
15
+ }
16
+ }
17
+ }
18
+
19
+ var onRowAction: ((_ payloadJson: String) -> Void)?
20
+ var onActionAnchorInvalidated: ((_ payloadJson: String) -> Void)?
21
+ var onSelectionDelta: ((_ payloadJson: String) -> Void)?
22
+ var onReorder: ((_ payloadJson: String) -> Void)?
23
+ var onEndReached: ((_ payloadJson: String) -> Void)?
24
+ var onVisibleRangeChanged: ((_ payloadJson: String) -> Void)?
25
+
26
+ override init() {
27
+ super.init()
28
+ hostView.onRowAction = { [weak self] in self?.onRowAction?($0) }
29
+ hostView.onActionAnchorInvalidated = { [weak self] in self?.onActionAnchorInvalidated?($0) }
30
+ hostView.onSelectionDelta = { [weak self] in self?.onSelectionDelta?($0) }
31
+ hostView.onReorder = { [weak self] in self?.onReorder?($0) }
32
+ hostView.onEndReached = { [weak self] in self?.onEndReached?($0) }
33
+ hostView.onVisibleRangeChanged = { [weak self] in self?.onVisibleRangeChanged?($0) }
34
+ }
35
+
36
+ func applySnapshot(snapshotJson: String) throws {
37
+ runOnMain { [weak self] in self?.hostView.applySnapshotJson(snapshotJson) }
38
+ }
39
+
40
+ func applyPatches(patchesJson: String) throws {
41
+ runOnMain { [weak self] in self?.hostView.applyPatchesJson(patchesJson) }
42
+ }
43
+
44
+ func reconcileSelection(selectedKeysJson: String) throws {
45
+ runOnMain { [weak self] in self?.hostView.reconcileSelectionJson(selectedKeysJson) }
46
+ }
47
+
48
+ func scrollToKey(
49
+ key: String,
50
+ animated: Bool,
51
+ alignment: NativeListScrollAlignment,
52
+ viewPosition: Double,
53
+ viewOffset: Double
54
+ ) throws {
55
+ runOnMain { [weak self] in
56
+ self?.hostView.scrollToKey(
57
+ key,
58
+ animated: animated,
59
+ alignment: alignment.stringValue,
60
+ viewPosition: viewPosition,
61
+ viewOffset: viewOffset
62
+ )
63
+ }
64
+ }
65
+
66
+ func scrollToIndex(
67
+ index: Double,
68
+ animated: Bool,
69
+ alignment: NativeListScrollAlignment,
70
+ viewPosition: Double,
71
+ viewOffset: Double
72
+ ) throws {
73
+ guard index.isFinite,
74
+ index >= 0,
75
+ index.rounded(.towardZero) == index,
76
+ index <= Double(Int.max) else { return }
77
+ runOnMain { [weak self] in
78
+ self?.hostView.scrollToIndex(
79
+ Int(index),
80
+ animated: animated,
81
+ alignment: alignment.stringValue,
82
+ viewPosition: viewPosition,
83
+ viewOffset: viewOffset
84
+ )
85
+ }
86
+ }
87
+
88
+ func scrollToOffset(offset: Double, animated: Bool) throws {
89
+ guard offset.isFinite, offset >= 0 else { return }
90
+ runOnMain { [weak self] in
91
+ self?.hostView.scrollToOffset(offset, animated: animated)
92
+ }
93
+ }
94
+
95
+ func scrollToEnd(animated: Bool) throws {
96
+ runOnMain { [weak self] in self?.hostView.scrollToEnd(animated: animated) }
97
+ }
98
+
99
+ func setActionAnchorState(stateJson: String) throws {
100
+ runOnMain { [weak self] in self?.hostView.setActionAnchorStateJson(stateJson) }
101
+ }
102
+
103
+ func setRefreshing(refreshing: Bool) throws {
104
+ runOnMain { [weak self] in self?.hostView.setRefreshing(refreshing) }
105
+ }
106
+
107
+ func onDropView() {
108
+ runOnMain { [weak self] in self?.hostView.disposeActionAnchor() }
109
+ }
110
+
111
+ func dispose() {
112
+ runOnMain { [weak self] in self?.hostView.disposeActionAnchor() }
113
+ }
114
+
115
+ deinit {
116
+ if Thread.isMainThread {
117
+ hostView.disposeActionAnchor()
118
+ } else {
119
+ let view = hostView
120
+ DispatchQueue.main.async { view.disposeActionAnchor() }
121
+ }
122
+ }
123
+
124
+ private func runOnMain(_ work: @escaping () -> Void) {
125
+ if Thread.isMainThread {
126
+ work()
127
+ } else {
128
+ DispatchQueue.main.async(execute: work)
129
+ }
130
+ }
131
+ }