Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
345fef5
docs(native-list): add the shared style spec and drop dead web CSS
huhuanming Sep 16, 2026
fc23d4a
feat(native-list): add the per-template row style and apply it on Web
huhuanming Sep 16, 2026
94f2a3f
feat(native-list): apply the row style on iOS and Android
huhuanming Sep 16, 2026
5c6f59d
feat(example): add the Native List Row Style page
huhuanming Sep 16, 2026
3e9db1d
feat(native-list): add listStyle for separator and group chrome
huhuanming Sep 16, 2026
b47323b
docs(native-list): define illustrated templates and shared capability…
huhuanming Sep 22, 2026
09baf11
fix(native-list): align style targeting and isolation with audited spec
huhuanming Sep 22, 2026
7fa6bb5
docs(native-list): assign overflow handling to integrators
huhuanming Sep 22, 2026
0cd8663
fix(native-list): align row style contracts across renderers
huhuanming Sep 22, 2026
8d9260a
feat(native-list): define container and text layout styles
huhuanming Sep 22, 2026
656de36
fix(native-list): align row styles and support styled heights
huhuanming Sep 22, 2026
c33a5b1
test(native-list): lock message binding and style reset behavior
huhuanming Sep 22, 2026
1bfb5c2
refactor(native-list): isolate web message renderer
huhuanming Sep 22, 2026
fe2f5fc
refactor(native-list): isolate Android message binding and style targets
huhuanming Sep 22, 2026
d77c555
refactor(native-list): isolate iOS message binding and measurement
huhuanming Sep 22, 2026
929a100
docs(native-list): record message migration and runtime acceptance
huhuanming Sep 22, 2026
24af968
docs(native-list): record iOS simulator runtime acceptance
huhuanming Sep 22, 2026
7652d6d
refactor(native-list): partition web Message row reuse
huhuanming Sep 22, 2026
0893434
refactor(native-list): route Android Message through its own view type
huhuanming Sep 22, 2026
f821913
refactor(native-list): reload iOS rows when renderer reuse changes
huhuanming Sep 22, 2026
6a94b01
docs(native-list): record structural reuse boundaries and acceptance
huhuanming Sep 22, 2026
b191286
Merge latest main into native list spec migration
huhuanming Sep 22, 2026
8f50055
docs(native-list): track the six-stage renderer migration contract
huhuanming Sep 22, 2026
67e2c01
refactor(native-list): let iOS Message own its text subtree
huhuanming Sep 22, 2026
0fa4881
refactor(native-list): let Android Message own its text subtree
huhuanming Sep 22, 2026
a756669
docs(native-list): record Message text ownership and runtime acceptance
huhuanming Sep 22, 2026
754e764
docs(native-list): complete migration baseline and Message exit contract
huhuanming Sep 22, 2026
987bcdb
refactor(native-list): complete Android Message renderer host
huhuanming Sep 22, 2026
8eb6f45
refactor(native-list): retain Web Message views and resolve layout
huhuanming Sep 22, 2026
22a0278
refactor(native-list): complete iOS Message renderer host
huhuanming Sep 22, 2026
ac91a33
fix(native-list): isolate Message image styles from corner badges
huhuanming Sep 22, 2026
5c9c71d
docs(native-list): close baseline and Message migration stages
huhuanming Sep 22, 2026
fc6f42c
docs(native-list): define simple-template migration acceptance
huhuanming Sep 22, 2026
471903c
fix(native-list): default Android text offset to zero
huhuanming Sep 22, 2026
6262020
refactor(native-list): share lightweight renderer host lifecycle
huhuanming Sep 22, 2026
21e7977
refactor(native-list): migrate Android Rail renderer
huhuanming Sep 22, 2026
8d62bff
refactor(native-list): migrate iOS Rail renderer
huhuanming Sep 22, 2026
6b53b35
refactor(native-list): persist Web Rail renderer views
huhuanming Sep 22, 2026
0d8d06f
docs(native-list): record Rail migration and runtime acceptance
huhuanming Sep 22, 2026
83cbecc
refactor(native-list): migrate MediaTile renderer on three platforms
huhuanming Sep 23, 2026
a57ef84
refactor(native-list): migrate Action renderer on three platforms
huhuanming Sep 23, 2026
46639d9
refactor(native-list): isolate System states and measurement
huhuanming Sep 23, 2026
f2a957a
refactor(native-list): migrate Activity views and footer actions
huhuanming Sep 23, 2026
a22a9dc
refactor(native-list): migrate DataRow columns and selection
huhuanming Sep 23, 2026
52e5a18
test(native-list): use DataRow fixture rows explicitly
huhuanming Sep 23, 2026
be8a3e7
fix(native-list): preserve DataRow table padding defaults
huhuanming Sep 23, 2026
72793e0
refactor(native-list): complete MetricCard renderer migration
huhuanming Sep 23, 2026
107efab
refactor(native-list): keep iOS measurement with renderer hosts
huhuanming Sep 23, 2026
98c87db
refactor(native-list): extract complex Web row renderers
huhuanming Sep 23, 2026
dfcd79a
refactor(native-list): register complex Android row hosts
huhuanming Sep 23, 2026
a3eeec5
refactor(native-list): register complex iOS row hosts
huhuanming Sep 23, 2026
b61199f
fix(native-list): lay out sticky overlays and narrow text helpers
huhuanming Sep 23, 2026
81fd3b3
docs(native-list): complete stage four and make header examples explicit
huhuanming Sep 23, 2026
a13172a
refactor(native-list): register keyed WalletGroup web renderer
huhuanming Sep 23, 2026
9c4b01c
refactor(native-list): compose WalletGroup from keyed iOS Identity hosts
huhuanming Sep 23, 2026
94351a6
refactor(native-list): compose WalletGroup from keyed Android Identit…
huhuanming Sep 23, 2026
3bead8a
fix(native-list): gate disabled WalletGroup member interactions
huhuanming Sep 23, 2026
63e8131
docs(native-list): complete WalletGroup migration and runtime acceptance
huhuanming Sep 23, 2026
86b925c
refactor(native-list): remove obsolete native row hosts
huhuanming Sep 23, 2026
cc409d4
refactor(native-list): retire key styling and renderer fallbacks
huhuanming Sep 23, 2026
969f722
docs(native-list): complete renderer cleanup and acceptance
huhuanming Sep 23, 2026
8370509
style(native-list): remove extra blank lines at EOF
huhuanming Sep 23, 2026
221730b
fix(native-list/android): restore legacy row rendering in renderer re…
huhuanming Sep 24, 2026
45818d4
fix(native-list/ios): restore legacy row rendering in renderer registry
huhuanming Sep 24, 2026
cfb34b7
fix(native-list/web): restore legacy rendering and sync spec
huhuanming Sep 24, 2026
0fb97d2
fix(native-list/android): keep user styles over restored legacy defaults
huhuanming Sep 24, 2026
a25876a
fix(native-list/ios): exact badge gap, typed change detection, direct…
huhuanming Sep 24, 2026
1d8f32b
fix(native-list/web): restore legacy retry and hover, align docs
huhuanming Sep 24, 2026
2dcd575
fix(native-list/android): honor container height for selectors, rebin…
huhuanming Sep 24, 2026
4b64ee4
fix(native-list/ios): honor container height for selectors, walletGro…
huhuanming Sep 24, 2026
b08c2a5
fix(native-list/web): restore warning measurement and style clearing
huhuanming Sep 24, 2026
a54f572
fix(native-list): address review feedback
huhuanming Sep 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,34 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

