Skip to content

Commit

Permalink
update types
Browse files Browse the repository at this point in the history
  • Loading branch information
Lykhoyda committed Jul 12, 2023
1 parent c211837 commit 2b8202a
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 62 deletions.
62 changes: 41 additions & 21 deletions packages/ui/src/components/library/Autocomplete.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,57 @@
import { Autocomplete as AutocompleteMui } from '@mui/material'
import React, { SyntheticEvent } from 'react'
import React from 'react'
import { styled } from '@mui/material/styles'
import { AutocompleteRenderInputParams } from '@mui/material/Autocomplete/Autocomplete'
import {
AutocompleteRenderInputParams,
AutocompleteRenderOptionState
} from '@mui/material/Autocomplete/Autocomplete'
import { HiOutlineChevronDown } from 'react-icons/hi2'
import { InjectedAccountWithMeta } from '@polkadot/extension-inject/types'

interface AutocompleteProps {
import {
AutocompleteFreeSoloValueMapping,
AutocompleteInputChangeReason,
AutocompleteValue,
FilterOptionsState
} from '@mui/base/useAutocomplete/useAutocomplete'

interface AutocompleteProps<T, Multiple, DisableClearable, FreeSolo> {
InputProps?: Partial<AutocompleteRenderInputParams['InputProps']>
className?: string
isOptionEqualToValue?: (option: any, value: any) => boolean
filterOptions?: (options: any[], state: any) => any[]
options: any[]
getOptionLabel: (option: any) => string
onChange?: (event: any, value: any) => void
value?: any
renderOption: (props: any, option: any, state: any) => React.ReactNode
isOptionEqualToValue?: (option: T, value: T) => boolean
filterOptions?: (options: T[], state: FilterOptionsState<T>) => T[]
options: ReadonlyArray<T>
getOptionLabel?: (option: T | AutocompleteFreeSoloValueMapping<FreeSolo>) => string
onChange?: (
event: React.SyntheticEvent,
value: AutocompleteValue<T, Multiple, DisableClearable, FreeSolo>
) => void
value?: AutocompleteValue<T, Multiple, DisableClearable, FreeSolo>
renderOption?: (
props: React.HTMLAttributes<HTMLLIElement>,
option: T,
state: AutocompleteRenderOptionState
) => React.ReactNode
renderInput: (params: AutocompleteRenderInputParams) => React.ReactNode

disableClearable?: boolean
onKeyDown?: (e: any) => void
disableClearable?: DisableClearable
onKeyDown?: (e: React.SyntheticEvent) => void
onInputChange?: (
_: SyntheticEvent<Element, Event>,
val: string | InjectedAccountWithMeta | null
event: React.SyntheticEvent,
value: string,
reason: AutocompleteInputChangeReason
) => void
disabled?: boolean
freeSolo?: boolean
freeSolo?: FreeSolo
iconSize?: string
selectOnFocus?: boolean
clearOnBlur?: boolean
handleHomeEndKeys?: boolean
}

const Autocomplete = ({
const Autocomplete = <
T,
Multiple extends boolean | undefined,
DisableClearable extends boolean | undefined,
FreeSolo extends boolean | undefined
>({
className,
isOptionEqualToValue,
filterOptions,
Expand All @@ -49,7 +69,7 @@ const Autocomplete = ({
clearOnBlur,
handleHomeEndKeys,
iconSize
}: AutocompleteProps) => {
}: AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>) => {
return (
<AutocompleteWrapper
iconSize={iconSize}
Expand Down Expand Up @@ -115,7 +135,7 @@ const AutocompleteWrapper = styled('div')<{ iconSize?: string }>`
.MuiAutocomplete-listbox {
padding: 0;
border: 1px solid ${({ theme }) => theme.custom.text.borderColor};
border-radius: 0.5rem;
border-radius: 0.75rem;
box-shadow: none;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/components/library/InputField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const InputStyledBaseCss = css`
padding: 0.5rem 1.25rem;
border: none;
outline: 1.5px solid ${theme.custom.text.borderColor};
border-radius: 0.5rem;
border-radius: 0.75rem;
font-size: 1rem;
font-family: 'Jost', sans-serif;
Expand All @@ -63,7 +63,7 @@ export const InputStyledBaseCss = css`
cursor: not-allowed;
background: #f3f6f9;
outline: 1.5px solid #e7e7e7;
border-radius: 0.5rem;
border-radius: 0.75rem;
}
`

Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/modals/Send.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ const Send = ({ onClose, className, onSuccess, onFinalized }: Props) => {
<DialogTitle>Send tx</DialogTitle>
<DialogContent className="generalContainer">
<Grid
sx={{ alignItems: 'center' }}
alignItems="center"
container
>
<Grid
Expand Down
31 changes: 21 additions & 10 deletions packages/ui/src/components/selectors/AccountSelection.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Box, InputAdornment } from '@mui/material'
import * as React from 'react'
import {
ChangeEvent,
SyntheticEvent,
Expand All @@ -17,8 +18,10 @@ import { useAccountNames } from '../../contexts/AccountNamesContext'
import MultixIdenticon from '../MultixIdenticon'
import { Autocomplete, Button, InputField, TextFieldStyled } from '../library'
import OptionMenuItem from './OptionMenuItem'
import { AutocompleteRenderInputParams } from '@mui/material/Autocomplete/Autocomplete'
import * as React from 'react'
import {
AutocompleteRenderInputParams,
AutocompleteRenderOptionState
} from '@mui/material/Autocomplete/Autocomplete'

interface Props {
className?: string
Expand All @@ -38,6 +41,9 @@ const filterOptions = createFilterOptions({
stringify: (option: InjectedAccountWithMeta) => option.address + option.meta.name
})

const isInjectedAccountWithMeta = (value: any): value is InjectedAccountWithMeta =>
value && value.address && value.meta && value.meta.source

const getOptionLabel = (option: string | InjectedAccountWithMeta | null) => {
if (!option) return ''

Expand Down Expand Up @@ -77,10 +83,19 @@ const AccountSelection = ({
}, [accountNames, selected])

const onChangeAutocomplete = useCallback(
(_: SyntheticEvent<Element, Event>, val: string | InjectedAccountWithMeta | null) => {
(
_: SyntheticEvent<Element, Event>,
val: NonNullable<
| InjectedAccountWithMeta
| string
| undefined
| (string | InjectedAccountWithMeta | undefined)[]
>
) => {
setErrorMessage('')
setName('')
const value = getOptionLabel(val)

const value = getOptionLabel(val as string)
setSelected(value)
},
[]
Expand Down Expand Up @@ -125,12 +140,8 @@ const AccountSelection = ({

const renderOption = (
props: React.HTMLAttributes<HTMLLIElement>,
option: {
address: string
meta: {
name: string
}
}
option: InjectedAccountWithMeta,
_: AutocompleteRenderOptionState
) => (
<OptionMenuItem
keyValue={option.address}
Expand Down
13 changes: 11 additions & 2 deletions packages/ui/src/components/selectors/GenericAccountSelection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ const isOptionEqualToValue = (option: AccountBaseInfo, value: AccountBaseInfo) =
return option.address === value.address
}

const isAccountBaseInfo = (value: any): value is AccountBaseInfo => {
return value && value.address
}

const GenericAccountSelection = ({
className,
accountList = [],
Expand Down Expand Up @@ -102,13 +106,18 @@ const GenericAccountSelection = ({
}, [])

const onChangeAutocomplete = useCallback(
(_: React.SyntheticEvent<Element, Event>, val: AccountBaseInfo | string) => {
(
_: React.SyntheticEvent<Element, Event>,
val: NonNullable<
AccountBaseInfo | string | undefined | (string | AccountBaseInfo | undefined)[]
>
) => {
if (typeof val === 'string') {
onChange({
address: val
})
} else {
onChange(val)
isAccountBaseInfo(val) && onChange(val)
}
onInputBlur()
},
Expand Down
35 changes: 24 additions & 11 deletions packages/ui/src/components/selectors/MultiProxySelection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@ import { Autocomplete } from '../library'
import { AutocompleteRenderInputParams } from '@mui/material/Autocomplete/Autocomplete'
import TextFieldLargeStyled from '../library/TextFieldLargeStyled'

const isMultiProxy = (value: any): value is MultiProxy =>
value && value.multisigs && value.multisigs.length > 0

interface Props {
className?: string
}

const getDisplayAddress = (option?: MultiProxy) =>
option?.proxy ? option?.proxy : option?.multisigs[0].address

const isOptionEqualToValue = (option: MultiProxy | undefined, value: MultiProxy | undefined) => {
const isOptionEqualToValue = (option?: MultiProxy, value?: MultiProxy) => {
if (!option || !value) return false

if (!!option.proxy || !!value.proxy) {
Expand All @@ -30,7 +33,6 @@ const isOptionEqualToValue = (option: MultiProxy | undefined, value: MultiProxy
const MultiProxySelection = ({ className }: Props) => {
const ref = useRef<HTMLInputElement>(null)
const { multiProxyList, selectedMultiProxy, selectMultiProxy } = useMultiProxy()

const isSelectedProxy = useMemo(() => !!selectedMultiProxy?.proxy, [selectedMultiProxy])
// We only support one multisigs if they have no proxy
const addressToShow = useMemo(
Expand All @@ -47,31 +49,42 @@ const MultiProxySelection = ({ className }: Props) => {
})

const getOptionLabel = useCallback(
(option: typeof selectedMultiProxy) => {
(option?: NonNullable<MultiProxy | string>): string => {
// We only support one multisigs if they have no proxy
const addressToSearch = option?.proxy || option?.multisigs[0].address
const name = !!addressToSearch && accountNames[addressToSearch]
return name || (addressToSearch as string)

if (isMultiProxy(option)) {
const addressToSearch = option?.proxy || option?.multisigs[0].address
const name = !!addressToSearch && accountNames[addressToSearch]
return name || (addressToSearch as string)
}

return ''
},
[accountNames]
)

const onChange = useCallback(
(_: React.SyntheticEvent<Element, Event>, val: typeof selectedMultiProxy) => {
if (!val) return
(
_: React.SyntheticEvent<Element, Event>,
value: NonNullable<MultiProxy | string | undefined | (string | MultiProxy | undefined)[]>
) => {
if (!value) return

selectMultiProxy(val)
isMultiProxy(value) && selectMultiProxy(value)
},
[selectMultiProxy]
)

const handleSpecialKeys = useCallback((e: any) => {
const handleSpecialKeys = useCallback((e: React.KeyboardEvent) => {
if (['Enter', 'Escape'].includes(e.key)) {
ref?.current?.blur()
}
}, [])

const renderOptions = (props: React.HTMLAttributes<HTMLLIElement>, option: MultiProxy) => {
const renderOptions = (
props: React.HTMLAttributes<HTMLLIElement>,
option: typeof selectedMultiProxy
): React.ReactNode => {
const displayAddress = getDisplayAddress(option)

return (
Expand Down
46 changes: 31 additions & 15 deletions packages/ui/src/components/selectors/SignerSelection.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { InputAdornment } from '@mui/material'
import * as React from 'react'
import { useCallback, useEffect, useMemo } from 'react'
import { styled } from '@mui/material/styles'
import { createFilterOptions } from '@mui/material/Autocomplete'
Expand All @@ -8,19 +9,22 @@ import AccountDisplay from '../AccountDisplay'
import MultixIdenticon from '../MultixIdenticon'
import { Autocomplete, TextFieldStyled } from '../library'
import OptionMenuItem from './OptionMenuItem'
import * as React from 'react'
import { AutocompleteRenderInputParams } from '@mui/material/Autocomplete/Autocomplete'

const isInjectedAccountWithMeta = (value: any): value is InjectedAccountWithMeta => {
return value && value.address && value.meta && value.meta.name
}

interface Props {
className?: string
possibleSigners: string[]
onChange?: () => void
}

const getOptionLabel = (option: InjectedAccountWithMeta | undefined) => {
if (!option) return ''
const getOptionLabel = (option?: NonNullable<InjectedAccountWithMeta | string>): string => {
if (!option || !isInjectedAccountWithMeta(option)) return ''

return option.meta.name || ''
return option.meta.name as string
}

const isOptionEqualToValue = (
Expand Down Expand Up @@ -54,24 +58,36 @@ const SignerSelection = ({ className, possibleSigners, onChange }: Props) => {
})

const onChangeSigner = useCallback(
(_: any, newSelected: (typeof signersList)[0]) => {
newSelected && selectAccount(newSelected)
(
_: React.SyntheticEvent<Element, Event>,
newSelected: NonNullable<
| (typeof signersList)[0]
| string
| undefined
| (string | (typeof signersList)[0] | undefined)[]
>
) => {
isInjectedAccountWithMeta(newSelected) && selectAccount(newSelected)
onChange && onChange()
},
[onChange, selectAccount]
)

const renderOption = (
props: React.HTMLAttributes<HTMLLIElement>,
option: InjectedAccountWithMeta
) => (
<OptionMenuItem
{...props}
keyValue={option?.address}
>
<AccountDisplay address={option?.address || ''} />
</OptionMenuItem>
)
option?: InjectedAccountWithMeta
) => {
if (!option) return null

return (
<OptionMenuItem
{...props}
keyValue={option.address}
>
<AccountDisplay address={option?.address || ''} />
</OptionMenuItem>
)
}

const renderInput = (params: AutocompleteRenderInputParams) => (
<TextFieldStyled
Expand Down

0 comments on commit 2b8202a

Please sign in to comment.