Skip to content

Commit 39294d1

Browse files
committed
fix: update folder name and interface
1 parent a8f0bfd commit 39294d1

File tree

11 files changed

+264
-79
lines changed

11 files changed

+264
-79
lines changed

src/chat/conversations/GroupTitle/index.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
import React from 'react';
22

33
import EllipsisText from '../../../ellipsisText';
4+
import { GroupTitleProps } from '../interface';
45
import './index.scss';
56

6-
export interface IGroupTitleProps {
7-
children?: React.ReactNode;
8-
prefixCls?: string;
9-
}
10-
11-
const GroupTitle: React.FC<IGroupTitleProps> = (props) => {
7+
const GroupTitle: React.FC<GroupTitleProps> = (props) => {
128
const { prefixCls = 'dtc-conversations' } = props;
139
return (
1410
<div className={`${prefixCls}-title`}>

src/chat/conversations/Item/index.tsx

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,13 @@
1-
import React, { HTMLAttributes } from 'react';
1+
import React from 'react';
22
import { MoreOutlined } from '@dtinsight/react-icons';
3-
import { Dropdown, DropdownProps } from 'antd';
3+
import { Dropdown } from 'antd';
44
import classNames from 'classnames';
55

66
import EllipsisText from '../../../ellipsisText';
7-
import { ConversationInfo } from '../interface';
7+
import { ConversationInfo, ConversationsItemProps } from '../interface';
88
import './index.scss';
99

10-
export interface IConversationsItemProps extends Omit<HTMLAttributes<HTMLLIElement>, 'onClick'> {
11-
info: ConversationInfo;
12-
active?: boolean;
13-
dropdown?: DropdownProps & {
14-
triggerDom?:
15-
| React.ReactNode
16-
| ((
17-
conversation: ConversationInfo,
18-
info: { originNode: React.ReactNode }
19-
) => React.ReactNode);
20-
};
21-
prefixCls?: string;
22-
onClick?: (info: ConversationInfo) => void;
23-
}
24-
25-
const Item: React.FC<IConversationsItemProps> = (props) => {
10+
const Item: React.FC<ConversationsItemProps> = (props) => {
2611
const { info, active, prefixCls, dropdown, onClick } = props;
2712

2813
const { disabled } = info;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.dtc-conversations-title {
2+
color: #B1B4C5;
3+
line-height: 20px;
4+
font-size: 12px;
5+
margin-bottom: 4px;
6+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import React from 'react';
2+
3+
import EllipsisText from '../../../ellipsisText';
4+
import { GroupTitleProps } from '../interface';
5+
import './index.scss';
6+
7+
const GroupTitle: React.FC<GroupTitleProps> = (props) => {
8+
const { prefixCls = 'dtc-conversations' } = props;
9+
return (
10+
<div className={`${prefixCls}-title`}>
11+
{props.children && (
12+
<EllipsisText
13+
value={props.children}
14+
maxWidth="100%"
15+
placement="right"
16+
destroyTooltipOnHide
17+
watchParentSizeChange
18+
/>
19+
)}
20+
</div>
21+
);
22+
};
23+
24+
export default GroupTitle;

src/chat/conversations/hooks/useGroupable.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@ import dayjs from 'dayjs';
33
import shortid from 'shortid';
44

55
import useLocale, { Locale } from '../../../locale/useLocale';
6-
import { ConversationInfo, Groupable, GroupInfo } from '../interface';
7-
import { IConversationsProps } from '..';
6+
import { ConversationInfo, ConversationsProps, Groupable, GroupInfo } from '../interface';
87

98
const DEFAULT_GROUP_KEY = 'updatedAt';
109
type GroupMap = Record<string, ConversationInfo[]>;
1110
const useGroupable = (
12-
groupable: IConversationsProps['groupable'],
11+
groupable: ConversationsProps['groupable'],
1312
conversations: ConversationInfo[]
1413
): [list: GroupInfo[], enable: boolean] => {
1514
const locale = useLocale('Chat');

src/chat/conversations/index.tsx

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,13 @@ import classNames from 'classnames';
55
import Empty from '../../empty';
66
import useLocale from '../../locale/useLocale';
77
import useGroupable from './hooks/useGroupable';
8-
import GroupTitle from './GroupTitle';
9-
import { ConversationInfo, Groupable } from './interface';
10-
import Item, { IConversationsItemProps } from './Item';
8+
import GroupTitle from './groupTitle';
9+
import { ConversationInfo, ConversationsProps } from './interface';
10+
import Item from './item';
1111
import './index.scss';
1212

13-
export interface IConversationsProps extends React.HTMLAttributes<HTMLUListElement> {
14-
conversations: ConversationInfo[];
15-
activeKey?: ConversationInfo['id'];
16-
defaultActiveKey?: ConversationInfo['id'];
17-
dropdown?:
18-
| IConversationsItemProps['dropdown']
19-
| ((info: ConversationInfo) => IConversationsItemProps['dropdown']);
20-
groupable?: boolean | Groupable;
21-
className?: string;
22-
style?: React.CSSProperties;
23-
loading?: boolean;
24-
header?: React.ReactNode | boolean;
25-
collapsed?: boolean;
26-
27-
onItemClick?: (info: ConversationInfo) => void;
28-
renderItem?: (props: IConversationsItemProps) => React.ReactNode;
29-
}
30-
3113
const prefixCls = 'dtc-conversations';
32-
const Conversations = (props: IConversationsProps) => {
14+
const Conversations = (props: ConversationsProps) => {
3315
const {
3416
conversations,
3517
activeKey,

src/chat/conversations/interface.ts

Lines changed: 100 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,122 @@
1+
import { HTMLAttributes } from 'react';
2+
import { DropdownProps } from 'antd';
3+
14
import { ConversationProperties } from '../entity';
2-
import { IGroupTitleProps } from './GroupTitle';
35

6+
/**
7+
* 单条会话信息结构
8+
* 用于描述侧边栏会话列表中的一项
9+
*/
410
export interface ConversationInfo extends ConversationProperties {
11+
/** 会话所属分组(用于分组展示,可选,默认以updateAt分组) */
512
group?: string;
13+
/** 会话项自定义图标 */
614
icon?: React.ReactNode;
15+
/** 是否禁用此会话(禁用点击与交互) */
716
disabled?: boolean;
817
}
9-
10-
export type GroupSorter = Parameters<[string, ConversationInfo[]][]['sort']>[0];
11-
12-
export type GroupTitleRenderComponents = {
13-
components: {
14-
GroupTitle: React.ComponentType<IGroupTitleProps>;
18+
/**
19+
* Conversations 会话组件入参
20+
* 用于渲染会话列表与相关交互
21+
*/
22+
export interface ConversationsProps extends React.HTMLAttributes<HTMLUListElement> {
23+
/** 会话列表数据源 */
24+
conversations: ConversationInfo[];
25+
/** 当前激活会话的 id(受控模式) */
26+
activeKey?: ConversationInfo['id'];
27+
/** 默认激活会话 id(非受控模式) */
28+
defaultActiveKey?: ConversationInfo['id'];
29+
/**
30+
* 自定义每一项的下拉菜单
31+
* - 传入对象时:所有项共享同一配置
32+
* - 传入方法时:可根据不同会话动态生成
33+
*/
34+
dropdown?:
35+
| ConversationsItemProps['dropdown']
36+
| ((info: ConversationInfo) => ConversationsItemProps['dropdown']);
37+
/** 是否启用按 group 分组展示(true 时使用默认配置,也可传入自定义 Groupable 配置) */
38+
groupable?: boolean | Groupable;
39+
className?: string;
40+
style?: React.CSSProperties;
41+
loading?: boolean;
42+
/** 列表头部区域内容(false 表示不展示) */
43+
header?: React.ReactNode | boolean;
44+
/** 是否为折叠状态(折叠时仅展示图标) */
45+
collapsed?: boolean;
46+
/** 点击某条会话时触发 */
47+
onItemClick?: (info: ConversationInfo) => void;
48+
/** 自定义渲染每一项的内容 */
49+
renderItem?: (props: ConversationsItemProps) => React.ReactNode;
50+
}
51+
/**
52+
* Conversations.Item 单个会话项组件的入参
53+
* 用于渲染侧边栏中的一条会话
54+
*/
55+
export interface ConversationsItemProps extends Omit<HTMLAttributes<HTMLLIElement>, 'onClick'> {
56+
/** 当前会话项的数据对象 */
57+
info: ConversationInfo;
58+
/** 是否为激活状态 */
59+
active?: boolean;
60+
/**
61+
* 下拉菜单配置(用于操作会话项)
62+
* - 可传入 DropdownProps
63+
* - 支持通过 triggerDom 自定义触发节点
64+
*/
65+
dropdown?: DropdownProps & {
66+
triggerDom?:
67+
| React.ReactNode
68+
| ((
69+
conversation: ConversationInfo,
70+
info: { originNode: React.ReactNode }
71+
) => React.ReactNode);
1572
};
16-
};
73+
prefixCls?: string;
74+
onClick?: (info: ConversationInfo) => void;
75+
}
76+
77+
/**
78+
* 分组组件入参
79+
*/
80+
export interface GroupTitleProps {
81+
/** 分组标题内容 */
82+
children?: React.ReactNode;
83+
prefixCls?: string;
84+
}
1785

86+
/**
87+
* 处理之后的分组数据
88+
*/
1889
export type GroupInfo = {
90+
/** 分组内的会话列表 */
1991
conversations: ConversationInfo[];
92+
/** 分组唯一标识(可选) */
2093
id?: string;
94+
/** 自定义渲染后的标题(Groupable.title 的结果) */
2195
title?: Groupable['title'];
2296
name?: string;
2397
};
98+
99+
/** 分组排序函数类型,来自 Array.sort 的入参类型 */
100+
export type GroupSorter = Parameters<[string, ConversationInfo[]][]['sort']>[0];
101+
102+
/** 自定义分组标题渲染时可访问的内置组件 */
103+
export type GroupTitleRenderComponents = {
104+
components: {
105+
GroupTitle: React.ComponentType<GroupTitleProps>;
106+
};
107+
};
108+
/**
109+
* 分组标题渲染函数
110+
* 用于完全自定义分组标题渲染逻辑
111+
*/
24112
export type GroupTitleRender =
25113
| ((groupInfo: GroupInfo, info: GroupTitleRenderComponents) => React.ReactNode)
26114
| undefined;
27115

116+
/**
117+
* 分组功能配置
118+
* 控制会话列表是否按 group 分组显示
119+
*/
28120
export interface Groupable {
29121
/**
30122
* @desc 分组排序函数
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
.dtc-conversations-item {
2+
display: flex;
3+
align-items: center;
4+
justify-content: center;
5+
height: 32px;
6+
gap: 4px;
7+
padding: 0 16px;
8+
border-radius: 4px;
9+
cursor: pointer;
10+
color: #3D446E;
11+
&-title {
12+
flex: 1;
13+
overflow: hidden;
14+
}
15+
&:hover {
16+
background-color: #EBECF0;
17+
.dtc-conversations-menu-icon {
18+
display: block;
19+
}
20+
}
21+
.dtc-conversations-menu-icon {
22+
display: none;
23+
}
24+
&--active, &--active:hover {
25+
color: #1D78FF;
26+
background-color: #E8F1FF;
27+
}
28+
&--disabled, &--disabled:hover {
29+
cursor: not-allowed;
30+
opacity: 0.5;
31+
}
32+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import React from 'react';
2+
import { MoreOutlined } from '@dtinsight/react-icons';
3+
import { Dropdown } from 'antd';
4+
import classNames from 'classnames';
5+
6+
import EllipsisText from '../../../ellipsisText';
7+
import { ConversationInfo, ConversationsItemProps } from '../interface';
8+
import './index.scss';
9+
10+
const Item: React.FC<ConversationsItemProps> = (props) => {
11+
const { info, active, prefixCls, dropdown, onClick } = props;
12+
13+
const { disabled } = info;
14+
const { triggerDom } = dropdown || {};
15+
16+
const handleClick = () => {
17+
if (disabled || active) return;
18+
onClick?.(info);
19+
};
20+
const stopPropagation = (e: React.MouseEvent) => {
21+
e.stopPropagation();
22+
};
23+
const renderMenuTrigger = (conversation: ConversationInfo) => {
24+
const originTriggerNode = (
25+
<MoreOutlined onClick={stopPropagation} className={`${prefixCls}-menu-icon`} />
26+
);
27+
if (triggerDom) {
28+
return typeof triggerDom === 'function'
29+
? triggerDom(conversation, { originNode: originTriggerNode })
30+
: triggerDom;
31+
}
32+
return originTriggerNode;
33+
};
34+
return (
35+
<div
36+
className={classNames(
37+
`${prefixCls}-item`,
38+
active && !disabled && `${prefixCls}-item--active`,
39+
disabled && `${prefixCls}-item--disabled`
40+
)}
41+
onClick={handleClick}
42+
>
43+
{info.icon && <div className={`${prefixCls}-item-icon`}>{info.icon}</div>}
44+
<div className={`${prefixCls}-item-title`}>
45+
<EllipsisText
46+
watchParentSizeChange
47+
value={info.title}
48+
placement="right"
49+
maxWidth="100%"
50+
destroyTooltipOnHide
51+
/>
52+
</div>
53+
{!disabled && dropdown?.overlay && (
54+
<Dropdown
55+
trigger={['click']}
56+
placement="bottom"
57+
arrow
58+
overlayStyle={{ minWidth: '80px' }}
59+
{...dropdown}
60+
disabled={disabled}
61+
>
62+
{renderMenuTrigger(info)}
63+
</Dropdown>
64+
)}
65+
</div>
66+
);
67+
};
68+
69+
export default Item;

src/chat/demos/components/customConversationItem.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import React from 'react';
22
import { Input, message } from 'antd';
33
import classNames from 'classnames';
44
import { Chat } from 'dt-react-component';
5-
import { IConversationsItemProps } from 'dt-react-component/chat/conversations/Item';
5+
import { ConversationsItemProps } from 'dt-react-component/chat/conversations/interface';
66

7-
interface IProps extends IConversationsItemProps {
8-
edit?: IConversationsItemProps['info'];
9-
onRename?: (info: IConversationsItemProps['info'], value: string) => Promise<boolean>;
10-
setEdit: (edit?: IConversationsItemProps['info']) => void;
7+
interface IProps extends ConversationsItemProps {
8+
edit?: ConversationsItemProps['info'];
9+
onRename?: (info: ConversationsItemProps['info'], value: string) => Promise<boolean>;
10+
setEdit: (edit?: ConversationsItemProps['info']) => void;
1111
}
1212

1313
export default function CustomConversionItem(props: IProps) {

0 commit comments

Comments
 (0)