### Features
- **native-list**: Add `snapshot.listStyle` for list chrome: `separator.inset`, `separator.color`, and `groupCornerRadius`, applied on all three platforms. The surface carries only what every platform can honour — pull to refresh is a system control on both native platforms, the section index belongs to `capabilities.sectionIndex`, and the reorder preview is drawn with platform-specific primitives — and `validateSnapshot` rejects any other key rather than accepting one that some platform would ignore. Every value is absent by default and each platform keeps its own number as the fallback, so an untouched list renders exactly as before; on Web the inset separator keeps a transparent border for layout and paints the line with a logical-inset overlay, so row heights do not move.
- **native-list**: Render every row through a closed renderer registry on iOS, Android and Web. Each of the 12 templates (Message, Rail, MediaTile, Action, System, Activity, DataRow, MetricCard, Market, Identity, SectionHeader and WalletGroup) owns its view tree, defaults, style mapping, binding and measurement; a shared host owns container appearance, events and binding invalidation. Renderer reuse is keyed by template family, so a same-key template change replaces an incompatible host, and every bind restores the current template's defaults without a preceding recycle. WalletGroup members are independent Identity renderers. The legacy native row monoliths, the global style-slot maps and the Web legacy pool are removed. See `native-views/react-native-native-list/docs/SPEC.md`.
- **native-list**: Add a bounded per-template row style. `style` keys name the model field they modify rather than the view that carries it, and each template renderer maps the key to the view that renders that field. Typography can be given as a named step (`{ token: '$bodyLg' }`) which is resolved to numbers in JavaScript before serialization, so no native renderer learns the vocabulary; explicit values still override. Keys a template does not declare are rejected by `validateSnapshot` and `validatePatches` (see Breaking Changes), and styles carried by a patch are resolved the same way. Text slots, template-applicable image/padding/gap parameters and a shared `style.container` (explicit `height`, background, opacity, corner radius, border and content alignment) are implemented on Web, iOS and Android. Height precedence is `style.container.height` → `row.height` → template measurement, and selector presentations use their explicit-height geometry whichever field supplies the height; without an explicit height, measured templates may change height with their styled metrics. Automatic overflow fitting remains the integrator's responsibility.
- **image**: New `resizeHeight` view prop, the pair of `resizeWidth`, so a non-square image can hand the pre-layout probe the same hints its preload used.

