Merge pull request #807 from lethemanh/806-resolve-double-tab-to-select-timezone-issue
#806 resolve double tab to select timezone-issue
This commit is contained in:
Generated
+11
@@ -41,6 +41,7 @@
|
|||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-redux": "^9.2.0",
|
"react-redux": "^9.2.0",
|
||||||
"react-router-dom": "^6.23.1",
|
"react-router-dom": "^6.23.1",
|
||||||
|
"react-virtuoso": "^4.18.5",
|
||||||
"redux-first-history": "^5.2.0",
|
"redux-first-history": "^5.2.0",
|
||||||
"twake-i18n": "^0.3.0",
|
"twake-i18n": "^0.3.0",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
@@ -12616,6 +12617,16 @@
|
|||||||
"react-dom": ">=16.6.0"
|
"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": {
|
"node_modules/read-cache": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-redux": "^9.2.0",
|
"react-redux": "^9.2.0",
|
||||||
"react-router-dom": "^6.23.1",
|
"react-router-dom": "^6.23.1",
|
||||||
|
"react-virtuoso": "^4.18.5",
|
||||||
"redux-first-history": "^5.2.0",
|
"redux-first-history": "^5.2.0",
|
||||||
"twake-i18n": "^0.3.0",
|
"twake-i18n": "^0.3.0",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
} from '@linagora/twake-mui'
|
} from '@linagora/twake-mui'
|
||||||
import { Search as SearchIcon } from '@mui/icons-material'
|
import { Search as SearchIcon } from '@mui/icons-material'
|
||||||
import React, { useState, useMemo, useEffect, useRef } from 'react'
|
import React, { useState, useMemo, useEffect, useRef } from 'react'
|
||||||
|
import { Virtuoso } from 'react-virtuoso'
|
||||||
import { useTimeZoneList } from './hooks/useTimeZoneList'
|
import { useTimeZoneList } from './hooks/useTimeZoneList'
|
||||||
import { TimezoneSelectProps } from './TimezoneSelector'
|
import { TimezoneSelectProps } from './TimezoneSelector'
|
||||||
import { useI18n } from 'twake-i18n'
|
import { useI18n } from 'twake-i18n'
|
||||||
@@ -31,6 +32,14 @@ const filterTimezones = (
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const VirtuosoList = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
React.HTMLAttributes<HTMLDivElement>
|
||||||
|
>((props, ref) => (
|
||||||
|
<List component="div" {...props} ref={ref} sx={{ pt: 0, pb: 0 }} />
|
||||||
|
))
|
||||||
|
VirtuosoList.displayName = 'VirtuosoList'
|
||||||
|
|
||||||
export const SmallTimezoneSelector: React.FC<
|
export const SmallTimezoneSelector: React.FC<
|
||||||
TimezoneSelectProps & {
|
TimezoneSelectProps & {
|
||||||
onClose: () => void
|
onClose: () => void
|
||||||
@@ -57,7 +66,6 @@ export const SmallTimezoneSelector: React.FC<
|
|||||||
onClose()
|
onClose()
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectedRef = useRef<HTMLDivElement>(null)
|
|
||||||
const inputRef = useRef<HTMLInputElement>(null)
|
const inputRef = useRef<HTMLInputElement>(null)
|
||||||
const paperRef = useRef<HTMLDivElement>(null)
|
const paperRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
@@ -96,7 +104,6 @@ export const SmallTimezoneSelector: React.FC<
|
|||||||
}
|
}
|
||||||
|
|
||||||
inputRef.current?.focus()
|
inputRef.current?.focus()
|
||||||
selectedRef.current?.scrollIntoView({ behavior: 'auto', block: 'start' })
|
|
||||||
|
|
||||||
return (): void => {
|
return (): void => {
|
||||||
if (viewport) {
|
if (viewport) {
|
||||||
@@ -158,18 +165,27 @@ export const SmallTimezoneSelector: React.FC<
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<List sx={{ overflow: 'auto', flex: 1, pt: 0 }}>
|
<Box sx={{ flex: 1, minHeight: 0 }}>
|
||||||
{filteredTimeZones.map(tz => (
|
<Virtuoso
|
||||||
<TimezoneListItem
|
data={filteredTimeZones}
|
||||||
key={tz}
|
initialTopMostItemIndex={Math.max(
|
||||||
tz={tz}
|
0,
|
||||||
referenceDate={referenceDate}
|
filteredTimeZones.findIndex(tz => tz === effectiveTimezone)
|
||||||
isSelected={effectiveTimezone === tz}
|
)}
|
||||||
onSelect={handleSelect}
|
components={{
|
||||||
selectedRef={selectedRef}
|
List: VirtuosoList
|
||||||
/>
|
}}
|
||||||
))}
|
itemContent={(_index, tz) => (
|
||||||
</List>
|
<TimezoneListItem
|
||||||
|
key={tz}
|
||||||
|
tz={tz}
|
||||||
|
referenceDate={referenceDate}
|
||||||
|
isSelected={effectiveTimezone === tz}
|
||||||
|
onSelect={handleSelect}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
</StyledSwipeableDrawer>
|
</StyledSwipeableDrawer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export function TimezoneAutocomplete({
|
|||||||
disableClearable = false,
|
disableClearable = false,
|
||||||
hideBorder = false,
|
hideBorder = false,
|
||||||
openOnFocus = false
|
openOnFocus = false
|
||||||
}: TimezoneAutocompleteProps) {
|
}: TimezoneAutocompleteProps): React.ReactElement {
|
||||||
const options = useMemo<TimezoneOption[]>(() => {
|
const options = useMemo<TimezoneOption[]>(() => {
|
||||||
return zones.map(tz => ({
|
return zones.map(tz => ({
|
||||||
value: tz,
|
value: tz,
|
||||||
|
|||||||
@@ -15,15 +15,13 @@ interface TimezoneListItemProps {
|
|||||||
referenceDate: Date
|
referenceDate: Date
|
||||||
isSelected: boolean
|
isSelected: boolean
|
||||||
onSelect: (tz: string) => void
|
onSelect: (tz: string) => void
|
||||||
selectedRef: React.RefObject<HTMLDivElement> | null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TimezoneListItem: React.FC<TimezoneListItemProps> = ({
|
export const TimezoneListItem: React.FC<TimezoneListItemProps> = ({
|
||||||
tz,
|
tz,
|
||||||
referenceDate,
|
referenceDate,
|
||||||
isSelected,
|
isSelected,
|
||||||
onSelect,
|
onSelect
|
||||||
selectedRef
|
|
||||||
}) => {
|
}) => {
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const offset = getTimezoneOffset(tz, referenceDate)
|
const offset = getTimezoneOffset(tz, referenceDate)
|
||||||
@@ -34,7 +32,6 @@ export const TimezoneListItem: React.FC<TimezoneListItemProps> = ({
|
|||||||
<ListItemButton
|
<ListItemButton
|
||||||
selected={isSelected}
|
selected={isSelected}
|
||||||
aria-selected={isSelected}
|
aria-selected={isSelected}
|
||||||
ref={isSelected ? selectedRef : null}
|
|
||||||
onClick={() => onSelect(tz)}
|
onClick={() => onSelect(tz)}
|
||||||
sx={{ py: 1 }}
|
sx={{ py: 1 }}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user