Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Conversations style by RICH. #242

Merged
merged 11 commits into from
Nov 27, 2024
Binary file modified bun.lockb
Binary file not shown.
15 changes: 8 additions & 7 deletions components/conversations/GroupTitle.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { Divider, Typography } from 'antd';
import { Typography } from 'antd';
import type { ConfigProviderProps, GetProp } from 'antd';
import classnames from 'classnames';
import React from 'react';

export interface GroupTitleProps {
children?: React.ReactNode;
Expand All @@ -9,16 +10,16 @@ export interface GroupTitleProps {
// User should not care about internal state.
// Which should pass by context instead.
export const GroupTitleContext = React.createContext<{
direction?: GetProp<ConfigProviderProps, 'direction'>;
prefixCls?: GetProp<ConfigProviderProps, 'prefixCls'>;
}>(null!);

const GroupTitle: React.FC<GroupTitleProps> = ({ children }) => {
const { direction } = React.useContext(GroupTitleContext);
const { prefixCls } = React.useContext(GroupTitleContext);

return (
<Divider orientation={direction === 'rtl' ? 'right' : 'left'} plain>
{children && <Typography.Text type="secondary">{children}</Typography.Text>}
</Divider>
<div className={classnames(`${prefixCls}-group-title`)}>
{children && <Typography.Text>{children}</Typography.Text>}
</div>
);
};

Expand Down
10 changes: 5 additions & 5 deletions components/conversations/Item.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from 'react';
import { EllipsisOutlined } from '@ant-design/icons';
import { Dropdown, Tooltip, Typography } from 'antd';
import classnames from 'classnames';
import { Tooltip, Typography, Dropdown } from 'antd';
import { MoreOutlined } from '@ant-design/icons';
import React from 'react';

import type { MenuProps } from 'antd';
import type { DirectionType } from 'antd/es/config-provider';
import type { Conversation } from './interface';
import pickAttrs from 'rc-util/lib/pickAttrs';
import type { Conversation } from './interface';

export interface ConversationsItemProps
extends Omit<React.HTMLAttributes<HTMLLIElement>, 'onClick'> {
Expand Down Expand Up @@ -87,7 +87,7 @@ const ConversationsItem: React.FC<ConversationsItemProps> = (props) => {
disabled={disabled}
onOpenChange={onOpenChange}
>
<MoreOutlined
<EllipsisOutlined
onClick={stopPropagation}
disabled={disabled}
className={`${prefixCls}-menu-icon`}
Expand Down
61 changes: 18 additions & 43 deletions components/conversations/demo/basic.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,23 @@
import React from 'react';
import { Card } from 'antd';
import { Conversations } from '@ant-design/x';
import type { ConversationsProps } from '@ant-design/x';
import { GithubOutlined, AlipayCircleOutlined, DockerOutlined } from '@ant-design/icons';
import type { GetProp } from 'antd';
import { type GetProp, theme } from 'antd';
import React from 'react';

const items: GetProp<ConversationsProps, 'items'> = Array.from({ length: 4 }).map((_, index) => ({
key: `item${index + 1}`,
label: `Conversation Item ${index + 1}`,
disabled: index === 3,
}));

const items: GetProp<ConversationsProps, 'items'> = [
// Basic
{
key: 'item1',
label: 'What is Ant Design X?',
icon: <GithubOutlined />,
},
// label as ReactNode
{
key: 'item2',
label: (
<div>
Getting Started:{' '}
<a target="_blank" href="https://ant-design.antgroup.com/index-cn" rel="noreferrer">
Ant Design !
</a>
</div>
),
icon: <AlipayCircleOutlined />,
},
// Auto ellipsis
{
key: 'item3',
label: 'In Docker, use 🐑 Ollama and initialize',
icon: <DockerOutlined />,
},
// Disabled
{
key: 'item4',
label: 'Expired, please go to the recycle bin to check',
disabled: true,
},
];
export default () => {
const { token } = theme.useToken();

const App = () => (
<Card style={{ width: 320 }} size="small">
<Conversations items={items} defaultActiveKey="item1" />
</Card>
);
// Customize the style of the container
const style = {
width: 256,
background: token.colorBgContainer,
borderRadius: token.borderRadius,
};

export default App;
return <Conversations items={items} defaultActiveKey="item1" style={style} />;
};
26 changes: 17 additions & 9 deletions components/conversations/demo/controlled-mode.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { Card, type GetProp, Flex, Button } from 'antd';
import { Conversations, type ConversationsProps } from '@ant-design/x';
import { Button, Flex, type GetProp, theme } from 'antd';
import React, { useState } from 'react';

const items: GetProp<ConversationsProps, 'items'> = Array.from({ length: 3 }).map((_, index) => ({
key: `item${index + 1}`,
Expand All @@ -10,15 +10,23 @@ const items: GetProp<ConversationsProps, 'items'> = Array.from({ length: 3 }).ma
const App = () => {
const [activeKey, setActiveKey] = useState<string>('item1');

const { token } = theme.useToken();

// Customize the style of the container
const style = {
width: 256,
background: token.colorBgContainer,
borderRadius: token.borderRadius,
};

return (
<Flex vertical gap="small" align="flex-start">
<Card style={{ width: 320 }} size="small">
<Conversations
activeKey={activeKey}
onActiveChange={(v) => setActiveKey(v)}
items={items}
/>
</Card>
<Conversations
activeKey={activeKey}
onActiveChange={(v) => setActiveKey(v)}
items={items}
style={style}
/>

<Flex gap="small">
<Button
Expand Down
4 changes: 2 additions & 2 deletions components/conversations/demo/group-sort.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## zh-CN

通过 `groupable.sort` 属性对分组排序
通过 `groupable.sort` 属性对分组排序, 通过 `groupable.title` 自定义渲染分组

## en-US

sort the groups via the `groupable.sort` property
Use the `groupable.sort` property to sort groups, and the `groupable.title` property to customize group rendering.
103 changes: 45 additions & 58 deletions components/conversations/demo/group-sort.tsx
Original file line number Diff line number Diff line change
@@ -1,65 +1,52 @@
import React from 'react';
import { Card, Space, type GetProp } from 'antd';
import { CommentOutlined } from '@ant-design/icons';
import type { ConversationsProps } from '@ant-design/x';
import { Conversations } from '@ant-design/x';
import { GithubOutlined, AlipayCircleOutlined, DockerOutlined } from '@ant-design/icons';
import { type GetProp, Space, theme } from 'antd';
import React from 'react';

const items: GetProp<ConversationsProps, 'items'> = Array.from({ length: 6 }).map((_, index) => {
const timestamp = index <= 3 ? Date.now() : Date.now() - 1000 * 60 * 60 * 24 * 2;

return {
key: `item${index + 1}`,
label: `Conversation - ${new Date(timestamp + index * 60 * 60).toLocaleTimeString()}`,
timestamp: timestamp + index * 60,
group: index <= 3 ? 'Today' : 'Yesterday',
};
});

const App = () => {
const { token } = theme.useToken();

// Customize the style of the container
const style = {
width: 256,
background: token.colorBgContainer,
borderRadius: token.borderRadius,
};

const items: GetProp<ConversationsProps, 'items'> = [
{
key: 'demo1',
label: 'What is Ant Design X ?',
icon: <GithubOutlined />,
group: 'Pinned',
},
{
key: 'demo2',
label: (
<div>
Getting Started:{' '}
<a target="_blank" href="https://ant-design.antgroup.com/index-cn" rel="noreferrer">
Ant Design !
</a>
</div>
),
icon: <AlipayCircleOutlined />,
group: 'Pinned',
},
// 默认分组
{
key: 'demo4',
label: 'In Docker, use 🐑 Ollama and initialize',
icon: <DockerOutlined />,
},
{
key: 'demo5',
label: 'Expired, please go to the recycle bin to check',
disabled: true,
group: 'Expired',
},
];
const groupable: GetProp<typeof Conversations, 'groupable'> = {
sort(a, b) {
if (a === b) return 0;

const App = () => (
<Card style={{ width: 320 }} size="small">
<Conversations
groupable={{
sort(a, b) {
if (a === b) return 0;
return a === 'Today' ? -1 : 1;
},
title: (group, { components: { GroupTitle } }) =>
group ? (
<GroupTitle>
<Space>
<CommentOutlined />
<span>{group}</span>
</Space>
</GroupTitle>
) : (
<GroupTitle />
),
};

YumoImer marked this conversation as resolved.
Show resolved Hide resolved
return a === 'Pinned' ? -1 : 1;
},
title: (group, { components: { GroupTitle } }) =>
group ? (
<GroupTitle>
<Space>🔥{group}</Space>
</GroupTitle>
) : (
<GroupTitle />
),
}}
defaultActiveKey="demo1"
items={items}
/>
</Card>
);
return (
<Conversations style={style} groupable={groupable} defaultActiveKey="demo1" items={items} />
);
};

export default App;
60 changes: 20 additions & 40 deletions components/conversations/demo/group.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,25 @@
import React from 'react';
import { Card, type GetProp } from 'antd';
import { Conversations, type ConversationsProps } from '@ant-design/x';
import { GithubOutlined, AlipayCircleOutlined, DockerOutlined } from '@ant-design/icons';
import { type GetProp, theme } from 'antd';
import React from 'react';

const items: GetProp<ConversationsProps, 'items'> = Array.from({ length: 4 }).map((_, index) => ({
key: `item${index + 1}`,
label: `Conversation Item ${index + 1}`,
disabled: index === 3,
group: index === 3 ? 'Group2' : 'Group1',
}));

const App = () => {
const { token } = theme.useToken();

const items: GetProp<ConversationsProps, 'items'> = [
{
key: 'demo1',
label: 'What is Ant Design X ?',
icon: <GithubOutlined />,
group: 'Group1',
},
{
key: 'demo2',
label: (
<div>
Getting Started:{' '}
<a target="_blank" href="https://ant-design.antgroup.com/index-cn" rel="noreferrer">
Ant Design !
</a>
</div>
),
icon: <AlipayCircleOutlined />,
group: 'Group1',
},
{
key: 'demo4',
label: 'In Docker, use 🐑 Ollama and initialize',
icon: <DockerOutlined />,
group: 'Group2',
},
{
key: 'demo5',
label: 'Expired, please go to the recycle bin to check',
group: 'Group2',
},
];
// Customize the style of the container
const style = {
width: 256,
background: token.colorBgContainer,
borderRadius: token.borderRadius,
};

const App = () => (
<Card style={{ width: 320 }} size="small">
<Conversations groupable defaultActiveKey="demo1" items={items} />
</Card>
);
return <Conversations items={items} defaultActiveKey="item1" style={style} groupable />;
};

export default App;
Loading
Loading