diff --git a/README.md b/README.md index 7636c3d..fcb83a6 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,12 @@ The monorepo for react-hook-window project. It contains: - [`@react-hook-window/use-windowed-list`][use-windowed-list] - React hook to render only the visible items in a container. -- [`@react-hook-window/use-infinite-loader`][use-infinite-loader] - React hook to manage infinite loading of windoed list items. +- [`@react-hook-window/use-items-loader`][use-items-loader] - React hook to manage infinite loading of windowed list items. [use-windowed-list]: /packages/use-windowed-list -[use-infinite-loader]: /packages/use-infinite-loader +[use-items-loader]: /packages/use-items-loader [lerna]: https://lerna.js.org/ [commitizen]: http://commitizen.github.io/cz-cli diff --git a/package.json b/package.json index 8cb1d34..b3a45f0 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,8 @@ "prebootstrap": "yarn build", "bootstrap": "yarn lerna bootstrap", "clean:use-windowed-list": "yarn workspace @react-hook-window/use-windowed-list clean", - "clean:use-infinite-loader": "yarn workspace @react-hook-window/use-infinite-loader clean", - "clean": "yarn clean:use-windowed-list && yarn clean:use-infinite-loader", + "clean:use-items-loader": "yarn workspace @react-hook-window/use-items-loader clean", + "clean": "yarn clean:use-windowed-list && yarn clean:use-items-loader", "prebuild": "yarn run clean", "build": "rollup --config", "test": "jest ./tests", diff --git a/packages/use-infinite-loader/README.md b/packages/use-infinite-loader/README.md deleted file mode 100644 index 886fa7c..0000000 --- a/packages/use-infinite-loader/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# `use-infinite-loader` - -React hook to manage infinite loading of windoed list items. diff --git a/packages/use-items-loader/README.md b/packages/use-items-loader/README.md new file mode 100644 index 0000000..fc6932b --- /dev/null +++ b/packages/use-items-loader/README.md @@ -0,0 +1,679 @@ +# `use-items-loader` + +React hook to manage pagination or infinite loading of a windowed list items. + +## Getting started + +Install with Yarn: + +```bash +yarn add @react-hook-window/use-items-loader +``` + +Install with NPM: + +```bash +npm install @react-hook-window/use-items-loader --save +``` + +## Infinite loading usage + +Consider a social network feed like one on Instagram, Facebook, YouTube, etc. That case is an infinite loading list, where an application can always render a loading placeholder while the next page is loading. As soon as the loading placeholder becomes visible, the app starts the next page loading. + +
+ + Show an infinite loading illustration. + + +
+ +Consider page size equals to 3 items. + +``` +                    load first page       ▶         scroll down         ▶       load next page        ▶         scroll down         ▶       load next page +┏┯━━━━━━━━━━━━━━━━━━━━━┯┓     ┏┯━━━━━━━━━━━━━━━━━━━━━┯┓      ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐ +┃│       LOADING       │┃     ┃│ #0                  │┃      │ #0                  │       │ #0                  │       │ #0                  │       │ #0                  │ +┃│   PLACEHOLDER       │┃     ┃│                     │┃      │                     │       │                     │       │                     │       │                     │ +┃└─────────────────────┘┃     ┃├─────────────────────┤┃     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓      ├─────────────────────┤       ├─────────────────────┤ +┃                       ┃     ┃│ #1                  │┃     ┃│ #1                  │┃     ┃│ #1                  │┃      │ #1                  │       │ #1                  │ +┃                       ┃     ┃│                     │┃     ┃│                     │┃     ┃│                     │┃      │                     │       │                     │ +┃                       ┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤ +┃                       ┃     ┃│ #2                  │┃     ┃│ #2                  │┃     ┃│ #2                  │┃      │ #2                  │       │ #2                  │ +┗━━━━━━━━━━━━━━━━━━━━━━━┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┃│                     │┃     ┃│                     │┃     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓ +                               ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃ +                               │       LOADING       │      ┃│       LOADING       │┃     ┃│ #3                  │┃     ┃│ #3                  │┃     ┃│ #3                  │┃ +                               │     PLACEHOLDER     │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┃│                     │┃     ┃│                     │┃     ┃│                     │┃ +                               └─────────────────────┘       └─────────────────────┘      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃ +                                                                                          ┃│ #4                  │┃     ┃│ #4                  │┃     ┃│ #4                  │┃ +                                                                                          ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┃│                     │┃     ┃│                     │┃ +                                                                                           ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃ +                                                                                           │ #5                  │      ┃│ #5                  │┃     ┃│ #5                  │┃ +                                                                                           │                     │      ┃│                     │┃     ┃│                     │┃ +                                                                                           ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃ +                                                                                           │       LOADING       │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛ +                                                                                           │     PLACEHOLDER     │       │     PLACEHOLDER     │       │                     │ +                                                                                           └─────────────────────┘       └─────────────────────┘       ├─────────────────────┤ +                                                                                                                                                       │ #7                  │ +                                                                                                                                                       │                     │ +                                                                                                                                                       ├─────────────────────┤ +                                                                                                                                                       │ #8                  │ +                                                                                                                                                       │                     │ +                                                                                                                                                       ├─────────────────────┤ +                                                                                                                                                       │       LOADING       │ +                                                                                                                                                       │     PLACEHOLDER     │ +                                                                                                                                                       └─────────────────────┘ +``` + +
+
+ +Let’s implement the `InfiniteFeed` windowed component with infinite items loading. Here is a [live demo][todo] with [source code][todo]. + +
+ + Show a windowed infinite loading illustration. + + +
+ +Consider page size equals to 3 items and [`UseWindowedListOptions.overscanCount`][use-windowed-list-options.overscan-count] equals 0. + +Compare it with the “infinite loading illustration” above to get more insights. + +``` +                    load first page       ▶         scroll down         ▶       load next page        ▶         scroll down         ▶       load next page +┏┯━━━━━━━━━━━━━━━━━━━━━┯┓     ┏┯━━━━━━━━━━━━━━━━━━━━━┯┓      ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐ +┃│       LOADING       │┃     ┃│ #0                  │┃      │ start space =       │       │ start space =       │       │ start space =       │       │ start space =       │ +┃│     PLACEHOLDER     │┃     ┃│                     │┃      │ #0.size             │       │ #0.size             │       │ #0.size +           │       │ #0.size +           │ +┃└─────────────────────┘┃     ┃├─────────────────────┤┃     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓      │ #1.size             │       │ #1.size             │ +┃                       ┃     ┃│ #1                  │┃     ┃│ #1                  │┃     ┃│ #1                  │┃      │                     │       │                     │ +┃                       ┃     ┃│                     │┃     ┃│                     │┃     ┃│                     │┃      │                     │       │                     │ +┃                       ┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤ +┃                       ┃     ┃│ #2                  │┃     ┃│ #2                  │┃     ┃│ #2                  │┃      │ #2                  │       │ #2                  │ +┗━━━━━━━━━━━━━━━━━━━━━━━┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┃│                     │┃     ┃│                     │┃     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓ +                               ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃ +                               │ end space =         │      ┃│       LOADING       │┃     ┃│ #3                  │┃     ┃│ #3                  │┃     ┃│ #3                  │┃ +                               │ loading.size        │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┃│                     │┃     ┃│                     │┃     ┃│                     │┃ +                               └─────────────────────┘       └─────────────────────┘      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃ +                                                                                          ┃│ #4                  │┃     ┃│ #4                  │┃     ┃│ #4                  │┃ +                                                                                          ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┃│                     │┃     ┃│                     │┃ +                                                                                           ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃ +                                                                                           │ end space =         │      ┃│ #5                  │┃     ┃│ #5                  │┃ +                                                                                           │ #5.size +           │      ┃│                     │┃     ┃│                     │┃ +                                                                                           │ loading.size        │      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃ +                                                                                           │                     │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛ +                                                                                           │                     │       │     PLACEHOLDER     │       │                     │ +                                                                                           └─────────────────────┘       └─────────────────────┘       ├─────────────────────┤ +                                                                                                                                                       │ end space =         │ +                                                                                                                                                       │ #7.size +           │ +                                                                                                                                                       │ #8.size +           │ +                                                                                                                                                       │ loading.size        │ +                                                                                                                                                       │                     │ +                                                                                                                                                       │                     │ +                                                                                                                                                       │                     │ +                                                                                                                                                       │                     │ +                                                                                                                                                       └─────────────────────┘ +``` + +
+
+ +```tsx +import { useWindowedList } from '@react-hook-window/use-windowed-list' +import { + LoadingItemsRange, + useItemsLoader +} from '@react-hook-window/use-items-loader' + +interface FeedItem { + id: string + content: string +} + +export const InfiniteFeed: React.VFC<{ + feedItemsPlaceholderCount?: number + feedItems: Array + loadNextPage(): void +}> = ({ feedItemsPlaceholderCount = 1, feedItems, loadNextPage }) => { + const { + setContainerRef, + startSpace, + endSpace, + indexes, + isScrolling, + overscanFromIndex, + overscanBeforeIndex + } = useWindowedList({ + containerSize: FEED_CONTAINER_HEIGHT, + itemSize: FEED_ITEM_HEIGHT, + // 1. Reserve extra items for the loading placeholders. + // It might be reasonable to define the value equal to the loading page size. + itemCount: feedItems.length + feedItemsPlaceholderCount + }) + + useItemsLoader({ + // 2. Skip the loading while isScrolling + skip: isScrolling, + overscanFromIndex, + overscanBeforeIndex, + shouldLoadItem: React.useCallback( + // 3. Items further than feedItems are loading placeholders so they should be loaded. + (index: number) => index >= feedItems.length, + [feedItems.length] + ), + loadItemsRange: React.useCallback( + // 4. Just load the next page ignoring loading items range. + (_range: LoadingItemsRange) => loadNextPage(), + [loadNextPage] + ) + }) + + return ( +
+
+ + {indexes.map(index => { + // 5. Render as many placeholders as reserved. + if (index >= feedItems.length) { + return ( +
+ LOADING PLACEHOLDER +
+ ) + } + + const feedItem = feedItems[index] + + return ( +
+ {feedItem.content} +
+ ) + })} + +
+
+ ) +} +``` + +## Finite loading (pagination) usage + +Consider an Internet shop’s searching page where resulting items split into pages. That case is a finite loading list, where an application knows a total count of items but loads them page by page when a user scrolls to an unloaded area. The app might render loading placeholders instead of all unloaded items since the total count is known ahead. + +
+ + Show a finite loading illustration. + + +
+ +Consider page size equals to 3 items with total count of 15 items. + +``` +                    load first page       ▶         scroll down         ▶      load second page       ▶       scroll down far       ▶       load third page       ▶       load fourth page      ▶         scroll down         ▶       load fifth page +┏┯━━━━━━━━━━━━━━━━━━━━━┯┓     ┏┯━━━━━━━━━━━━━━━━━━━━━┯┓      ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐ +┃│ #0    LOADING       │┃     ┃│ #0                  │┃      │ #0                  │       │ #0                  │       │ #0                  │       │ #0                  │       │ #0                  │       │ #0                  │       │ #0                  │ +┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ +┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤ +┃│ #1    LOADING       │┃     ┃│ #1                  │┃      │ #1                  │       │ #1                  │       │ #1                  │       │ #1                  │       │ #1                  │       │ #1                  │       │ #1                  │ +┃│     PLACEHOLDER     │┃     ┃│                     │┃     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓      │                     │       │                     │       │                     │       │                     │       │                     │ +┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤ +┃│ #2    LOADING       │┃     ┃│ #2                  │┃     ┃│ #2                  │┃     ┃│ #2                  │┃      │ #2                  │       │ #2                  │       │ #2                  │       │ #2                  │       │ #2                  │ +┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┃│                     │┃     ┃│                     │┃      │                     │       │                     │       │                     │       │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤ + │ #3    LOADING       │       │ #3    LOADING       │      ┃│ #3    LOADING       │┃     ┃│ #3                  │┃      │ #3                  │       │ #3                  │       │ #3                  │       │ #3                  │       │ #3                  │ + │     PLACEHOLDER     │       │     PLACEHOLDER     │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │       │                     │       │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤ + │ #4    LOADING       │       │ #4    LOADING       │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛      │ #4                  │       │ #4                  │       │ #4                  │       │ #4                  │       │ #4                  │ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤ + │ #5    LOADING       │       │ #5    LOADING       │       │ #5    LOADING       │       │ #5                  │       │ #5                  │       │ #5                  │       │ #5                  │       │ #5                  │       │ #5                  │ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤ + │ #6    LOADING       │       │ #6    LOADING       │       │ #6    LOADING       │       │ #6    LOADING       │       │ #6    LOADING       │       │ #6                  │       │ #6                  │       │ #6                  │       │ #6                  │ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │                     │       │                     │       │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤ + │ #7    LOADING       │       │ #7    LOADING       │       │ #7    LOADING       │       │ #7    LOADING       │       │ #7    LOADING       │       │ #7                  │       │ #7                  │       │ #7                  │       │ #7                  │ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │                     │       │                     │       │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤ + │ #8    LOADING       │       │ #8    LOADING       │       │ #8    LOADING       │       │ #8    LOADING       │       │ #8    LOADING       │       │ #8                  │       │ #8                  │       │ #8                  │       │ #8                  │ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │                     │       │                     │       │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤      ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓      ├─────────────────────┤       ├─────────────────────┤ + │ #9    LOADING       │       │ #9    LOADING       │       │ #9    LOADING       │       │ #9    LOADING       │      ┃│ #9    LOADING       │┃     ┃│ #9    LOADING       │┃     ┃│ #9                  │┃      │ #9                  │       │ #9                  │ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │      ┃│     PLACEHOLDER     │┃     ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤ + │ #10   LOADING       │       │ #10   LOADING       │       │ #10   LOADING       │       │ #10   LOADING       │      ┃│ #10   LOADING       │┃     ┃│ #10   LOADING       │┃     ┃│ #10                 │┃      │ #10                 │       │ #10                 │ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │      ┃│     PLACEHOLDER     │┃     ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓ + │ #11   LOADING       │       │ #11   LOADING       │       │ #11   LOADING       │       │ #11   LOADING       │      ┃│ #11   LOADING       │┃     ┃│ #11   LOADING       │┃     ┃│ #11                 │┃     ┃│ #11                 │┃     ┃│ #11                 │┃ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┃│                     │┃     ┃│                     │┃ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃ + │ #12   LOADING       │       │ #12   LOADING       │       │ #12   LOADING       │       │ #12   LOADING       │       │ #12   LOADING       │       │ #12   LOADING       │       │ #12   LOADING       │      ┃│ #12   LOADING       │┃     ┃│ #12                 │┃ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃ + │ #13   LOADING       │       │ #13   LOADING       │       │ #13   LOADING       │       │ #13   LOADING       │       │ #13   LOADING       │       │ #13   LOADING       │       │ #13   LOADING       │      ┃│ #13   LOADING       │┃     ┃│ #13                 │┃ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤ + │ #14   LOADING       │       │ #14   LOADING       │       │ #14   LOADING       │       │ #14   LOADING       │       │ #14   LOADING       │       │ #14   LOADING       │       │ #14   LOADING       │       │ #14   LOADING       │       │ #14                 │ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │                     │ + └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘ +``` + +
+
+ +Let’s implement the `SearchResult` windowed component with finite items loading. Here is a [live demo][todo] with [source code][todo]. + +
+ + Show a windowed finite loading illustration. + + +
+ +Consider page size equals to 3 items with total count of 15 items and [`UseWindowedListOptions.overscanCount`][use-windowed-list-options.overscan-count] equals 0. + +Compare it with the “finite loading illustration” above to get more insights. + +``` +                    load first page       ▶         scroll down         ▶      load second page       ▶       scroll down far       ▶       load third page       ▶       load fourth page      ▶         scroll down         ▶       load fifth page +┏┯━━━━━━━━━━━━━━━━━━━━━┯┓     ┏┯━━━━━━━━━━━━━━━━━━━━━┯┓      ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐ +┃│ #0    LOADING       │┃     ┃│ #0                  │┃      │ start space =       │       │ start space =       │       │ start space =       │       │ start space =       │       │ start space =       │       │ start space =       │       │ start space =       │ +┃│     PLACEHOLDER     │┃     ┃│                     │┃      │ #0.size             │       │ #0.size             │       │ #0.size +           │       │ #0.size +           │       │ #0.size +           │       │ #0.size +           │       │ #0.size +           │ +┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤       │ #1.size +           │       │ #1.size +           │       │ #1.size +           │       │ #1.size +           │       │ #1.size +           │ +┃│ #1    LOADING       │┃     ┃│ #1                  │┃      │ #1                  │       │ #1                  │       │ #2.size +           │       │ #2.size +           │       │ #2.size +           │       │ #2.size +           │       │ #2.size +           │ +┃│     PLACEHOLDER     │┃     ┃│                     │┃     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓      │ #3.size +           │       │ #3.size +           │       │ #3.size +           │       │ #3.size +           │       │ #3.size +           │ +┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      │ #4.size +           │       │ #4.size +           │       │ #4.size +           │       │ #4.size +           │       │ #4.size +           │ +┃│ #2    LOADING       │┃     ┃│ #2                  │┃     ┃│ #2                  │┃     ┃│ #2                  │┃      │ #5.size +           │       │ #5.size +           │       │ #5.size +           │       │ #5.size +           │       │ #5.size +           │ +┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┃│                     │┃     ┃│                     │┃      │ 3 * loading.size    │       │ #6.size +           │       │ #6.size +           │       │ #6.size +           │       │ #6.size +           │ + ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      │                     │       │ #7.size +           │       │ #7.size +           │       │ #7.size +           │       │ #7.size +           │ + │ end space =         │       │ end space =         │      ┃│ #3    LOADING       │┃     ┃│ #3                  │┃      │                     │       │ #8.size             │       │ #8.size             │       │ #8.size +           │       │ #8.size +           │ + │ 12 * loading.size   │       │ 12 * loading.size   │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │       │                     │       │ #9.size +           │       │ #9.size +           │ + │                     │       │                     │      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      │                     │       │                     │       │                     │       │ #10.size            │       │ #10.size            │ + │                     │       │                     │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛      │                     │       │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │     PLACEHOLDER     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       ├─────────────────────┤       ├─────────────────────┤       │                     │       │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │ end space =         │       │ end space =         │       │                     │       │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │ 10 * loading.size   │       │ #5.size +           │       │                     │       │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │                     │       │ 9 * loading.size    │       │                     │       │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │      ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓      │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │      ┃│ #9    LOADING       │┃     ┃│ #9    LOADING       │┃     ┃│ #9                  │┃      │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │      ┃│     PLACEHOLDER     │┃     ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │      ┃│ #10   LOADING       │┃     ┃│ #10   LOADING       │┃     ┃│ #10                 │┃      │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │      ┃│     PLACEHOLDER     │┃     ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓ + │                     │       │                     │       │                     │       │                     │      ┃│ #11   LOADING       │┃     ┃│ #11   LOADING       │┃     ┃│ #11                 │┃     ┃│ #11                 │┃     ┃│ #11                 │┃ + │                     │       │                     │       │                     │       │                     │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┃│                     │┃     ┃│                     │┃ + │                     │       │                     │       │                     │       │                     │       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃ + │                     │       │                     │       │                     │       │                     │       │ end space =         │       │ end space =         │       │ end space =         │      ┃│ #12   LOADING       │┃     ┃│ #12                 │┃ + │                     │       │                     │       │                     │       │                     │       │ 3 * loading.size    │       │ 3 * loading.size    │       │ 3 * loading.size    │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │      ┃│ #13   LOADING       │┃     ┃│ #13                 │┃ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       ├─────────────────────┤       ├─────────────────────┤ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │ end space =         │       │ end space =         │ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │ loading.size        │       │ #14.size            │ + └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘ +``` + +
+
+ +```tsx +import { useWindowedList } from '@react-hook-window/use-windowed-list' +import { + LoadingItemsRange, + useItemsLoader +} from '@react-hook-window/use-items-loader' + +interface SearchItem { + id: string + content: string +} + +export const SearchResult: React.VFC<{ + searchItemsTotalCount: number + searchItems: Array + loadNextPage(): void +}> = ({ searchItemsTotalCount, searchItems, loadNextPage }) => { + const { + setContainerRef, + startSpace, + endSpace, + indexes, + isScrolling, + overscanFromIndex, + overscanBeforeIndex + } = useWindowedList({ + containerSize: SEARCH_CONTAINER_HEIGHT, + itemSize: SEARCH_ITEM_HEIGHT, + // 1. Pass total count but not searchItems.length. + itemCount: searchItemsTotalCount + }) + + useItemsLoader({ + // 2. Skip the loading while isScrolling + skip: isScrolling, + overscanFromIndex, + overscanBeforeIndex, + shouldLoadItem: React.useCallback( + // 3. Items further than searchItems are loading placeholders so they should be loaded. + (index: number) => index >= searchItems.length, + [searchItems.length] + ), + loadItemsRange: React.useCallback( + // 4. Just load the next page ignoring loading items range. + (_range: LoadingItemsRange) => loadNextPage(), + [loadNextPage] + ) + }) + + return ( +
+
+ + {indexes.map(index => { + // 5. Render as many placeholders as needed. + if (index >= searchItems.length) { + return ( +
+ LOADING PLACEHOLDER +
+ ) + } + + const searchItem = searchItems[index] + + return ( +
+ {searchItem.content} +
+ ) + })} + +
+
+ ) +} +``` + +## Range loading usage + +The finite loading use case above might be a bit underwhelming for some use cases. + +1. The app might not need to load an entire page but only a few items. +2. The app might need to load a far away page. + +For both cases, it might be helpful to load a range of items instead of a page. That case is a range loading list, where an application knows a total count of items and can fetch a range of them when a user scrolls to unloaded items. The app might render loading placeholders since the total count is known ahead. + +
+ + Show a range loading illustration. + + +
+ +Consider total count of 15 items. + +``` +                  load items 0, 1, 2      ▶         scroll down         ▶       load items 3, 4       ▶         scroll down         ▶    load items 9, 10, 11     ▶         scroll down         ▶      load items 12, 13      ▶          scroll up          ▶     load items 5, 6, 7      ▶         scroll down         ▶         load item 8         ▶         scroll down         ▶         load item 14 +┏┯━━━━━━━━━━━━━━━━━━━━━┯┓     ┏┯━━━━━━━━━━━━━━━━━━━━━┯┓      ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐ +┃│ #0    LOADING       │┃     ┃│ #0                  │┃      │ #0                  │       │ #0                  │       │ #0                  │       │ #0                  │       │ #0                  │       │ #0                  │       │ #0                  │       │ #0                  │       │ #0                  │       │ #0                  │       │ #0                  │       │ #0                  │ +┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ +┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤ +┃│ #1    LOADING       │┃     ┃│ #1                  │┃      │ #1                  │       │ #1                  │       │ #1                  │       │ #1                  │       │ #1                  │       │ #1                  │       │ #1                  │       │ #1                  │       │ #1                  │       │ #1                  │       │ #1                  │       │ #1                  │ +┃│     PLACEHOLDER     │┃     ┃│                     │┃     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓      │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ +┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤ +┃│ #2    LOADING       │┃     ┃│ #2                  │┃     ┃│ #2                  │┃     ┃│ #2                  │┃      │ #2                  │       │ #2                  │       │ #2                  │       │ #2                  │       │ #2                  │       │ #2                  │       │ #2                  │       │ #2                  │       │ #2                  │       │ #2                  │ +┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┃│                     │┃     ┃│                     │┃      │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤ + │ #3    LOADING       │       │ #3    LOADING       │      ┃│ #3    LOADING       │┃     ┃│ #3                  │┃      │ #3                  │       │ #3                  │       │ #3                  │       │ #3                  │       │ #3                  │       │ #3                  │       │ #3                  │       │ #3                  │       │ #3                  │       │ #3                  │ + │     PLACEHOLDER     │       │     PLACEHOLDER     │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤ + │ #4    LOADING       │       │ #4    LOADING       │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛      │ #4                  │       │ #4                  │       │ #4                  │       │ #4                  │       │ #4                  │       │ #4                  │       │ #4                  │       │ #4                  │       │ #4                  │       │ #4                  │ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤      ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓      ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤ + │ #5    LOADING       │       │ #5    LOADING       │       │ #5    LOADING       │       │ #5    LOADING       │       │ #5    LOADING       │       │ #5    LOADING       │       │ #5    LOADING       │       │ #5    LOADING       │      ┃│ #5    LOADING       │┃     ┃│ #5                  │┃      │ #5                  │       │ #5                  │       │ #5                  │       │ #5                  │ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │       │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤ + │ #6    LOADING       │       │ #6    LOADING       │       │ #6    LOADING       │       │ #6    LOADING       │       │ #6    LOADING       │       │ #6    LOADING       │       │ #6    LOADING       │       │ #6    LOADING       │      ┃│ #6    LOADING       │┃     ┃│ #6                  │┃      │ #6                  │       │ #6                  │       │ #6                  │       │ #6                  │ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │       │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓      ├─────────────────────┤       ├─────────────────────┤ + │ #7    LOADING       │       │ #7    LOADING       │       │ #7    LOADING       │       │ #7    LOADING       │       │ #7    LOADING       │       │ #7    LOADING       │       │ #7    LOADING       │       │ #7    LOADING       │      ┃│ #7    LOADING       │┃     ┃│ #7                  │┃     ┃│ #7                  │┃     ┃│ #7                  │┃      │ #7                  │       │ #7                  │ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┃│                     │┃     ┃│                     │┃      │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤ + │ #8    LOADING       │       │ #8    LOADING       │       │ #8    LOADING       │       │ #8    LOADING       │       │ #8    LOADING       │       │ #8    LOADING       │       │ #8    LOADING       │       │ #8    LOADING       │       │ #8    LOADING       │       │ #8    LOADING       │      ┃│ #8    LOADING       │┃     ┃│ #8                  │┃      │ #8                  │       │ #8                  │ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤      ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓      ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤ + │ #9    LOADING       │       │ #9    LOADING       │       │ #9    LOADING       │       │ #9    LOADING       │      ┃│ #9    LOADING       │┃     ┃│ #9                  │┃      │ #9                  │       │ #9                  │       │ #9                  │       │ #9                  │      ┃│ #9                  │┃     ┃│ #9                  │┃      │ #9                  │       │ #9                  │ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │       │                     │       │                     │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛      │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤ + │ #10   LOADING       │       │ #10   LOADING       │       │ #10   LOADING       │       │ #10   LOADING       │      ┃│ #10   LOADING       │┃     ┃│ #10                 │┃      │ #10                 │       │ #10                 │       │ #10                 │       │ #10                 │       │ #10                 │       │ #10                 │       │ #10                 │       │ #10                 │ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓      ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤ + │ #11   LOADING       │       │ #11   LOADING       │       │ #11   LOADING       │       │ #11   LOADING       │      ┃│ #11   LOADING       │┃     ┃│ #11                 │┃     ┃│ #11                 │┃     ┃│ #11                 │┃      │ #11                 │       │ #11                 │       │ #11                 │       │ #11                 │       │ #11                 │       │ #11                 │ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┃│                     │┃     ┃│                     │┃      │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤ + │ #12   LOADING       │       │ #12   LOADING       │       │ #12   LOADING       │       │ #12   LOADING       │       │ #12   LOADING       │       │ #12   LOADING       │      ┃│ #12   LOADING       │┃     ┃│ #12                 │┃      │ #12                 │       │ #12                 │       │ #12                 │       │ #12                 │      ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │       │                     │       │                     │      ┃│                     │┃     ┃│                     │┃ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃ + │ #13   LOADING       │       │ #13   LOADING       │       │ #13   LOADING       │       │ #13   LOADING       │       │ #13   LOADING       │       │ #13   LOADING       │      ┃│ #13   LOADING       │┃     ┃│ #13                 │┃      │ #13                 │       │ #13                 │       │ #13                 │       │ #13                 │      ┃│ #13                 │┃     ┃│ #13                 │┃ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛      │                     │       │                     │       │                     │       │                     │      ┃│                     │┃     ┃│                     │┃ + ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃ + │ #14   LOADING       │       │ #14   LOADING       │       │ #14   LOADING       │       │ #14   LOADING       │       │ #14   LOADING       │       │ #14   LOADING       │       │ #14   LOADING       │       │ #14   LOADING       │       │ #14   LOADING       │       │ #14   LOADING       │       │ #14   LOADING       │       │ #14   LOADING       │      ┃│ #14   LOADING       │┃     ┃│ #14                 │┃ + │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │       │     PLACEHOLDER     │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃ + └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘      ┗┷━━━━━━━━━━━━━━━━━━━━━┷┛     ┗┷━━━━━━━━━━━━━━━━━━━━━┷┛ +``` + +
+
+ +Let’s implement the `RangedSearchResult` windowed component with finite items loading. Here is a [live demo][todo] with [source code][todo]. + +
+ + Show a windowed range loading illustration. + + +
+ +Consider total count of 15 items and [`UseWindowedListOptions.overscanCount`][use-windowed-list-options.overscan-count] equals 0. + +Compare it with the “range loading illustration” above to get more insights. + +``` +                  load items 0, 1, 2      ▶         scroll down         ▶       load items 3, 4       ▶         scroll down         ▶    load items 9, 10, 11     ▶         scroll down         ▶      load items 12, 13      ▶          scroll up          ▶     load items 5, 6, 7      ▶         scroll down         ▶         load item 8         ▶         scroll down         ▶         load item 14 +┏┯━━━━━━━━━━━━━━━━━━━━━┯┓     ┏┯━━━━━━━━━━━━━━━━━━━━━┯┓      ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐       ┌─────────────────────┐ +┃│ #0    LOADING       │┃     ┃│ #0                  │┃      │ start space =       │       │ start space =       │       │ start space =       │       │ start space =       │       │ start space =       │       │ start space =       │       │ start space =       │       │ start space =       │       │ start space =       │       │ start space =       │       │ start space =       │       │ start space =       │ +┃│     PLACEHOLDER     │┃     ┃│                     │┃      │ #0.size             │       │ #0.size             │       │ #0.size +           │       │ #0.size +           │       │ #0.size +           │       │ #0.size +           │       │ #0.size +           │       │ #0.size +           │       │ #0.size +           │       │ #0.size +           │       │ #0.size +           │       │ #0.size +           │ +┃├─────────────────────┤┃     ┃├─────────────────────┤┃      ├─────────────────────┤       ├─────────────────────┤       │ #1.size +           │       │ #1.size +           │       │ #1.size +           │       │ #1.size +           │       │ #1.size +           │       │ #1.size +           │       │ #1.size +           │       │ #1.size +           │       │ #1.size +           │       │ #1.size +           │ +┃│ #1    LOADING       │┃     ┃│ #1                  │┃      │ #1                  │       │ #1                  │       │ #2.size +           │       │ #2.size +           │       │ #2.size +           │       │ #2.size +           │       │ #2.size +           │       │ #2.size +           │       │ #2.size +           │       │ #2.size +           │       │ #2.size +           │       │ #2.size +           │ +┃│     PLACEHOLDER     │┃     ┃│                     │┃     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓      │ #3.size +           │       │ #3.size +           │       │ #3.size +           │       │ #3.size +           │       │ #3.size +           │       │ #3.size +           │       │ #3.size +           │       │ #3.size +           │       │ #3.size +           │       │ #3.size +           │ +┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      │ #4.size +           │       │ #4.size +           │       │ #4.size +           │       │ #4.size +           │       │ #4.size             │       │ #4.size             │       │ #4.size +           │       │ #4.size +           │       │ #4.size +           │       │ #4.size +           │ +┃│ #2    LOADING       │┃     ┃│ #2                  │┃     ┃│ #2                  │┃     ┃│ #2                  │┃      │ 4 * loading.size    │       │ 4 * loading.size    │       │ 4 * loading.size +  │       │ 4 * loading.size +  │       │                     │       │                     │       │ #5.size +           │       │ #5.size +           │       │ #5.size +           │       │ #5.size +           │ +┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┃│                     │┃     ┃│                     │┃      │                     │       │                     │       │ #9.size +           │       │ #9.size +           │       │                     │       │                     │       │ #6.size             │       │ #6.size             │       │ #6.size +           │       │ #6.size +           │ + ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      │                     │       │                     │       │ #10.size            │       │ #10.size            │       │                     │       │                     │       │                     │       │                     │       │ #7.size +           │       │ #7.size +           │ + │ end space =         │       │ end space =         │      ┃│ #3    LOADING       │┃     ┃│ #3                  │┃      │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │ #8.size +           │       │ #8.size +           │ + │ 12 * loading.size   │       │ 12 * loading.size   │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │ #9.size +           │       │ #9.size +           │ + │                     │       │                     │      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │ #10.size +          │       │ #10.size +          │ + │                     │       │                     │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛      │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │ #11.size            │       │ #11.size            │ + │                     │       │                     │       │   PLACEHOLDER       │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       ├─────────────────────┤       ├─────────────────────┤       │                     │       │                     │       │                     │       │                     │      ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓      │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │ end space =         │       │ end space =         │       │                     │       │                     │       │                     │       │                     │      ┃│ #5    LOADING       │┃     ┃│ #5                  │┃      │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │ 10 * loading.size   │       │ 10 * loading.size   │       │                     │       │                     │       │                     │       │                     │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │      ┃│ #6    LOADING       │┃     ┃│ #6                  │┃      │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓      │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │      ┃│ #7    LOADING       │┃     ┃│ #7                  │┃     ┃│ #7                  │┃     ┃│ #7                  │┃      │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┃│                     │┃     ┃│                     │┃      │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │ end space =         │       │ end space =         │      ┃│ #8    LOADING       │┃     ┃│ #8                  │┃      │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │ loading.size +      │       │ loading.size +      │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │      ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓      │                     │       │                     │       │ #8.size +           │       │ #8.size +           │      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │      ┃│ #9    LOADING       │┃     ┃│ #9                  │┃      │                     │       │                     │       │ #9.size +           │       │ #9.size +           │      ┃│ #9                  │┃     ┃│ #9                  │┃      │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │       │ #10.size +          │       │ #10.size +          │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛      │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      │                     │       │                     │       │ #11.size +          │       │ #11.size +          │       ├─────────────────────┤       ├─────────────────────┤       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │      ┃│ #10   LOADING       │┃     ┃│ #10                 │┃      │                     │       │                     │       │ #12.size +          │       │ #12.size +          │       │ end space =         │       │ end space =         │       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │       │ #13.size +          │       │ #13.size +          │       │ #10.size +          │       │ #10.size +          │       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓      │ loading.size        │       │ loading.size        │       │ #11.size +          │       │ #11.size +          │       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │      ┃│ #11   LOADING       │┃     ┃│ #11                 │┃     ┃│ #11                 │┃     ┃│ #11                 │┃      │                     │       │                     │       │ #12.size +          │       │ #12.size +          │       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┃│                     │┃     ┃│                     │┃      │                     │       │                     │       │ #13.size +          │       │ #13.size +          │       │                     │       │                     │ + │                     │       │                     │       │                     │       │                     │       ├─────────────────────┤       ├─────────────────────┤      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      │                     │       │                     │       │ loading.size        │       │ loading.size        │       ├─────────────────────┤       ├─────────────────────┤ + │                     │       │                     │       │                     │       │                     │       │ end space =         │       │ end space =         │      ┃│ #12   LOADING       │┃     ┃│ #12                 │┃      │                     │       │                     │       │                     │       │                     │      ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓     ┏┿━━━━━━━━━━━━━━━━━━━━━┿┓ + │                     │       │                     │       │                     │       │                     │       │ 3 * loading.size    │       │ 3 * loading.size    │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃      │                     │       │                     │       │                     │       │                     │      ┃│                     │┃     ┃│                     │┃ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃      │                     │       │                     │       │                     │       │                     │      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │      ┃│ #13   LOADING       │┃     ┃│ #13                 │┃      │                     │       │                     │       │                     │       │                     │      ┃│ #13                 │┃     ┃│ #13                 │┃ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │      ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛     ┗┿━━━━━━━━━━━━━━━━━━━━━┿┛      │                     │       │                     │       │                     │       │                     │      ┃│                     │┃     ┃│                     │┃ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       ├─────────────────────┤       ├─────────────────────┤       │                     │       │                     │       │                     │       │                     │      ┃├─────────────────────┤┃     ┃├─────────────────────┤┃ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │ end space =         │       │ end space =         │       │                     │       │                     │       │                     │       │                     │      ┃│ #14   LOADING       │┃     ┃│ #14                 │┃ + │                     │       │                     │       │                     │       │                     │       │                     │       │                     │       │ loading.size        │       │ loading.size        │       │                     │       │                     │       │                     │       │                     │      ┃│     PLACEHOLDER     │┃     ┃│                     │┃ + └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘       └─────────────────────┘      ┗┷━━━━━━━━━━━━━━━━━━━━━┷┛     ┗┷━━━━━━━━━━━━━━━━━━━━━┷┛ +``` + +
+
+ +```tsx +import { useWindowedList } from '@react-hook-window/use-windowed-list' +import { + LoadingItemsRange, + useItemsLoader +} from '@react-hook-window/use-items-loader' + +type Loadable = + | { type: 'NOT_LOADED' } + | { type: 'LOADING' } + | { type: 'LOADED'; data: T } + +interface SearchItem { + id: string + content: string +} + +export const SearchResult: React.VFC<{ + loadableItems: Array> + loadItemsRange(fromIndex: number, count: number): void +}> = ({ loadableItems, loadItemsRange }) => { + const { + setContainerRef, + startSpace, + endSpace, + indexes, + isScrolling, + overscanFromIndex, + overscanBeforeIndex + } = useWindowedList({ + containerSize: SEARCH_CONTAINER_HEIGHT, + itemSize: SEARCH_ITEM_HEIGHT, + // 1. Pass total loadableItems.length as it represents the search items' total count. + itemCount: loadableItems.length + }) + + useItemsLoader({ + // 2. Skip the loading while isScrolling + skip: isScrolling, + overscanFromIndex, + overscanBeforeIndex, + shouldLoadItem: React.useCallback( + // 3. Loadable items with NOT_LOADED type should be loaded. + (index: number) => index >= loadableItems[index].type === 'NOT_LOADED', + [loadableItems] + ), + loadItemsRange: React.useCallback( + // 4. Load the visible range. + ({ loadFromIndex, loadCount }: LoadingItemsRange) => { + loadItemsRange(loadFromIndex, loadCount) + }, + [loadItemsRange] + ) + }) + + return ( +
+
+ + {indexes.map(index => { + const loadableItem = loadableItems[index] + + // 5. Render loading placeholders for both NOT_LOADED and LOADING. + if (loadableItem.type !== 'LOADED') { + return ( +
+ LOADING PLACEHOLDER +
+ ) + } + + return ( +
+ {loadableItem.data.content} +
+ ) + })} + +
+
+ ) +} +``` + + + +[todo]: #i-am-sorry-it-is-not-done-yet +[use-windowed-list-options.overscan-count]: ../use-windowed-list/README.md#usewindowedlistoptionsoverscancount diff --git a/packages/use-infinite-loader/package.json b/packages/use-items-loader/package.json similarity index 92% rename from packages/use-infinite-loader/package.json rename to packages/use-items-loader/package.json index 95f6e6e..d851392 100644 --- a/packages/use-infinite-loader/package.json +++ b/packages/use-items-loader/package.json @@ -1,5 +1,5 @@ { - "name": "@react-hook-window/use-infinite-loader", + "name": "@react-hook-window/use-items-loader", "version": "0.0.0", "repository": "git@github.com:owanturist/react-hook-window.git", "author": "Anton Ovechkin ", diff --git a/packages/use-infinite-loader/src/calc-unloaded-ranges.ts b/packages/use-items-loader/src/calc-unloaded-ranges.ts similarity index 100% rename from packages/use-infinite-loader/src/calc-unloaded-ranges.ts rename to packages/use-items-loader/src/calc-unloaded-ranges.ts diff --git a/packages/use-infinite-loader/src/index.ts b/packages/use-items-loader/src/index.ts similarity index 81% rename from packages/use-infinite-loader/src/index.ts rename to packages/use-items-loader/src/index.ts index 6b56f7e..75463b6 100644 --- a/packages/use-infinite-loader/src/index.ts +++ b/packages/use-items-loader/src/index.ts @@ -7,23 +7,23 @@ export interface LoadingItemsRange { loadCount: number } -export interface UseInfiniteLoaderOptions { - isScrolling: boolean +export interface UseItemsLoaderOptions { + skip?: boolean overscanFromIndex: number overscanBeforeIndex: number shouldLoadItem(index: number): boolean loadItemsRange(range: LoadingItemsRange): void } -export const useInfiniteLoader = ({ - isScrolling, +export const useItemsLoader = ({ + skip = false, overscanFromIndex, overscanBeforeIndex, shouldLoadItem, loadItemsRange -}: UseInfiniteLoaderOptions): void => { +}: UseItemsLoaderOptions): void => { useEffect(() => { - if (isScrolling) { + if (skip) { return } @@ -41,7 +41,7 @@ export const useInfiniteLoader = ({ }) } }, [ - isScrolling, + skip, overscanFromIndex, overscanBeforeIndex, shouldLoadItem, diff --git a/packages/use-infinite-loader/tests/calc-unloaded-ranges.test.ts b/packages/use-items-loader/tests/calc-unloaded-ranges.test.ts similarity index 100% rename from packages/use-infinite-loader/tests/calc-unloaded-ranges.test.ts rename to packages/use-items-loader/tests/calc-unloaded-ranges.test.ts diff --git a/packages/use-infinite-loader/tsconfig.json b/packages/use-items-loader/tsconfig.json similarity index 100% rename from packages/use-infinite-loader/tsconfig.json rename to packages/use-items-loader/tsconfig.json diff --git a/packages/use-infinite-loader/tsconfig.prod.json b/packages/use-items-loader/tsconfig.prod.json similarity index 100% rename from packages/use-infinite-loader/tsconfig.prod.json rename to packages/use-items-loader/tsconfig.prod.json diff --git a/packages/use-windowed-list/README.md b/packages/use-windowed-list/README.md index 5a282ca..cb2d3a3 100644 --- a/packages/use-windowed-list/README.md +++ b/packages/use-windowed-list/README.md @@ -1,6 +1,6 @@ # use-windowed-list -React hook to render only the visible items in a container. +React hook to render only visible items in a container. ## Getting Started @@ -549,7 +549,7 @@ A set of available values defining a target element when scrolling via [`UseW │ │ │ │ │ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ - 3 ▼ no change + ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ 3 ▼ no change ┏┯━━━━━━━━━━━━━━━━━┯┓ ┌─────────────────┐ ┌─────────────────┐ ┃│ #0 │┃ │ #0 │ │ #0 │ @@ -623,7 +623,7 @@ A set of available values defining a target element when scrolling via [`UseW │ │ │ │ │ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ - 3 ▼ no change + ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ 3 ▼ no change ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ #0 │ │ #0 │ │ #0 │ @@ -733,7 +733,8 @@ A set of available values defining a target element when scrolling via [`UseW │ │ │ │ │ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ - 12 ▼ no change + ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ 12 ▼ no change + 3. scrolling to 12th that is already visible - no scroll needed 4. scrolling to 3th that is farther than one viewport - scroll to center the 3rd item 5. scrolling to 0th that is closer than one viewport - scroll as little as possible @@ -843,7 +844,7 @@ A set of available values defining a target element when scrolling via [`UseW │ │ │ │ ┃│ │┃ └─────────────────┘ └─────────────────┘ ┗┷━━━━━━━━━━━━━━━━━┷┛ - 3 ▼ + ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ 3 ▼ ┏┯━━━━━━━━━━━━━━━━━┯┓ ┌─────────────────┐ ┌─────────────────┐ ┃│ #0 │┃ │ #0 │ │ #0 │ @@ -926,7 +927,7 @@ A set of available values defining a target element when scrolling via [`UseW │ │ │ │ │ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ - 6 ▼ + ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ 6 ▼ ┏┯━━━━━━━━━━━━━━━━━┯┓ ┌─────────────────┐ ┌─────────────────┐ ┃│ #0 │┃ │ #0 │ │ #0 │ @@ -1009,7 +1010,7 @@ A set of available values defining a target element when scrolling via [`UseW │ │ │ │ │ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ - 7 ▼ + ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ 7 ▼ ┏┯━━━━━━━━━━━━━━━━━┯┓ ┌─────────────────┐ ┌─────────────────┐ ┃│ #0 │┃ │ #0 │ │ #0 │ diff --git a/rollup.config.js b/rollup.config.js index 19f7469..b662692 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -136,7 +136,7 @@ export default [ umdName: 'useWindowedList' }), ...makeConfig({ - root: path.resolve(__dirname, 'packages/use-infinite-loader'), + root: path.resolve(__dirname, 'packages/use-items-loader'), umdName: 'useWindowedList' }) ] diff --git a/sandbox/package.json b/sandbox/package.json index 5cd1e81..5db6d4a 100644 --- a/sandbox/package.json +++ b/sandbox/package.json @@ -12,7 +12,7 @@ }, "dependencies": { "@react-hook-window/use-windowed-list": "*", - "@react-hook-window/use-infinite-loader": "*", + "@react-hook-window/use-items-loader": "*", "react": "^17.0.2", "react-dom": "^17.0.2", "react-router-dom": "^5.2.0", diff --git a/sandbox/src/InfiniteLoaderDemo.tsx b/sandbox/src/InfiniteLoaderDemo.tsx index 22c8996..299eaf1 100644 --- a/sandbox/src/InfiniteLoaderDemo.tsx +++ b/sandbox/src/InfiniteLoaderDemo.tsx @@ -1,6 +1,6 @@ import * as React from 'react' import { useWindowedList } from '@react-hook-window/use-windowed-list' -import { useInfiniteLoader } from '@react-hook-window/use-infinite-loader' +import { useItemsLoader } from '@react-hook-window/use-items-loader' const loadRange = ( start: number, @@ -84,8 +84,8 @@ const InfiniteRangeLoaderDemo = React.memo(() => { itemCount: 1000 }) - useInfiniteLoader({ - isScrolling, + useItemsLoader({ + skip: isScrolling, overscanFromIndex, overscanBeforeIndex, shouldLoadItem, @@ -147,8 +147,8 @@ const InfinitePagedLoaderDemo = React.memo(() => { itemCount: 1000 }) - useInfiniteLoader({ - isScrolling, + useItemsLoader({ + skip: isScrolling, overscanFromIndex, overscanBeforeIndex, shouldLoadItem, @@ -196,8 +196,8 @@ const UndefinitePagedLoaderDemo = React.memo(() => { itemCount: items.length + 1 }) - useInfiniteLoader({ - isScrolling, + useItemsLoader({ + skip: isScrolling, overscanFromIndex, overscanBeforeIndex, shouldLoadItem,