From eac325e436b37b18c4e2468921ce7e5b2df3c8db Mon Sep 17 00:00:00 2001 From: daryl Date: Fri, 2 Aug 2024 10:06:16 +0800 Subject: [PATCH] feat(multi-select): add selected preview --- .../FilterSortContainer/index.module.scss | 4 +- src/components/MultiFilterButton/index.tsx | 141 ++++++++++-------- .../MultiFilterButton/styles.module.scss | 33 +++- src/pages/NftCollections/List.tsx | 16 +- src/pages/NftCollections/styles.module.scss | 4 +- src/pages/Xudts/index.tsx | 20 +-- src/pages/Xudts/styles.module.scss | 9 ++ 7 files changed, 145 insertions(+), 82 deletions(-) diff --git a/src/components/FilterSortContainer/index.module.scss b/src/components/FilterSortContainer/index.module.scss index 2b1fca07e..73f20a777 100644 --- a/src/components/FilterSortContainer/index.module.scss +++ b/src/components/FilterSortContainer/index.module.scss @@ -1,10 +1,11 @@ .filterSortContainerOnMobile { display: flex; - flex-wrap: wrap; + flex-wrap: nowrap; justify-content: space-between; gap: 20px; ul { + max-width: 100%; display: flex; flex-wrap: wrap; margin: 0; @@ -12,6 +13,7 @@ li { width: 50%; list-style-type: none; + text-wrap: nowrap; &:nth-child(odd) { text-align: left; diff --git a/src/components/MultiFilterButton/index.tsx b/src/components/MultiFilterButton/index.tsx index 4401e820a..96294f130 100644 --- a/src/components/MultiFilterButton/index.tsx +++ b/src/components/MultiFilterButton/index.tsx @@ -1,6 +1,7 @@ import { Link, useLocation } from 'react-router-dom' import { Popover } from 'antd' import { useTranslation } from 'react-i18next' +import { useEffect, useState } from 'react' import { ReactComponent as FilterIcon } from '../../assets/filter_icon.svg' import { ReactComponent as SelectedIcon } from '../../assets/selected-icon.svg' import { ReactComponent as NotSelectedIcon } from '../../assets/not-selected-icon.svg' @@ -17,11 +18,22 @@ export function MultiFilterButton({ filterList: { key: string; value: string; to: string; title: string | JSX.Element }[] isMobile?: boolean }) { + const [selected, setSelected] = useState('') const { t } = useTranslation() const params = useSearchParams(filterName) const filter = params[filterName] const types = filter?.split(',').filter(t => !!t) ?? [] + useEffect(() => { + const filterMap = new Map(filterList.map(f => [f.key, f.value])) + setSelected( + types + .map(item => filterMap.get(item)) + .filter(item => item) + .join(','), + ) + }, [filter]) + const isAllSelected = types.length === filterList.length const isNoneSelected = types.length === 0 const search = new URLSearchParams(useLocation().search) @@ -29,69 +41,78 @@ export function MultiFilterButton({ search.delete('page') return ( - -
-

{t('components.multi_filter_button.select')}

- { - const newSearch = new URLSearchParams(search) - if (isNoneSelected) { - newSearch.append(filterName, filterList.map(f => f.value).join(',')) - } +
+ {!!selected && ( +
+ {selected} + +{types.length} +
+ )} + +
+

{t('components.multi_filter_button.select')}

+ { + const newSearch = new URLSearchParams(search) + if (isNoneSelected) { + newSearch.append(filterName, filterList.map(f => f.key).join(',')) + } - return `${filterList[0].to}?${newSearch.toString()}` - }} - > - {types.length > 0 ? ( - <>{isAllSelected ? : } - ) : ( - - )} - -
- {filterList.map(f => ( - { - const subTypes = new Set(types) - if (subTypes.has(f.value)) { - subTypes.delete(f.value) - } else { - subTypes.add(f.value) - } + return `${filterList[0].to}?${newSearch.toString()}` + }} + > + {types.length > 0 ? ( + <>{isAllSelected ? : } + ) : ( + + )} + +
+ {filterList.map(f => ( + { + const subTypes = new Set(types) + if (subTypes.has(f.key)) { + subTypes.delete(f.key) + } else { + subTypes.add(f.key) + } - const newSearch = new URLSearchParams(search) - if (subTypes.size === 0) { - newSearch.delete(filterName) - } else { - newSearch.append(filterName, Array.from(subTypes).join(',')) - } - return `${f.to}?${newSearch.toString()}` - }} - data-is-active={types.includes(f.value)} - > - {f.title} - {types.includes(f.value) ? : } - - ))} + const newSearch = new URLSearchParams(search) + if (subTypes.size === 0) { + newSearch.delete(filterName) + } else { + newSearch.append(filterName, Array.from(subTypes).join(',')) + } + return `${f.to}?${newSearch.toString()}` + }} + data-is-active={types.includes(f.key)} + > + {f.title} + {types.includes(f.key) ? : } + + ))} +
+ } + > +
+
- } - > - -
+ + ) } diff --git a/src/components/MultiFilterButton/styles.module.scss b/src/components/MultiFilterButton/styles.module.scss index 464517d06..4c9601c54 100644 --- a/src/components/MultiFilterButton/styles.module.scss +++ b/src/components/MultiFilterButton/styles.module.scss @@ -3,9 +3,11 @@ border: none; outline: none; background: none; - display: inline-flex; - vertical-align: text-top; + gap: 4px; cursor: pointer; + width: 70%; + display: flex; + align-items: center; } .antPopover { @@ -31,6 +33,33 @@ } } +.selected { + border-radius: 48px; + border: 1px solid var(--primary-dimmed-color); + background: var(--secondary-color); + display: flex; + padding: 4px 8px; + align-items: flex-start; + align-content: flex-start; + gap: 4px; + flex-wrap: nowrap; + margin-left: 4px; + color: var(--primary-color); + font-size: 12px; + font-style: normal; + font-weight: 500; + line-height: normal; + align-self: center; + max-width: 85%; + + .selectedItems { + max-width: 95%; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } +} + .filterItems { display: flex; flex-direction: column; diff --git a/src/pages/NftCollections/List.tsx b/src/pages/NftCollections/List.tsx index 288892a37..a5a77554d 100644 --- a/src/pages/NftCollections/List.tsx +++ b/src/pages/NftCollections/List.tsx @@ -49,43 +49,43 @@ function useFilterList(): Record<'title' | 'value', string>[] { const filterList = [ { key: 'invalid', - value: 'invalid', + value: 'Invalid', title: , to: '/nft-collections', }, { key: 'suspicious', - value: 'suspicious', + value: 'Suspicious', title: , to: '/nft-collections', }, { key: 'out-of-length-range', - value: 'out-of-length-range', + value: 'Out Of Length Range', title: , to: '/nft-collections', }, { key: 'rgb++', - value: 'rgb++', + value: 'RGB++', title: , to: '/nft-collections', }, { key: 'duplicate', - value: 'duplicate', + value: 'Duplicate', title: , to: '/nft-collections', }, { key: 'layer-1-asset', - value: 'layer-1-asset', + value: 'Layer 1 Asset', title: , to: '/nft-collections', }, { key: 'layer-2-asset', - value: 'layer-2-asset', + value: 'Layer 2 Asset', title: , to: '/nft-collections', }, @@ -361,7 +361,7 @@ export const ListOnMobile: React.FC<{ isLoading: boolean; list: NFTCollection[] -
+
{t('xudt.title.tags')}
diff --git a/src/pages/NftCollections/styles.module.scss b/src/pages/NftCollections/styles.module.scss index 57b26afa7..10da348d2 100644 --- a/src/pages/NftCollections/styles.module.scss +++ b/src/pages/NftCollections/styles.module.scss @@ -67,8 +67,10 @@ } .colTags { + max-width: 100%; + width: 100%; display: flex; - flex-wrap: wrap; + flex-wrap: nowrap; align-items: center; } diff --git a/src/pages/Xudts/index.tsx b/src/pages/Xudts/index.tsx index a3ea9493f..5d626ac46 100644 --- a/src/pages/Xudts/index.tsx +++ b/src/pages/Xudts/index.tsx @@ -39,19 +39,19 @@ const filterList = [ // }, { key: 'layer-1-asset', - value: 'layer-1-asset', + value: 'Layer 1 Asset', title: , to: '/xudts', }, { key: 'layer-2-asset', - value: 'layer-2-asset', + value: 'Layer 2 Asset', title: , to: '/xudts', }, { key: 'supply-limited', - value: 'supply-limited', + value: 'Supply Limited', title: , to: '/xudts', }, @@ -134,20 +134,20 @@ export function TokensCard({ - {t('xudt.transactions')} - + {t('xudt.title.tags')} + - {t('xudt.unique_addresses')} - + {t('xudt.transactions')} + {t('xudt.created_time')} - {t('xudt.title.tags')} - + {t('xudt.unique_addresses')} + @@ -247,7 +247,7 @@ const TokenTable: FC<{ { title: ( <> - {t('xudt.unique_addresses')} + {t('xudt.unique_addresses')} ), diff --git a/src/pages/Xudts/styles.module.scss b/src/pages/Xudts/styles.module.scss index 124df684d..a8f89970a 100644 --- a/src/pages/Xudts/styles.module.scss +++ b/src/pages/Xudts/styles.module.scss @@ -236,6 +236,9 @@ dt { } .colTags { + display: flex; + align-items: center; + .tags { flex-wrap: wrap; display: flex; @@ -316,7 +319,13 @@ dt { } .colAddressCount { + display: flex; min-width: 170px; + flex-wrap: nowrap; + + span { + white-space: nowrap; + } } .colCreatedTime {