### Breaking Changes
- **native-list**: Remove implicit row-key styling; callers now choose `variant`, `style` and `separator` explicitly. A `history-` prefix on a section header's row key or section key no longer selects history typography or the 16-unit header height (use `variant: 'history'`). Android no longer gives the `linear-tokens` and `action-tokens` section headers token-manager typography, padding and 30-unit height (declare them with `style`). Android no longer suppresses `separator: true` for `token-*`, `balance-token-*` and `linear-custom-token` rows. The app-monorepo callers audited in the package `docs/MIGRATION_BASELINE.md` already use the explicit fields.
- **native-list**: Automatic (intrinsic) Message row heights change: measurement now uses the resolved text, spacing and image metrics of the rendered views instead of the old estimator-only defaults. Rows with `row.height` or `style.container.height` are unaffected.
- **native-list**: Row style validation is strict. `validateSnapshot` and `validatePatches` throw for any `style` key a template does not declare, for unknown nested text/image/container keys, and for unknown Market badge style keys, where extra keys used to be ignored. Colors must be `#RRGGBB` or `#RRGGBBAA`, including `listStyle.separator.color`. Every key sent by the app-monorepo Market list builder (`marketNativeListRows.ts`) still validates.

### Bug Fixes
- **native-list**: Review fixes for the renderer migration. Restore the legacy unstyled rendering of every template inside the new renderers (for example native linear DataRow single-label columns, pressed-row corners, Activity/Identity leading slots, and WalletGroup appearance and drag rules), without restoring key-based styling. Fix an Android sticky-header overlay crash and a leaked pre-draw listener on detached lists. On Web, keep loaded MetricCard images visible after rebinding, restore the legacy message-only retry row (no Web retry button for any presentation) and disabled WalletGroup member actions, include WalletGroup vertical padding in its height, and stop container alignment leaking into reused rows. On iOS, make `end` text alignment follow RTL layout and cache Message text measurement to cut its per-bind cost.
- **native-list**: Second legacy-parity review round. Web: remove the Market retry button, keep hover title actions keyed on the member only, make WalletGroup `verticalPadding` replace the legacy border inset in measurement and rendering, and undo container writes before each renderer rebind. Android: switch DataRow off the legacy layout only for its text-style keys, apply selector source-scale typography to every row text while honouring an explicit `fontSize`/`lineHeight`, let `truncate` override the Market retry/noMatch ellipsis, and restore the legacy wallet leading-overlay metrics. iOS: exact `titleBadgeGap` inside legacy badge pills, type-aware theme/listStyle change detection, start/end alignment re-resolved on layout-direction change (including the footer), and WalletGroup ignores `row.height` as before.
- **native-list**: Third review round. Keep Market subscripts at the legacy 60% of an explicit `fontSize` on all platforms. Web: lay out automatic-height System warnings at their rendered height again, and make clearing System/MetricCard text styles or a walletSidebar `leadingGap` match a fresh unstyled render. iOS/Android: selector geometry follows `style.container.height` as well as `row.height`; Android rebinds the fixed footer on a `listStyle`-only change; WalletGroup ignores row-level `backgroundColor` in the native full-width fill.
- **native-list**: Align the configurable row-style contract across Web, iOS and Android. Apply non-Market image/spacing overrides; isolate primary and secondary data-column text in linear/table layouts; preserve styles through selection and summary updates; reuse the ordinary Android row renderer for pinned headers including values and checkboxes. Reject template-inapplicable box keys and nonportable text colors. Keep template structure, local styling and shared list capabilities distinct; overflow fitting remains caller-owned.
- **native-list**: Apply Web selector styles after presentation defaults, isolate wallet-member styles, and target composite metric-card headings by their semantic role. Restore native text state on reuse while retaining unspecified iOS attributed-string properties. Propagate Android list chrome on initial snapshots and restrict custom group radius to actual grouped rows. Reject malformed nested text/image styles and unknown nested keys; developers integrating the list own overflow prevention.
- **image (iOS)**: Show a memory-cached image on the mount frame instead of an icon skeleton (OK-63873). The memory probe skipped every image whose JS side left `cachePolicy` unset (Fabric hands Nitro a nil, which the request path already treats as memory-disk), and before layout it keyed the decode thumbnail from the empty bounds, so a freshly mounted image never matched what the prewarm or a previous mount had stored. The probe now coalesces a nil policy to memory-disk and, before layout, tries the decode-thumbnail keys the laid-out request (`resizeWidth`/`resizeHeight` hint + the view's `contentFit`) and a preload (hint + cover) would use. An image already on screen for the same identity is kept as the placeholder while a load for another key runs, instead of being blanked to a skeleton.
- **image**: Clip the RN overlay container to the same circle as a `round` native image. `round` clips the native view to an oval on Android and to a `min(width, height) / 2` corner radius on iOS, but the wrapper that hosts a custom `placeholder` or `fallback` only ever clipped to the caller's own `borderRadius`, so those overlays were painted square over a round image — against the clipping contract the README states. The container and the drawn border overlay now take a percentage radius when `round` is set, overriding any per-corner radius from the caller's style.

### Features
- **image**: New `resizeHeight` view prop, the pair of `resizeWidth`, so a non-square image can hand the pre-layout probe the same hints its preload used.
### Documentation
- **native-list**: Audit the consolidated spec against template definitions, local layout responsibility and common container capabilities. Assign overflow handling to integrators and document existing structural headers, fixed/scrolling footers and pager header composition.
- **native-list**: Consolidate the row-style spec on current main. Define all 12 row types with structural diagrams, local style/layout boundaries, and shared header/footer, section, scroll and indexed-bar ownership. Record implementation and example-coverage gaps separately from the contract.
- **native-list**: Add `docs/STYLE_SPEC.md`, the shared style vocabulary for rows, section headers, fixed footers, and empty states. It records the design tokens (aliased to the application's own token names), the per-template style surface keyed by model field, list chrome, the template isolation rules, and a review checklist. Legacy row-height, typography and Android baseline scaling differences are documented separately from the unified configurable style contract.

### Chores
- Add the "Native List Row Style" example page with plain/styled pairs for all 12 row types, plus list chrome and explicit-height examples. Dated per-stage runtime acceptance of the renderer migration on iOS, Android and Web is recorded in the package `docs/DESIGN.md`; it is not a pixel-parity or scrolling-performance signoff.
- **native-list (Web)**: Remove dead duplicated rules from `WEB_LIST_CSS`. Four blocks (`.ok-native-list-footer`/`-sticky`/`-index-rail`/`-index-button`, `-refresh`, `-warning`, `-subtitle-segments`) were emitted twice and a `prefers-reduced-motion` block three times; every property of the earlier copies was redeclared by the later ones, so removing them changes no rendering.
- Stop tracking `nitrogen/generated` for `react-native-image` and `react-native-native-list`. Every other Nitro package already ignores `nitrogen/` and regenerates it from the spec at release time; these two were missing a package `.gitignore`, so 117 generated files rode along in every diff that touched a prop. `react-native-native-list` now runs `yarn nitrogen` in its `release` script like the other view packages, and local builds need `yarn nitrogen` in the package before the first native build.
- No version bump here; these changes ship with the next release. Note that 3.0.157 was published from this branch before the review fixes landed and should not be used.

Expand Down
12 changes: 12 additions & 0 deletions example/react-native/pages/NativeListExamplePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2137,6 +2137,12 @@ const actionRows: readonly RowModel[] = [
key: 'action-token-section-header',
sectionKey: 'action-tokens',
title: 'Tokens',
style: {
container: { height: 30, contentVerticalAlignment: 'bottom' },
horizontalPadding: 12,
verticalPadding: 0,
title: { fontSize: 14, lineHeight: 20, fontWeight: 'regular' },
},
},
...tokenManagerRows,
{ type: 'system', key: 'action-section-gap', variant: 'spacer', height: 64 },
Expand Down Expand Up @@ -2417,6 +2423,12 @@ function snapshotFor({
key: 'linear-token-section-header',
sectionKey: 'linear-tokens',
title: 'Tokens',
style: {
container: { height: 30, contentVerticalAlignment: 'bottom' },
horizontalPadding: 12,
verticalPadding: 0,
title: { fontSize: 14, lineHeight: 20, fontWeight: 'regular' },
},
},
...tokenManagerRows,
],
Expand Down
Loading
Loading