@onekeyfe/react-native-native-list 3.0.157-alpha.249 → 3.0.157-alpha.250

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 (130) hide show
  1. package/README.md +21 -5
  2. package/android/src/main/java/com/onekey/nativelist/NativeListAccessoryStack.kt +711 -0
  3. package/android/src/main/java/com/onekey/nativelist/NativeListActionRenderer.kt +169 -0
  4. package/android/src/main/java/com/onekey/nativelist/NativeListActivityRenderer.kt +243 -0
  5. package/android/src/main/java/com/onekey/nativelist/NativeListAdapter.kt +20 -6
  6. package/android/src/main/java/com/onekey/nativelist/NativeListDataRowRenderer.kt +487 -0
  7. package/android/src/main/java/com/onekey/nativelist/NativeListIdentityRenderer.kt +820 -0
  8. package/android/src/main/java/com/onekey/nativelist/NativeListImageSlot.kt +147 -0
  9. package/android/src/main/java/com/onekey/nativelist/NativeListLeadingVisual.kt +453 -0
  10. package/android/src/main/java/com/onekey/nativelist/NativeListMarketRenderer.kt +997 -0
  11. package/android/src/main/java/com/onekey/nativelist/NativeListMediaTileRenderer.kt +234 -0
  12. package/android/src/main/java/com/onekey/nativelist/NativeListMessageRenderer.kt +232 -0
  13. package/android/src/main/java/com/onekey/nativelist/NativeListMetricCardRenderer.kt +551 -0
  14. package/android/src/main/java/com/onekey/nativelist/NativeListModels.kt +24 -0
  15. package/android/src/main/java/com/onekey/nativelist/NativeListPrimitives.kt +475 -0
  16. package/android/src/main/java/com/onekey/nativelist/NativeListRailRenderer.kt +143 -0
  17. package/android/src/main/java/com/onekey/nativelist/NativeListRendererRegistry.kt +42 -0
  18. package/android/src/main/java/com/onekey/nativelist/NativeListRendererRowView.kt +415 -0
  19. package/android/src/main/java/com/onekey/nativelist/NativeListResolvedText.kt +163 -0
  20. package/android/src/main/java/com/onekey/nativelist/NativeListRowHost.kt +70 -0
  21. package/android/src/main/java/com/onekey/nativelist/NativeListSectionHeaderRenderer.kt +748 -0
  22. package/android/src/main/java/com/onekey/nativelist/NativeListSystemRenderer.kt +464 -0
  23. package/android/src/main/java/com/onekey/nativelist/NativeListTextView.kt +25 -0
  24. package/android/src/main/java/com/onekey/nativelist/NativeListView.kt +174 -104
  25. package/android/src/main/java/com/onekey/nativelist/NativeListWalletGroupRenderer.kt +407 -0
  26. package/android/src/test/java/com/margelo/nitro/nativelist/NativeListSelectorBackgroundColorTest.kt +34 -0
  27. package/docs/DESIGN.md +518 -9
  28. package/docs/MIGRATION_BASELINE.md +117 -0
  29. package/docs/ROW_TEMPLATES.md +359 -0
  30. package/docs/SPEC.md +358 -0
  31. package/docs/STYLE_SPEC.md +978 -0
  32. package/docs/images/list-capabilities.svg +39 -0
  33. package/docs/images/row-action.svg +17 -0
  34. package/docs/images/row-activity.svg +24 -0
  35. package/docs/images/row-data.svg +24 -0
  36. package/docs/images/row-identity.svg +25 -0
  37. package/docs/images/row-market.svg +23 -0
  38. package/docs/images/row-media-tile.svg +26 -0
  39. package/docs/images/row-message.svg +20 -0
  40. package/docs/images/row-metric-card.svg +33 -0
  41. package/docs/images/row-rail.svg +18 -0
  42. package/docs/images/row-section-header.svg +19 -0
  43. package/docs/images/row-style-regions.svg +30 -0
  44. package/docs/images/row-system.svg +30 -0
  45. package/docs/images/row-wallet-group.svg +26 -0
  46. package/ios/NativeListAccessoryStack.swift +680 -0
  47. package/ios/NativeListActionRenderer.swift +108 -0
  48. package/ios/NativeListActivityRenderer.swift +179 -0
  49. package/ios/NativeListDataRowRenderer.swift +444 -0
  50. package/ios/NativeListIdentityRenderer.swift +685 -0
  51. package/ios/NativeListImageSlot.swift +140 -0
  52. package/ios/NativeListLeadingVisual.swift +372 -0
  53. package/ios/NativeListMarketRenderer.swift +698 -0
  54. package/ios/NativeListMediaTileRenderer.swift +184 -0
  55. package/ios/NativeListMessageRenderer.swift +168 -0
  56. package/ios/NativeListMetricCardRenderer.swift +420 -0
  57. package/ios/NativeListModels.swift +32 -0
  58. package/ios/NativeListRailRenderer.swift +152 -0
  59. package/ios/NativeListRendererCell.swift +311 -0
  60. package/ios/NativeListRendererRegistry.swift +50 -0
  61. package/ios/NativeListResolvedText.swift +122 -0
  62. package/ios/NativeListRowHost.swift +63 -0
  63. package/ios/NativeListSectionHeaderRenderer.swift +708 -0
  64. package/ios/NativeListSystemRenderer.swift +568 -0
  65. package/ios/NativeListTextLabel.swift +42 -0
  66. package/ios/NativeListTextStyles.swift +236 -0
  67. package/ios/NativeListWalletGroupRenderer.swift +255 -0
  68. package/ios/RNCNativeListView.swift +111 -180
  69. package/lib/module/models.js +54 -0
  70. package/lib/module/validation.js +324 -26
  71. package/lib/module/web/NativeListWebEngine.js +148 -936
  72. package/lib/module/web/templates/ActionRowRenderer.js +97 -0
  73. package/lib/module/web/templates/ActivityRowRenderer.js +95 -0
  74. package/lib/module/web/templates/DataRowRenderer.js +145 -0
  75. package/lib/module/web/templates/IdentityRowRenderer.js +289 -0
  76. package/lib/module/web/templates/MarketRowRenderer.js +310 -0
  77. package/lib/module/web/templates/MediaTileRowRenderer.js +132 -0
  78. package/lib/module/web/templates/MessageRowRenderer.js +165 -0
  79. package/lib/module/web/templates/MetricCardRowRenderer.js +172 -0
  80. package/lib/module/web/templates/RailRowRenderer.js +98 -0
  81. package/lib/module/web/templates/RowContainerStyle.js +100 -0
  82. package/lib/module/web/templates/RowElements.js +93 -0
  83. package/lib/module/web/templates/RowRendererRegistry.js +70 -0
  84. package/lib/module/web/templates/RowText.js +121 -0
  85. package/lib/module/web/templates/RowVisual.js +43 -0
  86. package/lib/module/web/templates/SectionHeaderRowRenderer.js +146 -0
  87. package/lib/module/web/templates/SystemRowRenderer.js +161 -0
  88. package/lib/module/web/templates/WalletGroupRowRenderer.js +96 -0
  89. package/lib/typescript/src/models.d.ts +166 -13
  90. package/lib/typescript/src/web/NativeListWebEngine.d.ts +18 -16
  91. package/lib/typescript/src/web/templates/ActionRowRenderer.d.ts +15 -0
  92. package/lib/typescript/src/web/templates/ActivityRowRenderer.d.ts +15 -0
  93. package/lib/typescript/src/web/templates/DataRowRenderer.d.ts +15 -0
  94. package/lib/typescript/src/web/templates/IdentityRowRenderer.d.ts +16 -0
  95. package/lib/typescript/src/web/templates/MarketRowRenderer.d.ts +30 -0
  96. package/lib/typescript/src/web/templates/MediaTileRowRenderer.d.ts +15 -0
  97. package/lib/typescript/src/web/templates/MessageRowRenderer.d.ts +44 -0
  98. package/lib/typescript/src/web/templates/MetricCardRowRenderer.d.ts +15 -0
  99. package/lib/typescript/src/web/templates/RailRowRenderer.d.ts +28 -0
  100. package/lib/typescript/src/web/templates/RowContainerStyle.d.ts +9 -0
  101. package/lib/typescript/src/web/templates/RowElements.d.ts +38 -0
  102. package/lib/typescript/src/web/templates/RowRendererRegistry.d.ts +83 -0
  103. package/lib/typescript/src/web/templates/RowText.d.ts +9 -0
  104. package/lib/typescript/src/web/templates/RowVisual.d.ts +20 -0
  105. package/lib/typescript/src/web/templates/SectionHeaderRowRenderer.d.ts +15 -0
  106. package/lib/typescript/src/web/templates/SystemRowRenderer.d.ts +16 -0
  107. package/lib/typescript/src/web/templates/WalletGroupRowRenderer.d.ts +20 -0
  108. package/package.json +3 -3
  109. package/src/models.ts +281 -19
  110. package/src/validation.ts +501 -46
  111. package/src/web/NativeListWebEngine.ts +361 -1932
  112. package/src/web/templates/ActionRowRenderer.ts +123 -0
  113. package/src/web/templates/ActivityRowRenderer.ts +159 -0
  114. package/src/web/templates/DataRowRenderer.ts +212 -0
  115. package/src/web/templates/IdentityRowRenderer.ts +527 -0
  116. package/src/web/templates/MarketRowRenderer.ts +467 -0
  117. package/src/web/templates/MediaTileRowRenderer.ts +182 -0
  118. package/src/web/templates/MessageRowRenderer.ts +306 -0
  119. package/src/web/templates/MetricCardRowRenderer.ts +337 -0
  120. package/src/web/templates/RailRowRenderer.ts +136 -0
  121. package/src/web/templates/RowContainerStyle.ts +131 -0
  122. package/src/web/templates/RowElements.ts +160 -0
  123. package/src/web/templates/RowRendererRegistry.ts +111 -0
  124. package/src/web/templates/RowText.ts +181 -0
  125. package/src/web/templates/RowVisual.ts +115 -0
  126. package/src/web/templates/SectionHeaderRowRenderer.ts +243 -0
  127. package/src/web/templates/SystemRowRenderer.ts +282 -0
  128. package/src/web/templates/WalletGroupRowRenderer.ts +131 -0
  129. package/android/src/main/java/com/onekey/nativelist/NativeListRowView.kt +0 -4538
  130. package/ios/NativeListCell.swift +0 -4300
package/docs/SPEC.md ADDED
@@ -0,0 +1,358 @@
1
+ # NativeList contract
2
+
3
+ This is the entry point for the package's behavioral contract. The linked
4
+ documents are part of this spec; implementation status is separate from target
5
+ architecture and runtime evidence.
6
+
7
+ ## Purpose and non-goals
8
+
9
+ NativeList renders bounded data with fixed row templates on iOS, Android and
10
+ Web. It does not render arbitrary React children. Integrators own overflow
11
+ prevention; there is no automatic fitting or shrinking pass.
12
+
13
+ ## Definitions and ownership
14
+
15
+ - `rowTemplate` defines structure, semantic fields and supported variants.
16
+ [ROW_TEMPLATES.md](ROW_TEMPLATES.md) defines and illustrates every template.
17
+ - `rowStyle` adjusts the template's named text, image, spacing and container
18
+ properties. It can set row height but cannot replace the template structure.
19
+ [STYLE_SPEC.md](STYLE_SPEC.md) defines the common property vocabulary.
20
+ - The list owns placement, sections, scrolling, indexed bar, selection and
21
+ reorder. These capabilities do not belong to individual row templates.
22
+ - The renderer owns template views, defaults, binding and measurement. A shared
23
+ host owns row appearance, events and binding invalidation. This ownership is a
24
+ migration target, not a claim that the current native hosts are already split.
25
+
26
+ ## Public API and defaults
27
+
28
+ [README.md](../README.md) documents the snapshot, patch, selection, events and
29
+ imperative API; [STYLE_SPEC.md](STYLE_SPEC.md) defines normalization, omitted
30
+ style defaults and platform differences. Height precedence is
31
+ `style.container.height` → `row.height` → template measurement/default.
32
+ Removing a style restores the current template's defaults, not the previous
33
+ row's appearance. Selector presentations (`accountSelector`, `networkSelector`,
34
+ `walletSidebar`) use their explicit-height geometry whenever either
35
+ `style.container.height` or `row.height` is set.
36
+
37
+ The row style surface (`row.style`, including `style.container`) and
38
+ `snapshot.listStyle` are **new public TypeScript/JSON protocol in this change**;
39
+ they travel inside the existing `snapshotJson` string, so the Nitro schema is
40
+ unchanged. Validation of that surface is strict: undeclared or unknown nested
41
+ keys are rejected (see Failures below and STYLE_SPEC.md §2). The renderer
42
+ migration itself does not change any other protocol field.
43
+
44
+ ## Lifecycle and concurrency
45
+
46
+ Full binding must work without a preceding recycle callback, including
47
+ style set/change/clear and content A → B. A binding epoch invalidates stale
48
+ image callbacks and action anchors. Recycling/disposal releases pending work
49
+ through the existing image/host lifecycle. Image loading visibility belongs to
50
+ the image lifecycle: restoring template defaults on rebind must never hide an
51
+ image that already loaded. Common container styling clears what it wrote on the
52
+ next bind, including properties it set on template children. UI mutation remains on the platform
53
+ UI thread; [DESIGN.md](DESIGN.md) describes update and event ownership.
54
+
55
+ ## Data, cache and identity
56
+
57
+ `row.key` identifies data; renderer reuse identity describes compatible view
58
+ structure. Content, styles, height and placement must not enter reuse identity.
59
+ All twelve templates have their own renderer family: Message, Rail, MediaTile,
60
+ Action, System, Activity, DataRow, MetricCard, Market, Identity, SectionHeader and
61
+ WalletGroup. Same-key family changes must replace the incompatible host. OneKeyImage owns image caches; NativeList owns row/slot binding identity.
62
+
63
+ ## Platform contract
64
+
65
+ All platforms expose the same bounded style properties and public semantics.
66
+ Existing geometry/typography differences are recorded in
67
+ [STYLE_SPEC.md](STYLE_SPEC.md); structural extraction must not silently change
68
+ them. iOS uses UICollectionView, Android RecyclerView, and Web a windowed DOM
69
+ engine. See [DESIGN.md](DESIGN.md) for their current ownership boundaries.
70
+
71
+ ## Failures, fallback and limits
72
+
73
+ Snapshot validation rejects malformed/duplicate-key input without partial
74
+ application. Template field/array bounds and image fallback behavior are defined
75
+ in [ROW_TEMPLATES.md](ROW_TEMPLATES.md), [README.md](../README.md) and
76
+ [DESIGN.md](DESIGN.md). This change adds the style surface's limits, defined in
77
+ [STYLE_SPEC.md](STYLE_SPEC.md) §3.3/§4/§5: numeric bounds, `#RRGGBB`/`#RRGGBBAA`
78
+ colors (including `listStyle.separator.color`), `groupCornerRadius` `0…40`, and
79
+ rejection of any undeclared or unknown nested style key by `validateSnapshot`
80
+ and `validatePatches`, where extra keys used to be ignored. It adds no retry
81
+ policy or automatic layout correction.
82
+
83
+ ## Performance and resources
84
+
85
+ Snapshots and patches cross the bridge in batches. Visible rows use platform
86
+ recycling/windowing; shared primitives own image cancellation. All twelve templates use dedicated lightweight native hosts and persistent Web
87
+ bodies. WalletGroup composes the migrated Identity member hosts.
88
+ None allocates the legacy native tree. This structural change is
89
+ not a measured scrolling-performance result; performance claims still need a
90
+ separate workload and measurements.
91
+
92
+ ## Conformance and six-stage migration
93
+
94
+ | Stage | Current status | Exit condition |
95
+ | --- | --- | --- |
96
+ | 1. Baseline | Complete: [implicit keys, defaults, special updates and acceptance baseline](MIGRATION_BASELINE.md) inventoried | Preserve each existing rule or explicitly migrate its caller |
97
+ | 2. Message pilot | Complete: registered lightweight native hosts, persistent Web body, resolved styling/measurement and lifecycle acceptance | Lightweight native hosts, resolved styling/measurement, update classification and lifecycle acceptance |
98
+ | 3. Simple templates | Complete (7/7): Rail, MediaTile, Action, System, Activity, DataRow and MetricCard migrated on all three platforms | Migrate mediaTile, rail, action, system, activity, dataRow and metricCard; remove each old dispatch/reset path |
99
+ | 4. Complex templates | Complete (3/3): Market, Identity and SectionHeader migrated on all three platforms | Migrate Market, Identity and SectionHeader while preserving quote, selection and header behavior |
100
+ | 5. WalletGroup | Complete: registered composites and independent keyed Identity members on all three platforms | Independent member renderers; verify member events/styles, compact dragging and height restoration |
101
+ | 6. Cleanup | Complete: obsolete hosts/maps/fallback pools and audited key styling removed | Remove migrated key inference and global style maps; container no longer manipulates template internals |
102
+
103
+ The closed internal registry selects all twelve renderers by template type.
104
+ No supported template dispatches to the legacy native tree. WalletGroup owns
105
+ composition and compact appearance; its members use independent Identity
106
+ renderers. Legacy native classes, global style maps and fallback registry entries
107
+ are removed, including footer initialization. Web preserves compatible bodies and
108
+ unchanged member image elements across rebinding.
109
+
110
+ Message resolves text/spacing/image inputs from data/theme/styles, classifies
111
+ updates as unchanged, content/style, assets or replacement, and binds/measures
112
+ using those resolved values. Image slots retain an unchanged effective request;
113
+ source/row/slot or image-request-option changes invalidate old callbacks and
114
+ retries. Image request epochs are independent of row action-anchor epochs, so
115
+ text-only updates preserve in-flight images. Legacy Message binding, slot-map
116
+ and measurement branches have been removed. Stage 6 also removes the audited Android separator-key
117
+ compatibility policy; the explicit separator field controls visibility.
118
+
119
+ Message intrinsic measurement now uses its actual resolved view metrics rather
120
+ than the historical estimator-only defaults listed in MIGRATION_BASELINE.md.
121
+ This can change **automatic** Message heights; explicit row/container heights
122
+ and unstyled drawing defaults remain unchanged. Native measurement accounts
123
+ for the allocated column width, line limits, gaps and optional images. Web uses
124
+ the same resolved geometry with a conservative text estimate, then corrects the
125
+ visible intrinsic height from its rendered DOM; it does not auto-fit content.
126
+
127
+ Source boundaries and dated runtime evidence are in the incremental migration
128
+ section of [DESIGN.md](DESIGN.md). Acceptance covers style set/change/clear,
129
+ binding without recycle, same-key template changes, image add/remove, scrolling
130
+ away/back, explicit height restoration and fixed-footer placement. Unit/type
131
+ checks are not native runtime verification, and Message acceptance does not
132
+ complete the remaining stages.
133
+
134
+ Stage 3 extends the closed registry one template at a time. Migrated templates
135
+ own their view trees and semantic styles; native templates share the Message
136
+ host's appearance/event lifecycle and bounded image primitives, not a legacy
137
+ view tree. Preserve existing default geometry, variant behavior, actions,
138
+ selection echo and platform differences. Horizontal sizing belongs to each
139
+ renderer and must use its resolved text/image/spacing inputs. A style change
140
+ must invalidate horizontal placement when its measured width changes. Fixed
141
+ template height defaults remain defaults, not automatic content fitting.
142
+ DataRow keeps the inventoried `asset`-column Web badge behavior until a separate
143
+ caller migration; this extraction does not change which column owns badges.
144
+
145
+ Rail owns its title/badge/status views and leading visual. Shared native hosts
146
+ own appearance, action-anchor epochs, selection routing and reuse invalidation;
147
+ Web uses the same primitive interface for Message and Rail. Legacy Rail bind,
148
+ style-slot, reset and width branches have been removed. Horizontal measurement
149
+ now responds to explicit fonts, image dimensions, padding and gaps while
150
+ retaining the existing default width allowances and platform limits. Text-only
151
+ rebinding preserves unchanged image requests; clearing styles restores defaults.
152
+ All seven stage 3 templates are now migrated; dated acceptance for each is recorded in DESIGN.md.
153
+
154
+ MediaTile owns its picture, network indicator, title/subtitle, badge and close
155
+ control. Its legacy bind/style/reset allocation paths are removed. Images retain
156
+ unchanged requests across content/style updates; close events use the shared
157
+ host epoch with `mediaClose` source. Grid and horizontal allocation remain
158
+ container-owned. Default iOS grid height stays width + 48, including existing
159
+ compression when a close control is present; explicit container heights let the
160
+ caller allocate more room. No overflow fitting is added.
161
+
162
+ Action owns its title, optional icon and bounded accessory controls. Native
163
+ checkbox presentation can update without rebinding the title/icon; all actions
164
+ carry the shared host epoch and preserve the original account-control anchor
165
+ inset. Fixed footers now also resolve their host through the closed registry
166
+ and replace it when their renderer family changes. Placement and gesture
167
+ routing remain list-owned.
168
+
169
+ MetricCard owns standard, activity and performance variants. Its existing
170
+ per-platform measurement, badge colors, composite spacing and progress layout
171
+ remain template defaults. Standard-card styles address title/value/subtitle/trend;
172
+ composite cards expose the heading slot and keep metric internals fixed as
173
+ defined in STYLE_SPEC.md. Image slots retain unchanged requests across rebinding
174
+ and reset when a source disappears or its slot identity changes.
175
+
176
+ All six stages are complete. Stages 4–6 and their acceptance scopes are recorded
177
+ below; the baseline inventory explicitly identifies two retained compatibility
178
+ policies outside renderer selection/style mapping.
179
+ No migrated simple template dispatches through a legacy binder.
180
+
181
+ ### Stage 4 acceptance scope
182
+
183
+ Market, Identity and SectionHeader move to dedicated registered renderers on all
184
+ three platforms. This stage preserves existing defaults and implicit-key
185
+ compatibility recorded in MIGRATION_BASELINE.md. It adds no style fields beyond
186
+ the style surface this change introduces.
187
+ Market owns quote-only binding and its platform row interactions; Identity owns
188
+ selection presentation; SectionHeader owns stable summary updates and measurement.
189
+ Sticky placement and header/footer routing stay in the list container.
190
+ Acceptance includes variant changes on the same key, styled → unstyled rebinding,
191
+ unchanged image requests, partial updates with current action context, selection,
192
+ scroll/recycle, and shared footer/sticky-header behavior.
193
+
194
+ Each complex renderer now owns its view tree, defaults, semantic style slots and
195
+ measurement. Native hosts share bounded leading/image/accessory primitives. Web
196
+ retains the compatible body and unchanged image elements; loaded image state is
197
+ not reset when geometry is restored. Quote and summary updates keep the latest
198
+ row model for subsequent action/selection dispatch. Stage 4 introduces no public
199
+ API or Nitro schema beyond the style surface described above. Stage 5 below also replaces the native WalletGroup composite tree. Stage 6 below removes the
200
+ obsolete native classes and maps.
201
+
202
+ Stage 4 validation: package typecheck and all 161 tests in five suites pass;
203
+ focused lint has zero errors and two existing shadowing warnings. iOS Debug
204
+ build/link and Android Debug APK plus seven unit tests pass. Both dedicated
205
+ native simulators and headed Chrome exercised the acceptance cases above.
206
+ The section fixture additionally verified imperative scroll pinning and active
207
+ index updates after the container fixes. Stages 5 and 6 acceptance follow below. This is not a performance signoff.
208
+
209
+ ### Stage 5 ownership and acceptance
210
+
211
+ WalletGroup owns only member composition, measurement and compact presentation.
212
+ Each member uses the registered Identity renderer and retains its own key, style,
213
+ selection, action origin and binding lifetime. Group styles never cascade into
214
+ members. Rebinding reconciles by member key; removed members are recycled
215
+ immediately, so retention is bounded by the current member count (plus one
216
+ compact parent on native). Recycling releases every member and compact parent.
217
+
218
+ Acceptance covers member press/accessory routing, disabled and pressDisabled
219
+ members, selection-only changes, style set/change/clear, member reorder/removal,
220
+ family replacement and reuse. The compact drag allocation is 68 on iOS and Web;
221
+ Android keeps its legacy `max(68, parent member height + 2 × group vertical
222
+ inset)` (for example 94 for a badged parent with an explicit height).
223
+ `+N` counts children whose draggable is not false. Only `draggable: false`
224
+ prevents a member from initiating group drag; a disabled member can still start
225
+ it (legacy behavior on all three platforms). Drop/cancel restore the
226
+ resolved group height and all configured member/container styles. Reorder
227
+ orchestration stays in the list container. Existing platform defaults stay
228
+ unchanged. Verify on the dedicated external-drive simulators and headed Web.
229
+
230
+ Stage 5 runtime verification: iOS and Android member press/menu actions carry
231
+ the member key and current action origin, including after content updates.
232
+ Both platforms verified selected/disabled members, style set/clear, member
233
+ removal/reordering, same-key family replacement, empty/repopulation, scrolling
234
+ and the shared fixed footer. Real member/parent drags move the group atomically;
235
+ excluded members do not start dragging. Default 274-point and styled 340-point
236
+ fixture heights restore after drop. iOS also verified a no-op long press;
237
+ Android verified touch cancellation; Web verified Escape cancellation.
238
+
239
+ All 163 package tests and typecheck pass; focused lint has zero errors (two
240
+ existing warnings). iOS Debug build/link, Android Debug APK and seven Android
241
+ unit tests pass. Headed Chrome includes a 390px viewport and in-drag captures.
242
+ Native simulator captures, action payloads and iOS recordings are stored with
243
+ the stage 5 harness in the external validation runtime. These are standalone
244
+ NativeList checks, not a consumer-app release or scrolling-performance signoff.
245
+
246
+ ### Stage 6 cleanup and acceptance
247
+
248
+ The native monoliths and global style-slot maps are deleted. Their still-used
249
+ fonts, icons, layout helpers, action origins and controls remain shared primitives.
250
+ All twelve registry families are explicit. JavaScript validation rejects an
251
+ unknown row type before serialization. If one still reaches native code, iOS
252
+ keeps its legacy behavior: an empty 56-point placeholder row with shared chrome
253
+ and a single log message. Android rejects the snapshot while parsing it. Footer initialization uses a registered Action host.
254
+ Web has no legacy pool or warning-specific container measurement path; template
255
+ renderers own selector typography, System warning DOM measurement and
256
+ WalletGroup compact-preview lookup.
257
+
258
+ The consumer audit in MIGRATION_BASELINE.md allows removal of history-key header
259
+ inference, Android token-section typography inference, and separator-key exceptions.
260
+ Callers choose `variant`, `style` and `separator` explicitly. Market pagination-tail
261
+ recognition and the existing Web DataRow `asset` badge column are deliberately
262
+ retained under the separately documented migration boundaries.
263
+
264
+ Validation covers same-key cycling through twelve templates, style set/clear,
265
+ ordinary/history-named/explicit-history headers, explicit 30-unit token headers,
266
+ Action/System footer replacement and callbacks, scrolling/reuse and WalletGroup
267
+ member actions and compact dragging. Source/type checks and runtime evidence
268
+ are recorded separately in DESIGN.md. This completes the architecture migration;
269
+ it does not add automatic overflow fitting or claim a performance benchmark.
270
+
271
+ ### Web legacy-default audit (2026-09-24)
272
+
273
+ The renderer structure is retained; these legacy Web defaults are restored
274
+ inside it. MetricCard/System default restoration keeps image loading visibility
275
+ (a loaded image stays visible after content or style rebinding). WalletGroup
276
+ measurement keeps the legacy member sum, 12-unit gaps and the 1px border pair
277
+ (budgeted only when the parent member carries `height`, like native's 1-unit
278
+ inset); `style.verticalPadding` replaces that inset instead of adding to it, and
279
+ the rendered padding matches the measurement (the border supplies the first
280
+ unit). walletSidebar members keep their legacy 68/92 presets, which never
281
+ applied the `size` adjustment. The shared container pass records its own inline
282
+ writes and the engine (and WalletGroup, per member) undoes them before the
283
+ renderer rebinds, so alignment set on template children does not leak into a
284
+ reused, unstyled row and a renderer value equal to the previous container value
285
+ is never reverted. DataRow measurement is layout-aware again (table rows
286
+ without secondary text are 48) and linear columns keep the legacy structure:
287
+ secondary leading text inline before the primary text, secondary text directly
288
+ below. Selector geometry follows either explicit height field. A disabled
289
+ WalletGroup member can start the group drag and emit its own actions again
290
+ while its member press stays blocked; title-help hover checks only the resolved
291
+ member. Every System retry (Market or not) is message-only with a row-press
292
+ action, as in the legacy engine. Text styling no longer reads computed style, so
293
+ attached and detached rows style identically.
294
+
295
+ Review round 3 (2026-09-24). Web: a Market subscript run keeps the legacy
296
+ `ceil(0.6 × fontSize)` size on a `fontSize` line box when the field has an
297
+ explicit `fontSize`, and iOS/Android again draw it at `ceil(0.6 × fontSize)` on the
298
+ field's own line height (legacy on each platform);
299
+ an automatic-height System warning is laid out at its rendered border-box
300
+ height again; System and MetricCard rebuild their text when a text style
301
+ changes, so clearing `lines`/`offsetY` restores the original text and removes
302
+ the layout wrapper; a reused visual restores `margin-bottom`, so a cleared
303
+ walletSidebar `leadingGap` leaves no residue. iOS and Android gate every
304
+ selector explicit-height geometry on `style.container.height ?? row.height`
305
+ (Android's list-wide source scale stays keyed on `row.height` only); Android
306
+ rebinds the fixed footer on a `listStyle`-only snapshot.
307
+ Validation: package typecheck and 180 tests pass (jsdom/unit level); this is
308
+ not new rendered browser or native device evidence.
309
+
310
+ ### Platform interaction and appearance differences (legacy, retained)
311
+
312
+ These are pre-existing platform behaviors recorded after the 2026-09-24 native
313
+ audit; they are not new in this change.
314
+
315
+ - **Disabled rows and actions.** iOS blocks every action on a disabled row
316
+ (cell interaction off plus an action-emission guard). Android blocks text
317
+ accessories (radio, switch, `⋮` menu), checkboxes, Activity footer buttons and
318
+ System Retry, but still emits trailing/leading icon actions, Market badges,
319
+ media close, title help and WalletGroup member actions; a disabled group does
320
+ not block its members' actions on Android. Web (legacy) blocks row press and
321
+ click actions on a disabled row or disabled WalletGroup. A disabled member
322
+ inside an enabled group still emits its own actions, but its member press is
323
+ blocked.
324
+ - **Web hover actions.** Web only: a title marked `titleActionOnHover` or an icon
325
+ accessory with `hoverActionKey` emits that action with an anchor on
326
+ `pointerover` (not on moves inside the element) and invalidates the anchor
327
+ with reason `pointerLeave` on `pointerout`. The check is the resolved source's
328
+ `disabled` only: a WalletGroup member's own flag, never the group's, so a
329
+ member of a disabled group still emits its hover action (legacy). Native has
330
+ no hover; the same keys fire on tap.
331
+ - **System retry.** Android and iOS show a literal "Retry" button on non-Market
332
+ retry rows and read `actionText` only for the Market retry. Web keeps its
333
+ legacy rendering for every presentation: a retry row shows only its message
334
+ and the row press (click, Enter or Space) emits `actionKey` with a `row`
335
+ anchor; no retry button is drawn. `actionText` and `style.actionText` are
336
+ accepted by validation and have no Web target (native only).
337
+ - **Pressed corners.** Native pressed feedback ignores `groupPosition` and uses
338
+ 12 on all corners; templates with their own resting radius keep it (Rail 8,
339
+ MediaTile 16). iOS walletSidebar identity rows use 20; Android has no
340
+ wallet-sidebar exception (12). Web changes only the pressed background and
341
+ keeps the resting (group or template) radius.
342
+ - **WalletGroup row appearance.** The group's row-level `backgroundColor` is
343
+ ignored on iOS and Android (legacy), in both the resting and the
344
+ `backgroundFullWidth` fill: the group fill is
345
+ `style.container.backgroundColor` or the theme `subduedBackground`. Web
346
+ (legacy) applies it inline over the group fill. Use
347
+ `style.container.backgroundColor` for a cross-platform group fill.
348
+ - **WalletGroup height.** iOS and Android (legacy) ignore the group's
349
+ `row.height`: `style.container.height` wins, otherwise the height comes from
350
+ the members. Web (legacy) honors `row.height` for a WalletGroup like any other
351
+ row.
352
+ - **Text direction.** `start`/`end` text alignment follows the layout direction
353
+ on all platforms. On iOS a runtime layout-direction change re-resolves it:
354
+ visible rows and the fixed footer rebind immediately, offscreen rows on reuse.
355
+ - **Separator inset.** Identity rows default to a 60-unit inset and other
356
+ templates to 12 on native; Web defaults to 0 (STYLE_SPEC §6.2).
357
+ - **DataRow linear layout.** See ROW_TEMPLATES.md: native unstyled linear rows
358
+ keep the legacy single-label column.