diff --git a/package-lock.json b/package-lock.json index 71761da..b1ca8b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,6 +41,7 @@ "react-dom": "^18.2.0", "react-redux": "^9.2.0", "react-router-dom": "^6.23.1", + "react-virtuoso": "^4.18.5", "redux-first-history": "^5.2.0", "twake-i18n": "^0.3.0", "web-vitals": "^2.1.4" @@ -12616,6 +12617,16 @@ "react-dom": ">=16.6.0" } }, + "node_modules/react-virtuoso": { + "version": "4.18.5", + "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.18.5.tgz", + "integrity": "sha512-QDyNjyNEuurZG67SOmzYyxEkQYSyGmAMixOI6M15L/Q4CF39EgG+88y6DgZRo0q7rmy0HPx3Fj90I8/tPdnRCQ==", + "license": "MIT", + "peerDependencies": { + "react": ">=16 || >=17 || >= 18 || >= 19", + "react-dom": ">=16 || >=17 || >= 18 || >=19" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", diff --git a/package.json b/package.json index 718e39b..1a0add4 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "react-dom": "^18.2.0", "react-redux": "^9.2.0", "react-router-dom": "^6.23.1", + "react-virtuoso": "^4.18.5", "redux-first-history": "^5.2.0", "twake-i18n": "^0.3.0", "web-vitals": "^2.1.4" diff --git a/src/components/Timezone/SmallTimeZoneSelector.tsx b/src/components/Timezone/SmallTimeZoneSelector.tsx index 76299cf..84e344b 100644 --- a/src/components/Timezone/SmallTimeZoneSelector.tsx +++ b/src/components/Timezone/SmallTimeZoneSelector.tsx @@ -9,6 +9,7 @@ import { } from '@linagora/twake-mui' import { Search as SearchIcon } from '@mui/icons-material' import React, { useState, useMemo, useEffect, useRef } from 'react' +import { Virtuoso } from 'react-virtuoso' import { useTimeZoneList } from './hooks/useTimeZoneList' import { TimezoneSelectProps } from './TimezoneSelector' import { useI18n } from 'twake-i18n' @@ -31,6 +32,14 @@ const filterTimezones = ( }) } +const VirtuosoList = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>((props, ref) => ( + +)) +VirtuosoList.displayName = 'VirtuosoList' + export const SmallTimezoneSelector: React.FC< TimezoneSelectProps & { onClose: () => void @@ -57,7 +66,6 @@ export const SmallTimezoneSelector: React.FC< onClose() } - const selectedRef = useRef(null) const inputRef = useRef(null) const paperRef = useRef(null) @@ -96,7 +104,6 @@ export const SmallTimezoneSelector: React.FC< } inputRef.current?.focus() - selectedRef.current?.scrollIntoView({ behavior: 'auto', block: 'start' }) return (): void => { if (viewport) { @@ -158,18 +165,27 @@ export const SmallTimezoneSelector: React.FC< }} /> - - {filteredTimeZones.map(tz => ( - - ))} - + + tz === effectiveTimezone) + )} + components={{ + List: VirtuosoList + }} + itemContent={(_index, tz) => ( + + )} + /> + ) } diff --git a/src/components/Timezone/TimezoneAutocomplete.tsx b/src/components/Timezone/TimezoneAutocomplete.tsx index 94f4a5c..fbca9a2 100644 --- a/src/components/Timezone/TimezoneAutocomplete.tsx +++ b/src/components/Timezone/TimezoneAutocomplete.tsx @@ -42,7 +42,7 @@ export function TimezoneAutocomplete({ disableClearable = false, hideBorder = false, openOnFocus = false -}: TimezoneAutocompleteProps) { +}: TimezoneAutocompleteProps): React.ReactElement { const options = useMemo(() => { return zones.map(tz => ({ value: tz, diff --git a/src/components/Timezone/TimezoneListItem.tsx b/src/components/Timezone/TimezoneListItem.tsx index b876630..344c59f 100644 --- a/src/components/Timezone/TimezoneListItem.tsx +++ b/src/components/Timezone/TimezoneListItem.tsx @@ -15,15 +15,13 @@ interface TimezoneListItemProps { referenceDate: Date isSelected: boolean onSelect: (tz: string) => void - selectedRef: React.RefObject | null } export const TimezoneListItem: React.FC = ({ tz, referenceDate, isSelected, - onSelect, - selectedRef + onSelect }) => { const theme = useTheme() const offset = getTimezoneOffset(tz, referenceDate) @@ -34,7 +32,6 @@ export const TimezoneListItem: React.FC = ({ onSelect(tz)} sx={{ py: 1 }} >