packages/lynx-ui-feed-list/SKILL.md
# lynx-ui-feed-list SKILL `FeedList` is a high-performance feed stream list component, built upon `List`. It encapsulates common feed scenarios such as **pull-to-refresh** and **load more**, allowing developers to quickly build feed list pages. Note: Use `FeedList` only when you need pull-to-refresh and load-more behaviors. For regular virtual lists without these features, prefer using `List` directly. ## 1. Core Capabilities - **High-Performance Virtual List**: Inherits all the performance
npx skillsauth add lynx-family/lynx-ui packages/lynx-ui-feed-listInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
FeedList is a high-performance feed stream list component, built upon List. It encapsulates common feed scenarios such as pull-to-refresh and load more, allowing developers to quickly build feed list pages.
Note: Use FeedList only when you need pull-to-refresh and load-more behaviors. For regular virtual lists without these features, prefer using List directly.
List, including virtual scrolling and multi-layout support (single, flow, waterfall).refreshOptions, supports custom refresh headers.onScrollToLower, loadMoreFooter, and noMoreDataFooter to implement pagination states.Popup) via main-thread:gesture.When using FeedList, you MUST provide listId and listType, and use <list-item> as the direct child. To enable pull-to-refresh and load more, you also need to configure the corresponding props and get the instance via ref to control the state.
import { useRef } from '@lynx-js/react'
import { FeedList, FeedListRef } from '@lynx-js/lynx-ui'
function BasicFeedList() {
const feedListRef = useRef<FeedListRef>(null)
const items = Array.from({ length: 20 }, (_, i) => `Item ${i}`)
const handleRefresh = () => {
console.log('Refreshing...')
setTimeout(() => {
feedListRef.current?.finishRefresh()
}, 2000)
}
const handleLoadMore = () => {
console.log('Loading more...')
// After loading, you might need to call feedListRef.current?.changeHasMoreStatus(false);
}
return (
<FeedList
ref={feedListRef}
listId='my-feed-list'
listType='single'
refreshOptions={{ onRefresh: handleRefresh }}
onScrollToLower={handleLoadMore}
style={{ width: '100%', height: '500px' }}
>
{items.map(item => (
<list-item item-key={item} key={item}>
<view style={{ height: '60px' }}>{item}</view>
</list-item>
))}
</FeedList>
)
}
Scenario Description + Layout Configuration + Refresh and Load More Logic + Custom UI
Example Prompt:
FeedList. When pulled down, it triggers a refresh operation, and the refresh animation should be stopped after 2 seconds."FeedList. When scrolled to the bottom, it triggers a load more function. When there is no more data, display a ‘No more data’ footer."FeedList to be a Lottie animation."A list with pull-to-refresh and load more functionality.
import { useRef, useState } from '@lynx-js/react';
import { FeedList, FeedListRef } from '@lynx-js/lynx-ui';
function FullFeaturedFeedList() {
const listRef = useRef<FeedListRef>(null);
const [items, setItems] = useState([...]);
const [hasMore, setHasMore] = useState(true);
const onRefresh = async () => {
const newData = await fetchNewData();
setItems(newData);
listRef.current?.finishRefresh();
setHasMore(true); // Reset hasMore status on refresh
listRef.current?.changeHasMoreStatus(true);
};
const onLoadMore = async () => {
if (!hasMore) return;
const moreData = await fetchMoreData();
if (moreData.length > 0) {
setItems([...items, ...moreData]);
} else {
setHasMore(false);
listRef.current?.changeHasMoreStatus(false);
}
};
return (
<FeedList
ref={listRef}
listId="feed"
listType="single"
refreshOptions={{ onRefresh }}
onScrollToLower={onLoadMore}
loadMoreFooter={<text>Loading...</text>}
noMoreDataFooter={<text>-- End --</text>}
>
{/* ... list-items ... */}
</FeedList>
);
}
Example Path: apps/examples/src/FeedList/Basic/index.tsx
Combine listType: 'flow' to create a feed in a grid layout.
<FeedList
listId='grid-feed'
listType='flow'
spanCount={2}
{...otherProps}
>
{/* ... */}
</FeedList>
Example Path: apps/examples/src/FeedList/Grid/index.tsx
FeedList displays two footer variants:
loadMoreFooter: shown when there is more data to loadnoMoreDataFooter: shown when all data has been loadedFooters are controlled exclusively via ref.current.changeHasMoreStatus(hasMore). They are not linked to refresh status or diff results.
import { useRef, useState } from '@lynx-js/react'
import { FeedList, FeedListRef } from '@lynx-js/lynx-ui'
function FooterStateExample() {
const listRef = useRef<FeedListRef>(null)
const [hasMore, setHasMore] = useState(true)
const onScrollToLower = () => {
// fetch more...
const more = await fetchMore()
if (more.length === 0) {
setHasMore(false)
listRef.current?.changeHasMoreStatus(false) // switch to noMoreDataFooter
}
}
const onRefresh = async () => {
// refresh resets footer state if needed
setHasMore(true)
listRef.current?.changeHasMoreStatus(true) // back to loadMoreFooter
listRef.current?.finishRefresh()
}
return (
<FeedList
ref={listRef}
listId='feed'
listType='single'
refreshOptions={{ onRefresh }}
onScrollToLower={onScrollToLower}
loadMoreFooter={<text>Loading…</text>}
noMoreDataFooter={<text>-- End --</text>}
>
{/* ... list-items ... */}
</FeedList>
)
}
Q: After triggering onRefresh, the refresh header persists. What should I do?
A: FeedList does not automatically end the refresh animation. Call ref.current.finishRefresh() after your data request completes; otherwise, the refresh header remains visible.
Q: After loading all data, the load more footer is still displayed. How do I stop it?
A: Call ref.current.changeHasMoreStatus(false) to indicate there is no more data, and display noMoreDataFooter instead of loadMoreFooter.
Q: When should I use FeedList vs List?
A: Use FeedList only when you need pull-to-refresh and load-more behaviors. For regular virtual lists without these features, prefer using List directly.
<list-item>: This is a built-in tag, not a React component provided by lynx-ui. It must be the direct child of FeedList and must have a unique item-key and key property. All content for a list item should be placed inside this tag.development
# lynx-ui-sortable SKILL `Sortable` is a headless drag-to-reorder list primitive for ReactLynx. It performs reordering on the main thread for smooth, gesture-driven animations and exposes a composable `SortableRoot` / `SortableItem` / `SortableItemArea` API. For massive datasets, prefer `List` or `FeedList`; `Sortable` targets small to medium reorder-able lists. ## 1. Core Capabilities - **Headless Composition**: Three building blocks — `SortableRoot`, `SortableItem`, and (optional) `Sortable
development
# lynx-ui-sheet SKILL ## What It Is `lynx-ui-sheet` is a headless Sheet primitive for ReactLynx. It supports bottom-sheet semantics and side-drawer semantics through the same composition model, state model, drag handling, backdrop, and snap-point APIs. Use it when a UI needs a dismissible panel that slides from an edge of the viewport and may be controlled by refs, external state, snap points, or drag gestures. ## Building Blocks - **`SheetRoot`**: Owns visibility state, side, snap points,
development
# Lynx UI Popover SKILL `lynx-ui-popover` is a headless primitive for building accessible, positioned floating elements. It handles the complex logic of positioning, stacking context, and enter/exit animations via `usePresence`. ## 1. Core Capabilities - **Headless & Composable**: Provides raw functional components (`Root`, `Trigger`, `Positioner`, `Content`) that you compose to build custom UIs. - **Auto Positioning**: The `PopoverPositioner` automatically calculates coordinates to anchor th
development
# lynx-ui-dialog SKILL `Dialog` is a dialog component, used to display important information or require user interaction, interrupting the current workflow. `lynx-ui-dialog` is a composite component built on `primitives`, offering high flexibility and customizability. ## 1. Core Capabilities - **Composite Component Structure**: Composed of `DialogRoot`, `DialogView`, `DialogBackdrop`, `DialogContent`, `DialogTrigger`, and `DialogClose`, allowing for free assembly of the dialog's structure. -