♻️ refactor: improve popover trigger styles and component consistency (#11832)

- Add active state highlighting for group member items based on current route
- Add popover trigger styles for agent profile popup
- Replace antd Select with LobeSelect in SharePopover for UI consistency
This commit is contained in:
Innei
2026-01-26 01:43:58 +08:00
committed by GitHub
parent d424a81aa1
commit f5c5d52266
3 changed files with 39 additions and 5 deletions

View File

@@ -65,6 +65,13 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
color: ${cssVar.colorTextTertiary};
text-transform: uppercase;
`,
trigger: css`
border-radius: ${cssVar.borderRadius};
&[data-popup-open] {
background: ${cssVar.colorFillTertiary};
}
`,
}));
interface AgentProfilePopupProps extends PropsWithChildren {
@@ -169,7 +176,9 @@ const AgentProfilePopup = memo<AgentProfilePopupProps>(({ agent, groupId, childr
return (
<Popover
classNames={{ trigger: styles.trigger }}
content={content}
nativeButton={false}
onOpenChange={setOpen}
open={open}
placement="right"

View File

@@ -1,9 +1,11 @@
'use client';
import { ActionIcon, Flexbox } from '@lobehub/ui';
import { createStaticStyles } from 'antd-style';
import { UserMinus } from 'lucide-react';
import { memo, useState } from 'react';
import { memo, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useLocation } from 'react-router-dom';
import { DEFAULT_AVATAR } from '@/const/meta';
import NavItem from '@/features/NavPanel/components/NavItem';
@@ -20,6 +22,18 @@ import AddGroupMemberModal from '../AddGroupMemberModal';
import AgentProfilePopup from './AgentProfilePopup';
import GroupMemberItem from './GroupMemberItem';
const styles = createStaticStyles(({ css, cssVar }) => ({
memberTrigger: css`
border-radius: ${cssVar.borderRadius};
transition: background 0.2s ${cssVar.motionEaseOut};
&[data-popup-open],
&[data-active='true'] {
background: ${cssVar.colorFillTertiary};
}
`,
}));
interface GroupMemberProps {
addModalOpen: boolean;
groupId?: string;
@@ -32,6 +46,7 @@ interface GroupMemberProps {
const GroupMember = memo<GroupMemberProps>(({ addModalOpen, onAddModalOpenChange, groupId }) => {
const { t } = useTranslation('chat');
const router = useQueryRoute();
const location = useLocation();
const [nickname, username] = useUserStore((s) => [
userProfileSelectors.nickName(s),
userProfileSelectors.username(s),
@@ -43,6 +58,12 @@ const GroupMember = memo<GroupMemberProps>(({ addModalOpen, onAddModalOpenChange
const groupMembers = useAgentGroupStore(agentGroupSelectors.getGroupMembers(groupId || ''));
const activeTab = useMemo(() => new URLSearchParams(location.search).get('tab'), [location.search]);
const isProfileRoute = useMemo(() => {
if (!groupId) return false;
return location.pathname === `/group/${groupId}/profile`;
}, [groupId, location.pathname]);
const handleAddMembers = async (selectedAgents: string[]) => {
if (!groupId) {
console.error('No active group to add members to');
@@ -96,7 +117,11 @@ const GroupMember = memo<GroupMemberProps>(({ addModalOpen, onAddModalOpenChange
key={item.id}
onChat={() => handleMemberClick(item.id)}
>
<div onDoubleClick={() => handleMemberDoubleClick(item.id)}>
<div
className={styles.memberTrigger}
data-active={isProfileRoute && activeTab === item.id ? 'true' : undefined}
onDoubleClick={() => handleMemberDoubleClick(item.id)}
>
<GroupMemberItem
actions={
<ActionIcon

View File

@@ -3,13 +3,14 @@
import {
Button,
Flexbox,
LobeSelect,
Popover,
Skeleton,
Text,
copyToClipboard,
usePopoverContext,
} from '@lobehub/ui';
import { App, Divider, Select } from 'antd';
import { App, Divider } from 'antd';
import { ExternalLinkIcon, LinkIcon, LockIcon } from 'lucide-react';
import { type ReactNode, memo, useCallback, useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
@@ -146,9 +147,8 @@ const SharePopoverContent = memo<SharePopoverContentProps>(({ onOpenModal }) =>
<Flexbox gap={4}>
<Text type="secondary">{t('shareModal.popover.visibility')}</Text>
<Select
<LobeSelect
disabled={updating}
getPopupContainer={() => containerRef.current || document.body}
labelRender={({ value }) => {
const option = visibilityOptions.find((o) => o.value === value);
return (