Chore: frontend infrastructure upgrade (#16420)
Co-authored-by: NFish <douxc512@gmail.com> Co-authored-by: zxhlyh <jasonapring2015@outlook.com> Co-authored-by: twwu <twwu@dify.ai> Co-authored-by: jZonG <jzongcode@gmail.com>
This commit is contained in:
@@ -9,17 +9,17 @@ type DescriptionProps = {
|
||||
const Description = async ({
|
||||
locale: localeFromProps,
|
||||
}: DescriptionProps) => {
|
||||
const localeDefault = getLocaleOnServer()
|
||||
const localeDefault = await getLocaleOnServer()
|
||||
const { t } = await translate(localeFromProps || localeDefault, 'plugin')
|
||||
const { t: tCommon } = await translate(localeFromProps || localeDefault, 'common')
|
||||
const isZhHans = localeFromProps === 'zh-Hans'
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1 className='shrink-0 mb-2 text-center title-4xl-semi-bold text-text-primary'>
|
||||
<h1 className='title-4xl-semi-bold mb-2 shrink-0 text-center text-text-primary'>
|
||||
{t('marketplace.empower')}
|
||||
</h1>
|
||||
<h2 className='shrink-0 flex justify-center items-center text-center body-md-regular text-text-tertiary'>
|
||||
<h2 className='body-md-regular flex shrink-0 items-center justify-center text-center text-text-tertiary'>
|
||||
{
|
||||
isZhHans && (
|
||||
<>
|
||||
@@ -36,23 +36,23 @@ const Description = async ({
|
||||
</>
|
||||
)
|
||||
}
|
||||
<span className="relative ml-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected z-[1]">
|
||||
<span className="body-md-medium relative z-[1] ml-1 text-text-secondary after:absolute after:bottom-[1.5px] after:left-0 after:h-2 after:w-full after:bg-text-text-selected after:content-['']">
|
||||
<span className='relative z-[2] lowercase'>{t('category.models')}</span>
|
||||
</span>
|
||||
,
|
||||
<span className="relative ml-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected z-[1]">
|
||||
<span className="body-md-medium relative z-[1] ml-1 text-text-secondary after:absolute after:bottom-[1.5px] after:left-0 after:h-2 after:w-full after:bg-text-text-selected after:content-['']">
|
||||
<span className='relative z-[2] lowercase'>{t('category.tools')}</span>
|
||||
</span>
|
||||
,
|
||||
<span className="relative ml-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected z-[1]">
|
||||
<span className="body-md-medium relative z-[1] ml-1 text-text-secondary after:absolute after:bottom-[1.5px] after:left-0 after:h-2 after:w-full after:bg-text-text-selected after:content-['']">
|
||||
<span className='relative z-[2] lowercase'>{t('category.agents')}</span>
|
||||
</span>
|
||||
,
|
||||
<span className="relative ml-1 mr-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected z-[1]">
|
||||
<span className="body-md-medium relative z-[1] ml-1 mr-1 text-text-secondary after:absolute after:bottom-[1.5px] after:left-0 after:h-2 after:w-full after:bg-text-text-selected after:content-['']">
|
||||
<span className='relative z-[2] lowercase'>{t('category.extensions')}</span>
|
||||
</span>
|
||||
{t('marketplace.and')}
|
||||
<span className="relative ml-1 mr-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected z-[1]">
|
||||
<span className="body-md-medium relative z-[1] ml-1 mr-1 text-text-secondary after:absolute after:bottom-[1.5px] after:left-0 after:h-2 after:w-full after:bg-text-text-selected after:content-['']">
|
||||
<span className='relative z-[2] lowercase'>{t('category.bundles')}</span>
|
||||
</span>
|
||||
{
|
||||
|
@@ -21,14 +21,14 @@ const Empty = ({
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn('grow relative h-0 flex flex-wrap p-2 overflow-hidden', className)}
|
||||
className={cn('relative flex h-0 grow flex-wrap overflow-hidden p-2', className)}
|
||||
>
|
||||
{
|
||||
Array.from({ length: 16 }).map((_, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={cn(
|
||||
'mr-3 mb-3 h-[144px] w-[calc((100%-36px)/4)] rounded-xl bg-background-section-burn',
|
||||
'mb-3 mr-3 h-[144px] w-[calc((100%-36px)/4)] rounded-xl bg-background-section-burn',
|
||||
index % 4 === 3 && 'mr-0',
|
||||
index > 11 && 'mb-0',
|
||||
lightCard && 'bg-background-default-lighter opacity-75',
|
||||
@@ -40,19 +40,19 @@ const Empty = ({
|
||||
{
|
||||
!lightCard && (
|
||||
<div
|
||||
className='absolute inset-0 bg-marketplace-plugin-empty z-[1]'
|
||||
className='absolute inset-0 z-[1] bg-marketplace-plugin-empty'
|
||||
></div>
|
||||
)
|
||||
}
|
||||
<div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-[2] flex flex-col items-center'>
|
||||
<div className='relative flex items-center justify-center mb-3 w-14 h-14 rounded-xl border border-dashed border-divider-deep bg-components-card-bg shadow-lg'>
|
||||
<Group className='w-5 h-5' />
|
||||
<div className='absolute left-1/2 top-1/2 z-[2] flex -translate-x-1/2 -translate-y-1/2 flex-col items-center'>
|
||||
<div className='relative mb-3 flex h-14 w-14 items-center justify-center rounded-xl border border-dashed border-divider-deep bg-components-card-bg shadow-lg'>
|
||||
<Group className='h-5 w-5' />
|
||||
<Line className='absolute right-[-1px] top-1/2 -translate-y-1/2' />
|
||||
<Line className='absolute left-[-1px] top-1/2 -translate-y-1/2' />
|
||||
<Line className='absolute top-0 left-1/2 -translate-x-1/2 -translate-y-1/2 rotate-90' />
|
||||
<Line className='absolute top-full left-1/2 -translate-x-1/2 -translate-y-1/2 rotate-90' />
|
||||
<Line className='absolute left-1/2 top-0 -translate-x-1/2 -translate-y-1/2 rotate-90' />
|
||||
<Line className='absolute left-1/2 top-full -translate-x-1/2 -translate-y-1/2 rotate-90' />
|
||||
</div>
|
||||
<div className='text-center system-md-regular text-text-tertiary'>
|
||||
<div className='system-md-regular text-center text-text-tertiary'>
|
||||
{text || t('plugin.marketplace.noPluginFound')}
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -14,7 +14,7 @@ const IntersectionLine = ({
|
||||
useScrollIntersection(ref, intersectionContainerId)
|
||||
|
||||
return (
|
||||
<div ref={ref} className='shrink-0 mb-4 h-[1px] bg-transparent'></div>
|
||||
<div ref={ref} className='mb-4 h-[1px] shrink-0 bg-transparent'></div>
|
||||
)
|
||||
}
|
||||
|
||||
|
@@ -32,7 +32,7 @@ const CardWrapper = ({
|
||||
if (showInstallButton) {
|
||||
return (
|
||||
<div
|
||||
className='group relative rounded-xl cursor-pointer hover:bg-components-panel-on-panel-item-bg-hover'
|
||||
className='group relative cursor-pointer rounded-xl hover:bg-components-panel-on-panel-item-bg-hover'
|
||||
>
|
||||
<Card
|
||||
key={plugin.name}
|
||||
@@ -47,7 +47,7 @@ const CardWrapper = ({
|
||||
/>
|
||||
{
|
||||
showInstallButton && (
|
||||
<div className='hidden absolute bottom-0 group-hover:flex items-center space-x-2 px-4 pt-8 pb-4 w-full bg-gradient-to-tr from-components-panel-on-panel-item-bg to-background-gradient-mask-transparent rounded-b-xl'>
|
||||
<div className='absolute bottom-0 hidden w-full items-center space-x-2 rounded-b-xl bg-gradient-to-tr from-components-panel-on-panel-item-bg to-background-gradient-mask-transparent px-4 pb-4 pt-8 group-hover:flex'>
|
||||
<Button
|
||||
variant='primary'
|
||||
className='w-[calc(50%-4px)]'
|
||||
@@ -55,12 +55,12 @@ const CardWrapper = ({
|
||||
>
|
||||
{t('plugin.detailPanel.operation.install')}
|
||||
</Button>
|
||||
<a href={`${getPluginLinkInMarketplace(plugin)}?language=${localeFromLocale}`} target='_blank' className='block flex-1 shrink-0 w-[calc(50%-4px)]'>
|
||||
<a href={`${getPluginLinkInMarketplace(plugin)}?language=${localeFromLocale}`} target='_blank' className='block w-[calc(50%-4px)] flex-1 shrink-0'>
|
||||
<Button
|
||||
className='w-full gap-0.5'
|
||||
>
|
||||
{t('plugin.detailPanel.operation.detail')}
|
||||
<RiArrowRightUpLine className='ml-1 w-4 h-4' />
|
||||
<RiArrowRightUpLine className='ml-1 h-4 w-4' />
|
||||
</Button>
|
||||
</a>
|
||||
</div>
|
||||
@@ -82,7 +82,7 @@ const CardWrapper = ({
|
||||
|
||||
return (
|
||||
<a
|
||||
className='group inline-block relative rounded-xl cursor-pointer'
|
||||
className='group relative inline-block cursor-pointer rounded-xl'
|
||||
href={getPluginLinkInMarketplace(plugin)}
|
||||
>
|
||||
<Card
|
||||
|
@@ -13,7 +13,7 @@ type ListProps = {
|
||||
showInstallButton?: boolean
|
||||
locale: string
|
||||
cardContainerClassName?: string
|
||||
cardRender?: (plugin: Plugin) => JSX.Element | null
|
||||
cardRender?: (plugin: Plugin) => React.JSX.Element | null
|
||||
onMoreClick?: () => void
|
||||
emptyClassName?: string
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@ type ListWithCollectionProps = {
|
||||
showInstallButton?: boolean
|
||||
locale: string
|
||||
cardContainerClassName?: string
|
||||
cardRender?: (plugin: Plugin) => JSX.Element | null
|
||||
cardRender?: (plugin: Plugin) => React.JSX.Element | null
|
||||
onMoreClick?: (searchParams?: SearchParamsFromCollection) => void
|
||||
}
|
||||
const ListWithCollection = ({
|
||||
@@ -37,7 +37,7 @@ const ListWithCollection = ({
|
||||
key={collection.name}
|
||||
className='py-3'
|
||||
>
|
||||
<div className='flex justify-between items-end'>
|
||||
<div className='flex items-end justify-between'>
|
||||
<div>
|
||||
<div className='title-xl-semi-bold text-text-primary'>{collection.label[getLanguage(locale)]}</div>
|
||||
<div className='system-xs-regular text-text-tertiary'>{collection.description[getLanguage(locale)]}</div>
|
||||
@@ -45,17 +45,17 @@ const ListWithCollection = ({
|
||||
{
|
||||
collection.searchable && onMoreClick && (
|
||||
<div
|
||||
className='flex items-center system-xs-medium text-text-accent cursor-pointer '
|
||||
className='system-xs-medium flex cursor-pointer items-center text-text-accent '
|
||||
onClick={() => onMoreClick?.(collection.search_params)}
|
||||
>
|
||||
{t('plugin.marketplace.viewMore')}
|
||||
<RiArrowRightSLine className='w-4 h-4' />
|
||||
<RiArrowRightSLine className='h-4 w-4' />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div className={cn(
|
||||
'grid grid-cols-4 gap-3 mt-2',
|
||||
'mt-2 grid grid-cols-4 gap-3',
|
||||
cardContainerClassName,
|
||||
)}>
|
||||
{
|
||||
|
@@ -39,19 +39,19 @@ const ListWrapper = ({
|
||||
return (
|
||||
<div
|
||||
style={{ scrollbarGutter: 'stable' }}
|
||||
className='relative flex flex-col grow px-12 py-2 bg-background-default-subtle'>
|
||||
className='relative flex grow flex-col bg-background-default-subtle px-12 py-2'>
|
||||
{
|
||||
plugins && (
|
||||
<div className='flex items-center mb-4 pt-3'>
|
||||
<div className='mb-4 flex items-center pt-3'>
|
||||
<div className='title-xl-semi-bold text-text-primary'>{t('plugin.marketplace.pluginsResult', { num: pluginsTotal })}</div>
|
||||
<div className='mx-3 w-[1px] h-3.5 bg-divider-regular'></div>
|
||||
<div className='mx-3 h-3.5 w-[1px] bg-divider-regular'></div>
|
||||
<SortDropdown locale={locale} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
isLoading && page === 1 && (
|
||||
<div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2'>
|
||||
<div className='absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2'>
|
||||
<Loading />
|
||||
</div>
|
||||
)
|
||||
|
@@ -46,33 +46,33 @@ const PluginTypeSwitch = ({
|
||||
{
|
||||
value: PLUGIN_TYPE_SEARCH_MAP.model,
|
||||
text: t('plugin.category.models'),
|
||||
icon: <RiBrain2Line className='mr-1.5 w-4 h-4' />,
|
||||
icon: <RiBrain2Line className='mr-1.5 h-4 w-4' />,
|
||||
},
|
||||
{
|
||||
value: PLUGIN_TYPE_SEARCH_MAP.tool,
|
||||
text: t('plugin.category.tools'),
|
||||
icon: <RiHammerLine className='mr-1.5 w-4 h-4' />,
|
||||
icon: <RiHammerLine className='mr-1.5 h-4 w-4' />,
|
||||
},
|
||||
{
|
||||
value: PLUGIN_TYPE_SEARCH_MAP.agent,
|
||||
text: t('plugin.category.agents'),
|
||||
icon: <RiSpeakAiLine className='mr-1.5 w-4 h-4' />,
|
||||
icon: <RiSpeakAiLine className='mr-1.5 h-4 w-4' />,
|
||||
},
|
||||
{
|
||||
value: PLUGIN_TYPE_SEARCH_MAP.extension,
|
||||
text: t('plugin.category.extensions'),
|
||||
icon: <RiPuzzle2Line className='mr-1.5 w-4 h-4' />,
|
||||
icon: <RiPuzzle2Line className='mr-1.5 h-4 w-4' />,
|
||||
},
|
||||
{
|
||||
value: PLUGIN_TYPE_SEARCH_MAP.bundle,
|
||||
text: t('plugin.category.bundles'),
|
||||
icon: <RiArchive2Line className='mr-1.5 w-4 h-4' />,
|
||||
icon: <RiArchive2Line className='mr-1.5 h-4 w-4' />,
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
'shrink-0 flex items-center justify-center py-3 bg-background-body space-x-2',
|
||||
'flex shrink-0 items-center justify-center space-x-2 bg-background-body py-3',
|
||||
searchBoxCanAnimate && 'sticky top-[56px] z-10',
|
||||
className,
|
||||
)}>
|
||||
@@ -81,7 +81,7 @@ const PluginTypeSwitch = ({
|
||||
<div
|
||||
key={option.value}
|
||||
className={cn(
|
||||
'flex items-center px-3 h-8 border border-transparent rounded-xl cursor-pointer hover:bg-state-base-hover hover:text-text-secondary system-md-medium text-text-tertiary',
|
||||
'system-md-medium flex h-8 cursor-pointer items-center rounded-xl border border-transparent px-3 text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary',
|
||||
activePluginType === option.value && 'border-components-main-nav-nav-button-border !bg-components-main-nav-nav-button-bg-active !text-components-main-nav-nav-button-text-active shadow-xs',
|
||||
)}
|
||||
onClick={() => {
|
||||
|
@@ -27,9 +27,9 @@ const SearchBox = ({
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'flex items-center z-[11]',
|
||||
size === 'large' && 'p-1.5 bg-components-panel-bg-blur rounded-xl shadow-md border border-components-chat-input-border',
|
||||
size === 'small' && 'p-0.5 bg-components-input-bg-normal rounded-lg',
|
||||
'z-[11] flex items-center',
|
||||
size === 'large' && 'rounded-xl border border-components-chat-input-border bg-components-panel-bg-blur p-1.5 shadow-md',
|
||||
size === 'small' && 'rounded-lg bg-components-input-bg-normal p-0.5',
|
||||
inputClassName,
|
||||
)}
|
||||
>
|
||||
@@ -39,12 +39,12 @@ const SearchBox = ({
|
||||
size={size}
|
||||
locale={locale}
|
||||
/>
|
||||
<div className='mx-1 w-[1px] h-3.5 bg-divider-regular'></div>
|
||||
<div className='relative grow flex items-center p-1 pl-2'>
|
||||
<div className='flex items-center mr-2 w-full'>
|
||||
<div className='mx-1 h-3.5 w-[1px] bg-divider-regular'></div>
|
||||
<div className='relative flex grow items-center p-1 pl-2'>
|
||||
<div className='mr-2 flex w-full items-center'>
|
||||
<input
|
||||
className={cn(
|
||||
'grow block outline-none appearance-none body-md-medium text-text-secondary bg-transparent',
|
||||
'body-md-medium block grow appearance-none bg-transparent text-text-secondary outline-none',
|
||||
)}
|
||||
value={search}
|
||||
onChange={(e) => {
|
||||
@@ -56,7 +56,7 @@ const SearchBox = ({
|
||||
search && (
|
||||
<div className='absolute right-2 top-1/2 -translate-y-1/2'>
|
||||
<ActionButton onClick={() => onSearchChange('')}>
|
||||
<RiCloseLine className='w-4 h-4' />
|
||||
<RiCloseLine className='h-4 w-4' />
|
||||
</ActionButton>
|
||||
</div>
|
||||
)
|
||||
|
@@ -27,7 +27,7 @@ const SearchBoxWrapper = ({
|
||||
return (
|
||||
<SearchBox
|
||||
inputClassName={cn(
|
||||
'mx-auto w-[640px] shrink-0 z-[0]',
|
||||
'z-[0] mx-auto w-[640px] shrink-0',
|
||||
searchBoxCanAnimate && 'sticky top-3 z-[11]',
|
||||
!intersected && searchBoxCanAnimate && 'w-[508px] transition-[width] duration-300',
|
||||
)}
|
||||
|
@@ -57,17 +57,17 @@ const TagsFilter = ({
|
||||
onClick={() => setOpen(v => !v)}
|
||||
>
|
||||
<div className={cn(
|
||||
'flex items-center text-text-tertiary rounded-lg hover:bg-state-base-hover cursor-pointer',
|
||||
size === 'large' && 'px-2 py-1 h-8',
|
||||
size === 'small' && 'pr-1.5 py-0.5 h-7 pl-1 ',
|
||||
'flex cursor-pointer items-center rounded-lg text-text-tertiary hover:bg-state-base-hover',
|
||||
size === 'large' && 'h-8 px-2 py-1',
|
||||
size === 'small' && 'h-7 py-0.5 pl-1 pr-1.5 ',
|
||||
selectedTagsLength && 'text-text-secondary',
|
||||
open && 'bg-state-base-hover',
|
||||
)}>
|
||||
<div className='p-0.5'>
|
||||
<RiFilter3Line className='w-4 h-4' />
|
||||
<RiFilter3Line className='h-4 w-4' />
|
||||
</div>
|
||||
<div className={cn(
|
||||
'flex items-center p-1 system-sm-medium',
|
||||
'system-sm-medium flex items-center p-1',
|
||||
size === 'large' && 'p-1',
|
||||
size === 'small' && 'px-0.5 py-1',
|
||||
)}>
|
||||
@@ -79,7 +79,7 @@ const TagsFilter = ({
|
||||
}
|
||||
{
|
||||
selectedTagsLength > 2 && (
|
||||
<div className='ml-1 system-xs-medium text-text-tertiary'>
|
||||
<div className='system-xs-medium ml-1 text-text-tertiary'>
|
||||
+{selectedTagsLength - 2}
|
||||
</div>
|
||||
)
|
||||
@@ -88,20 +88,20 @@ const TagsFilter = ({
|
||||
{
|
||||
!!selectedTagsLength && (
|
||||
<RiCloseCircleFill
|
||||
className='w-4 h-4 text-text-quaternary cursor-pointer'
|
||||
className='h-4 w-4 cursor-pointer text-text-quaternary'
|
||||
onClick={() => onTagsChange([])}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
!selectedTagsLength && (
|
||||
<RiArrowDownSLine className='w-4 h-4' />
|
||||
<RiArrowDownSLine className='h-4 w-4' />
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</PortalToFollowElemTrigger>
|
||||
<PortalToFollowElemContent className='z-[1000]'>
|
||||
<div className='w-[240px] border-[0.5px] border-components-panel-border bg-components-panel-bg-blur rounded-xl shadow-lg'>
|
||||
<div className='w-[240px] rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg'>
|
||||
<div className='p-2 pb-1'>
|
||||
<Input
|
||||
showLeftIcon
|
||||
@@ -110,19 +110,19 @@ const TagsFilter = ({
|
||||
placeholder={t('pluginTags.searchTags') || ''}
|
||||
/>
|
||||
</div>
|
||||
<div className='p-1 max-h-[448px] overflow-y-auto'>
|
||||
<div className='max-h-[448px] overflow-y-auto p-1'>
|
||||
{
|
||||
filteredOptions.map(option => (
|
||||
<div
|
||||
key={option.name}
|
||||
className='flex items-center px-2 py-1.5 h-7 rounded-lg cursor-pointer hover:bg-state-base-hover'
|
||||
className='flex h-7 cursor-pointer items-center rounded-lg px-2 py-1.5 hover:bg-state-base-hover'
|
||||
onClick={() => handleCheck(option.name)}
|
||||
>
|
||||
<Checkbox
|
||||
className='mr-1'
|
||||
checked={tags.includes(option.name)}
|
||||
/>
|
||||
<div className='px-1 system-sm-medium text-text-secondary'>
|
||||
<div className='system-sm-medium px-1 text-text-secondary'>
|
||||
{option.label}
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -57,29 +57,29 @@ const SortDropdown = ({
|
||||
onOpenChange={setOpen}
|
||||
>
|
||||
<PortalToFollowElemTrigger onClick={() => setOpen(v => !v)}>
|
||||
<div className='flex items-center px-2 pr-3 h-8 rounded-lg bg-state-base-hover-alt cursor-pointer'>
|
||||
<span className='mr-1 system-sm-regular text-text-secondary'>
|
||||
<div className='flex h-8 cursor-pointer items-center rounded-lg bg-state-base-hover-alt px-2 pr-3'>
|
||||
<span className='system-sm-regular mr-1 text-text-secondary'>
|
||||
{t('plugin.marketplace.sortBy')}
|
||||
</span>
|
||||
<span className='mr-1 system-sm-medium text-text-primary'>
|
||||
<span className='system-sm-medium mr-1 text-text-primary'>
|
||||
{selectedOption.text}
|
||||
</span>
|
||||
<RiArrowDownSLine className='w-4 h-4 text-text-tertiary' />
|
||||
<RiArrowDownSLine className='h-4 w-4 text-text-tertiary' />
|
||||
</div>
|
||||
</PortalToFollowElemTrigger>
|
||||
<PortalToFollowElemContent>
|
||||
<div className='p-1 rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur backdrop-blur-sm shadow-lg'>
|
||||
<div className='rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur p-1 shadow-lg backdrop-blur-sm'>
|
||||
{
|
||||
options.map(option => (
|
||||
<div
|
||||
key={`${option.value}-${option.order}`}
|
||||
className='flex items-center justify-between px-3 pr-2 h-8 cursor-pointer system-md-regular text-text-primary rounded-lg hover:bg-components-panel-on-panel-item-bg-hover'
|
||||
className='system-md-regular flex h-8 cursor-pointer items-center justify-between rounded-lg px-3 pr-2 text-text-primary hover:bg-components-panel-on-panel-item-bg-hover'
|
||||
onClick={() => handleSortChange({ sortBy: option.value, sortOrder: option.order })}
|
||||
>
|
||||
{option.text}
|
||||
{
|
||||
sort.sortBy === option.value && sort.sortOrder === option.order && (
|
||||
<RiCheckLine className='ml-2 w-4 h-4 text-text-accent' />
|
||||
<RiCheckLine className='ml-2 h-4 w-4 text-text-accent' />
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user