@@ -27,6 +27,12 @@ import { BoolToggle } from '@components/inputs/BoolToggle'
2727import { GenericSearchMemo } from '@components/inputs/GenericSearch'
2828import { StandardItem } from '@components/virtual/StandardItem'
2929
30+ import {
31+ getDrawerGridState ,
32+ setDrawerGridState ,
33+ useDrawerScrollMemory ,
34+ } from '../hooks/useScrollMemory'
35+
3036/**
3137 * @template {keyof import('@rm/types').Available } T
3238 * @typedef {{
@@ -36,14 +42,27 @@ import { StandardItem } from '@components/virtual/StandardItem'
3642 * children?: React.ReactNode,
3743 * label?: string
3844 * height?: React.CSSProperties['height'],
45+ * scrollKey?: string,
46+ * visible?: boolean,
3947 * }} SelectorListProps
4048 * @param {SelectorListProps<keyof import('@rm/types').Available> } props
4149 * @returns
4250 */
43- function SelectorList ( { category, subCategory, label, height = 400 } ) {
51+ function SelectorList ( {
52+ category,
53+ subCategory,
54+ label,
55+ height = 400 ,
56+ scrollKey,
57+ visible = true ,
58+ } ) {
4459 const searchKey = `${ category } ${
4560 subCategory ? capitalize ( subCategory ) : ''
4661 } QuickSelect`
62+ const listScrollKey =
63+ scrollKey ||
64+ `selector:${ category } :${ subCategory || 'default' } :${ label || 'default' } `
65+ const drawer = useLayoutStore ( ( s ) => s . drawer )
4766 const { available } = useGetAvailable ( category )
4867 const { t : tId } = useTranslateById ( {
4968 quest : subCategory === 'pokemon' ,
@@ -114,6 +133,32 @@ function SelectorList({ category, subCategory, label, height = 400 }) {
114133 . map ( ( item ) => item . id )
115134 } , [ translated , search ] )
116135
136+ const restoreStateFrom = React . useMemo (
137+ ( ) => getDrawerGridState ( listScrollKey ) ,
138+ [ listScrollKey ] ,
139+ )
140+ const shouldPersistGridState = drawer && visible
141+ const scrollMemory = useDrawerScrollMemory (
142+ listScrollKey ,
143+ shouldPersistGridState ,
144+ )
145+
146+ const handleStateChanged = React . useCallback (
147+ ( state ) => {
148+ if (
149+ ! shouldPersistGridState ||
150+ ! state . viewport . height ||
151+ ! state . viewport . width ||
152+ ! state . item . height ||
153+ ! state . item . width
154+ ) {
155+ return
156+ }
157+ setDrawerGridState ( listScrollKey , state )
158+ } ,
159+ [ listScrollKey , shouldPersistGridState ] ,
160+ )
161+
117162 /** @param {'enable' | 'disable' | 'advanced' } action */
118163 const setAll = ( action ) => {
119164 const keys = new Set ( items . map ( ( item ) => item ) )
@@ -194,7 +239,13 @@ function SelectorList({ category, subCategory, label, height = 400 }) {
194239 : height
195240 }
196241 >
197- < VirtualGrid data = { items } xs = { 4 } >
242+ < VirtualGrid
243+ data = { items }
244+ xs = { 4 }
245+ scrollerRef = { scrollMemory . ref }
246+ restoreStateFrom = { restoreStateFrom }
247+ stateChanged = { handleStateChanged }
248+ >
198249 { ( _ , key ) => < StandardItem id = { key } category = { category } /> }
199250 </ VirtualGrid >
200251 </ Box >
@@ -208,13 +259,16 @@ export const SelectorListMemo = React.memo(
208259 prev . category === next . category &&
209260 prev . subCategory === next . subCategory &&
210261 prev . label === next . label &&
211- prev . height === next . height ,
262+ prev . height === next . height &&
263+ prev . scrollKey === next . scrollKey &&
264+ prev . visible === next . visible ,
212265)
213266
214267/** @param {{ children: React.ReactElement[], tabKey: string } } props */
215268export function MultiSelectorList ( { children, tabKey } ) {
216269 const { t } = useTranslation ( )
217270 const [ openTab , setOpenTab ] = useDeepStore ( `tabs.${ tabKey } ` , 0 )
271+ const visibleChildren = children . filter ( Boolean )
218272
219273 /** @type {import('@mui/material').TabsProps['onChange'] } */
220274 const handleTabChange = React . useCallback (
@@ -226,14 +280,14 @@ export function MultiSelectorList({ children, tabKey }) {
226280 < Box pt = { 2 } >
227281 < AppBar position = "static" >
228282 < Tabs value = { openTab } onChange = { handleTabChange } >
229- { children . map ( ( child ) => (
283+ { visibleChildren . map ( ( child ) => (
230284 < Tab key = { child . key } label = { t ( child . key ) } />
231285 ) ) }
232286 </ Tabs >
233287 </ AppBar >
234- { children . filter ( Boolean ) . map ( ( child , index ) => (
288+ { visibleChildren . map ( ( child , index ) => (
235289 < TabPanel value = { openTab } index = { index } key = { child . key } >
236- { child }
290+ { React . cloneElement ( child , { visible : openTab === index } ) }
237291 </ TabPanel >
238292 ) ) }
239293 </ Box >
0 commit comments