Commit f3f51ee8 authored by tom's avatar tom

fix ts

parent 30bee36e
'use client';
import type { CollectionItem, ListCollection } from '@chakra-ui/react';
import type { ListCollection } from '@chakra-ui/react';
import { Box, Select as ChakraSelect, createListCollection, Flex, Portal, useSelectContext } from '@chakra-ui/react';
import { useDebounce } from '@uidotdev/usehooks';
import * as React from 'react';
import FilterInput from 'ui/shared/filters/FilterInput';
import type { IconName } from 'ui/shared/IconSvg';
import IconSvg from 'ui/shared/IconSvg';
import { CloseButton } from './close-button';
......@@ -14,6 +15,7 @@ import { Skeleton } from './skeleton';
export interface SelectOption<Value extends string = string> {
value: Value;
label: string;
icon?: IconName | React.ReactNode;
}
export interface SelectControlProps extends ChakraSelect.ControlProps {
......@@ -112,7 +114,7 @@ export const SelectItem = React.forwardRef<
});
interface SelectValueTextProps extends Omit<ChakraSelect.ValueTextProps, 'children'> {
children?(items: Array<CollectionItem>): React.ReactNode;
children?(items: Array<SelectOption>): React.ReactNode;
size?: SelectRootProps['size'];
required?: boolean;
invalid?: boolean;
......@@ -136,11 +138,11 @@ export const SelectValueText = React.forwardRef<
if (children) return children(items);
if (items.length === 1) {
const item = items[0] as CollectionItem & { icon?: React.ReactNode };
const item = items[0] as SelectOption;
const icon = (() => {
if (item.icon) {
return typeof item.icon === 'string' ? <IconSvg name={ item.icon } boxSize={ 5 } flexShrink={ 0 }/> : item.icon;
return typeof item.icon === 'string' ? <IconSvg name={ item.icon as IconName } boxSize={ 5 } flexShrink={ 0 }/> : item.icon;
}
return null;
......@@ -235,7 +237,7 @@ export const SelectLabel = ChakraSelect.Label;
export const SelectItemText = ChakraSelect.ItemText;
export interface SelectProps extends SelectRootProps {
collection: ListCollection<CollectionItem>;
collection: ListCollection<SelectOption>;
placeholder: string;
portalled?: boolean;
loading?: boolean;
......@@ -260,7 +262,7 @@ export const Select = React.forwardRef<HTMLDivElement, SelectProps>((props, ref)
/>
</SelectControl>
<SelectContent portalled={ portalled }>
{ collection.items.map((item) => (
{ collection.items.map((item: SelectOption) => (
<SelectItem item={ item } key={ item.value }>
{ item.label }
</SelectItem>
......@@ -274,14 +276,14 @@ export interface SelectAsyncProps extends Omit<SelectProps, 'collection'> {
placeholder: string;
portalled?: boolean;
loading?: boolean;
loadOptions: (input: string, currentValue: Array<string>) => Promise<ListCollection<CollectionItem>>;
loadOptions: (input: string, currentValue: Array<string>) => Promise<ListCollection<SelectOption>>;
extraControls?: React.ReactNode;
}
export const SelectAsync = React.forwardRef<HTMLDivElement, SelectAsyncProps>((props, ref) => {
const { placeholder, portalled = true, loading, loadOptions, extraControls, onValueChange, errorText, ...rest } = props;
const [ collection, setCollection ] = React.useState<ListCollection<CollectionItem>>(createListCollection({ items: [] }));
const [ collection, setCollection ] = React.useState<ListCollection<SelectOption>>(createListCollection<SelectOption>({ items: [] }));
const [ inputValue, setInputValue ] = React.useState('');
const [ value, setValue ] = React.useState<Array<string>>([]);
......@@ -295,7 +297,7 @@ export const SelectAsync = React.forwardRef<HTMLDivElement, SelectAsyncProps>((p
setInputValue(value);
}, [ ]);
const handleValueChange = React.useCallback(({ value, items }: { value: Array<string>; items: Array<CollectionItem> }) => {
const handleValueChange = React.useCallback(({ value, items }: { value: Array<string>; items: Array<SelectOption> }) => {
setValue(value);
onValueChange?.({ value, items });
}, [ onValueChange ]);
......
......@@ -85,7 +85,11 @@ const AddressVerificationStepSignature = ({ address, signingMessage, contractCre
const { signMessage, isPending: isSigning } = useSignMessage();
const handleSignMethodChange = React.useCallback(({ value }: { value: string }) => {
const handleSignMethodChange = React.useCallback(({ value }: { value: string | null }) => {
if (!value) {
return;
}
setSignMethod(value as SignMethod);
clearErrors('root');
}, [ clearErrors ]);
......
......@@ -20,7 +20,11 @@ type Props = {
};
const AddressRelationFilter = ({ value = DEFAULT_VALUE, handleFilterChange, onClose }: Props) => {
const onFilter = React.useCallback(({ value }: { value: string }) => {
const onFilter = React.useCallback(({ value }: { value: string | null }) => {
if (!value) {
return;
}
onClose && onClose();
handleFilterChange(FILTER_PARAM, value as Value);
}, [ handleFilterChange, onClose ]);
......
......@@ -9,6 +9,7 @@ import hexToBase64 from 'lib/hexToBase64';
import hexToBytes from 'lib/hexToBytes';
import hexToUtf8 from 'lib/hexToUtf8';
import { Button } from 'toolkit/chakra/button';
import type { SelectOption } from 'toolkit/chakra/select';
import { Select } from 'toolkit/chakra/select';
import { Skeleton } from 'toolkit/chakra/skeleton';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
......@@ -44,7 +45,7 @@ const BlobData = ({ data, isLoading, hash }: Props) => {
const isImage = guessedType?.mime?.startsWith('image/');
const collection = React.useMemo(() => {
const formats = isImage ? FORMATS : FORMATS.filter((format) => format.value !== 'Image');
return createListCollection({
return createListCollection<SelectOption>({
items: formats,
});
}, [ isImage ]);
......
......@@ -4,11 +4,12 @@ import React from 'react';
import type { FormFields } from '../types';
import { CONTRACT_LICENSES } from 'lib/contracts/licenses';
import type { SelectOption } from 'toolkit/chakra/select';
import FormFieldSelect from 'ui/shared/forms/fields/FormFieldSelect';
import ContractVerificationFormRow from '../ContractVerificationFormRow';
const collection = createListCollection({
const collection = createListCollection<SelectOption>({
items: CONTRACT_LICENSES.map(({ label, title, type }) => ({ label: `${ title } (${ label })`, value: type })),
});
......
......@@ -11,6 +11,7 @@ import type { SmartContractVerificationMethod, SmartContractVerificationConfig }
import { nbsp } from 'lib/html-entities';
import { Link } from 'toolkit/chakra/link';
import type { SelectOption } from 'toolkit/chakra/select';
import FormFieldSelect from 'ui/shared/forms/fields/FormFieldSelect';
import Hint from 'ui/shared/Hint';
......@@ -21,7 +22,7 @@ interface Props {
}
const ContractVerificationFieldMethod = ({ methods }: Props) => {
const collection = React.useMemo(() => createListCollection({
const collection = React.useMemo(() => createListCollection<SelectOption>({
items: methods.map((method) => ({
value: method,
label: METHOD_LABELS[method],
......
......@@ -16,6 +16,7 @@ import * as metadata from 'lib/metadata';
import * as mixpanel from 'lib/mixpanel/index';
import getQueryParamString from 'lib/router/getQueryParamString';
import { Button } from 'toolkit/chakra/button';
import type { SelectOption } from 'toolkit/chakra/select';
import { Select } from 'toolkit/chakra/select';
import { Skeleton } from 'toolkit/chakra/skeleton';
import isCustomAppError from 'ui/shared/AppError/isCustomAppError';
......@@ -173,7 +174,7 @@ const Chart = () => {
.filter((resolution) => resolutions.includes(resolution.id))
.map((resolution) => ({ value: resolution.id, label: resolution.title }));
return createListCollection({ items });
return createListCollection<SelectOption>({ items });
}, [ lineQuery.data?.info?.resolutions ]);
return (
......
......@@ -42,7 +42,6 @@ const Login = () => {
cookies.set(cookies.NAMES.API_TOKEN, token);
setToken('');
toaster.create({
placement: 'top-end',
title: 'Success 🥳',
description: 'Successfully set cookie',
type: 'success',
......
......@@ -5,6 +5,7 @@ import React from 'react';
import type { FormFields } from '../types';
import type { PublicTagType } from 'types/api/addressMetadata';
import type { SelectOption } from 'toolkit/chakra/select';
import FormFieldSelect from 'ui/shared/forms/fields/FormFieldSelect';
interface Props {
......@@ -33,7 +34,7 @@ const PublicTagsSubmitFieldTagType = ({ index, tagTypes }: Props) => {
icon: getItemIcon(type),
})) ?? [];
return createListCollection({ items });
return createListCollection<SelectOption>({ items });
}, [ tagTypes, getItemIcon ]);
return (
......
......@@ -33,7 +33,6 @@ const AppErrorTooManyRequests = () => {
} catch (error) {
toaster.create({
placement: 'top-end',
title: 'Error',
description: 'Unable to get client key.',
type: 'error',
......
......@@ -2,6 +2,7 @@ import { createListCollection } from '@chakra-ui/react';
import React from 'react';
import hexToUtf8 from 'lib/hexToUtf8';
import type { SelectOption } from 'toolkit/chakra/select';
import { Select } from 'toolkit/chakra/select';
import RawDataSnippet from 'ui/shared/RawDataSnippet';
......@@ -10,7 +11,7 @@ const OPTIONS = [
{ label: 'UTF-8', value: 'UTF-8' as const },
];
const collection = createListCollection({
const collection = createListCollection<SelectOption>({
items: OPTIONS,
});
......
......@@ -30,7 +30,11 @@ const TokenTransferFilter = ({
}: Props) => {
const isInitialLoading = useIsInitialLoading(isLoading);
const handleAddressFilterChange = React.useCallback(({ value }: { value: string }) => {
const handleAddressFilterChange = React.useCallback(({ value }: { value: string | null }) => {
if (!value) {
return;
}
onAddressFilterChange?.(value);
}, [ onAddressFilterChange ]);
......
......@@ -3,23 +3,25 @@ import { noop } from 'es-toolkit';
import React from 'react';
import { Checkbox } from 'toolkit/chakra/checkbox';
import type { SelectOption } from 'toolkit/chakra/select';
import { Select, SelectAsync } from 'toolkit/chakra/select';
import PopoverFilterRadio from 'ui/shared/filters/PopoverFilterRadio';
import type { IconName } from 'ui/shared/IconSvg';
import Sort from 'ui/shared/sort/Sort';
import TokenTransferFilter from 'ui/shared/TokenTransfer/TokenTransferFilter';
import { SORT_OPTIONS } from 'ui/txs/useTxsSort';
import { Section, Container, SectionHeader, SamplesStack, Sample, SectionSubHeader } from './parts';
const frameworks = createListCollection({
const frameworks = createListCollection<SelectOption>({
items: [
{ label: 'React.js is the most popular framework', value: 'react', icon: 'API' },
{ label: 'React.js is the most popular framework', value: 'react', icon: 'API' as IconName },
{ label: 'Vue.js is the second most popular framework', value: 'vue' },
{ label: 'Angular', value: 'angular' },
{ label: 'Svelte', value: 'svelte' },
],
});
const txSortingOptions = createListCollection({
const txSortingOptions = createListCollection<SelectOption>({
items: SORT_OPTIONS,
});
......
......@@ -4,11 +4,11 @@ import React from 'react';
import type { NetworkGroup, FeaturedNetwork } from 'types/networks';
import type { SelectOption } from 'toolkit/chakra/select';
import { Select } from 'toolkit/chakra/select';
import { Skeleton } from 'toolkit/chakra/skeleton';
import NetworkMenuLink from './NetworkMenuLink';
interface Props {
tabs: Array<NetworkGroup>;
items?: Array<FeaturedNetwork>;
......@@ -29,7 +29,7 @@ const NetworkMenuContentMobile = ({ items, tabs }: Props) => {
}, []);
const selectCollection = React.useMemo(() => {
return createListCollection({
return createListCollection<SelectOption>({
items: tabs.map((tab) => ({ label: capitalize(tab), value: tab })),
});
}, [ tabs ]);
......
......@@ -4,6 +4,7 @@ import React from 'react';
import type { TokenInstance } from 'types/api/token';
import { Alert } from 'toolkit/chakra/alert';
import type { SelectOption } from 'toolkit/chakra/select';
import { Select } from 'toolkit/chakra/select';
import ContentLoader from 'ui/shared/ContentLoader';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
......@@ -17,7 +18,7 @@ const OPTIONS = [
{ label: 'JSON', value: 'JSON' as const },
];
const collection = createListCollection({ items: OPTIONS });
const collection = createListCollection<SelectOption>({ items: OPTIONS });
type Format = (typeof OPTIONS)[number]['value'];
......
......@@ -20,6 +20,8 @@ import useReCaptcha from 'ui/shared/reCaptcha/useReCaptcha';
import { useMetadataUpdateContext } from './contexts/metadataUpdate';
const TOAST_ID = 'token-instance-metadata-fetcher';
interface Props {
hash: string;
id: string;
......@@ -27,7 +29,6 @@ interface Props {
const TokenInstanceMetadataFetcher = ({ hash, id }: Props) => {
const timeoutId = React.useRef<number>();
const toastId = React.useRef<string>();
const { status, setStatus } = useMetadataUpdateContext() || {};
const apiFetch = useApiFetch();
......@@ -36,7 +37,7 @@ const TokenInstanceMetadataFetcher = ({ hash, id }: Props) => {
const handleRefreshError = React.useCallback(() => {
setStatus?.('ERROR');
toastId.current && toaster.update(toastId.current, {
toaster.update(TOAST_ID, {
title: 'Error',
description: 'The refreshing process has failed. Please try again.',
type: 'error',
......@@ -55,7 +56,8 @@ const TokenInstanceMetadataFetcher = ({ hash, id }: Props) => {
},
});
setStatus?.('WAITING_FOR_RESPONSE');
toastId.current = toaster.loading({
toaster.loading({
id: TOAST_ID,
title: 'Please wait',
description: 'Refetching metadata request sent',
duration: Infinity,
......@@ -63,6 +65,7 @@ const TokenInstanceMetadataFetcher = ({ hash, id }: Props) => {
timeoutId.current = window.setTimeout(handleRefreshError, 2 * MINUTE);
} catch (error) {
toaster.error({
id: TOAST_ID,
title: 'Error',
description: getErrorMessage(error) || 'Unable to initialize metadata update',
});
......@@ -103,7 +106,7 @@ const TokenInstanceMetadataFetcher = ({ hash, id }: Props) => {
};
});
toastId.current && toaster.update(toastId.current, {
toaster.update(TOAST_ID, {
title: 'Success!',
description: 'Metadata has been refreshed',
type: 'success',
......@@ -140,7 +143,7 @@ const TokenInstanceMetadataFetcher = ({ hash, id }: Props) => {
React.useEffect(() => {
return () => {
timeoutId.current && window.clearTimeout(timeoutId.current);
toastId.current && toaster.remove(toastId.current);
toaster.remove(TOAST_ID);
};
// run only on mount/unmount
}, []);
......
......@@ -4,6 +4,7 @@ import React from 'react';
import type { VerifiedContractsFilter as TVerifiedContractsFilter } from 'types/api/contracts';
import config from 'configs/app';
import type { SelectOption } from 'toolkit/chakra/select';
import PopoverFilterRadio from 'ui/shared/filters/PopoverFilterRadio';
type OptionValue = TVerifiedContractsFilter | 'all';
......@@ -16,7 +17,7 @@ const OPTIONS = [
{ value: 'scilla', label: 'Scilla' },
].filter(({ value }) => value === 'all' || config.UI.views.address.languageFilters.includes(value)) as Array<{ value: OptionValue; label: string }>;
const collection = createListCollection({
const collection = createListCollection<SelectOption>({
items: OPTIONS,
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment