Skip to content

feat: add search, column filters and server-driven data mode - #1

Merged
ahmdshrif merged 3 commits into
mainfrom
feat/filtering
Sep 17, 2026
Merged

ahmdshrif merged 3 commits into
mainfrom
feat/filtering

Conversation

@ahmdshrif

Copy link
Copy Markdown
Owner

Reopened after the repository was recreated. Combines the previous PR #1 (search and column filters) and PR #2 (server-driven data mode, already merged into this branch).

Search and column filters

  • searchText: matches shown cell text, ignoring case and accents. The search index is built on the first search and reused until data or columns change.
  • columnFilters: text, values, range and custom filters, by column key.
  • Range filters reject NaN, invalid dates and non-numeric cells, and ignore invalid bounds.
  • Row keys recompute when keyExtractor changes; identical key arrays keep their identity.
  • Example perf monitor reports "long frame intervals" (> 25 ms); README no longer implies virtualization removes whole-dataset work or that Android performance is proven.

Server-driven data mode

  • manualSorting: keeps the order of data; the header still shows sort and taps still call onSortChange.
  • manualFiltering: shows data without applying searchText or columnFilters locally.
  • loading: spinner only while there are no rows; existing rows stay visible during a new query.
  • loadingMore, refreshing / onRefresh, onEndReached / onEndReachedThreshold, error / onRetry.
  • The app owns fetching, pagination, retries and cancellation.
  • Example app: Local and Server tabs. The Server tab pages a fake API (5,000 rows, 50 per page, 700 ms latency) with server-side sort, search and status filter, plus a "Fail next request" switch.

Testing

  • 37 unit tests, lint and typecheck pass.
  • iOS 26 simulator, Release build: search and filter chips (884 then 53 of 10,000 rows), first page load, load more (50 → 150), failed page shows footer error with Retry while rows stay visible, Retry recovers, server sort, pull-to-refresh.
  • Android emulator (API 35), Release build: load more and pull-to-refresh.
  • Not tested on a physical device.

Known follow-up

  • After a new sort or filter, the list keeps its scroll offset, so a deep scroll position can trigger onEndReached right away. A scrollToTop ref method or reset option would fix this.

- searchText prop matches shown cell text, ignoring case and accents, with a
  lazily built search index reused until data or columns change
- columnFilters prop with text, values, range and custom filters
- Range filters reject NaN, invalid dates and non-numeric cells, and ignore
  invalid bounds
- Recompute row keys when keyExtractor changes while keeping identical key
  arrays stable
- Label perf monitor counts as long frame intervals and qualify README
  performance claims
- Example app: search box and status/amount filter chips
- manualSorting keeps the supplied row order while the header still shows
  sort and taps still call onSortChange
- manualFiltering shows supplied rows without local search or filters
- loading shows a spinner only while there are no rows, so existing rows
  stay visible during a new query
- loadingMore footer, pull-to-refresh (refreshing/onRefresh), onEndReached,
  and error with optional Retry in the empty state or footer
- getVisibleRows helper with tests for manual modes
- Example app: Local and Server tabs; the Server tab pages a fake API with
  latency, server-side sort/search/status filter, refresh, load more and a
  fail-next-request switch
feat: add server-driven data mode
@ahmdshrif
ahmdshrif merged commit 58995e0 into main Sep 17, 2026
6 checks passed
@ahmdshrif
ahmdshrif deleted the feat/filtering branch September 17, 2026 11:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant