Skip to content

Commit

Permalink
✨ feat: 新增 Grid 模式
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx committed Aug 26, 2023
1 parent 02df71c commit dd5e8a2
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 66 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"dependencies": {
"@lobehub/chat-plugin-sdk": "^1",
"antd-style": "^3",
"polished": "^4.2.2",
"query-string": "^8",
"react-layout-kit": "^1"
},
Expand Down
81 changes: 81 additions & 0 deletions src/GridItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { createStyles } from 'antd-style';
import { rgba } from 'polished';
import { memo } from 'react';
import { Flexbox } from 'react-layout-kit';

import { SearchItem } from './type';

const useStyles = createStyles(({ css, token, cx }) => {
const title = css`
margin-top: 4px;
font-size: 16px;
`;
return {
container: css`
background: ${token.colorBgContainer};
border: 1px solid ${rgba(token.colorBorderSecondary, 0.5)};
border-radius: 8px;
:hover {
background: ${token.colorFillSecondary};
}
`,
desc: css`
color: ${token.colorTextTertiary};
`,
displayLink: css`
color: ${token.colorTextQuaternary};
`,
favicon: css`
border-radius: 50%;
`,
link: css`
&:hover {
.${cx(title)} {
text-decoration: underline;
}
}
display: flex;
flex: 1;
`,
title,
};
});

const GridItem = memo<SearchItem>(({ content, date, link, favicon, title, source }) => {
const { styles } = useStyles();

return (
<a className={styles.link} href={link!} rel="noreferrer" target={'_blank'}>
<Flexbox
className={styles.container}
distribution={'space-between'}
flex={1}
gap={12}
padding={12}
>
<Flexbox>
<Flexbox>
<Flexbox className={styles.title}>{title}</Flexbox>
</Flexbox>
<Flexbox className={styles.desc}>{date ? `${date} - ${content}` : content}</Flexbox>
</Flexbox>
<Flexbox align={'center'} gap={8} horizontal>
{favicon && (
<img
alt={title || link}
className={styles.favicon}
height={16}
src={favicon}
width={16}
/>
)}
<Flexbox>
<Flexbox className={styles.desc}>{source}</Flexbox>
</Flexbox>
</Flexbox>
</Flexbox>
</a>
);
});

export default GridItem;
76 changes: 76 additions & 0 deletions src/ListItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { createStyles } from 'antd-style';
import { memo } from 'react';
import { Flexbox } from 'react-layout-kit';

import { SearchItem } from './type';

const useStyles = createStyles(({ css, token, cx }) => {
const title = css`
margin-top: 4px;
font-size: 16px;
`;
return {
container: css`
overflow: scroll;
max-height: 370px;
`,
desc: css`
color: ${token.colorTextTertiary};
`,
displayLink: css`
color: ${token.colorTextQuaternary};
`,
favicon: css`
border-radius: 50%;
`,
item: css`
:not(:last-child) {
border-bottom: 1px solid ${token.colorBorder};
}
`,
link: css`
&:hover {
.${cx(title)} {
text-decoration: underline;
}
}
`,
title,
};
});

const ListItem = memo<SearchItem>(
({ content, date, link, favicon, title, displayed_link, source }) => {
const { styles } = useStyles();

return (
<Flexbox className={styles.item} distribution={'space-between'} horizontal padding={12}>
<Flexbox>
<a className={styles.link} href={link!} rel="noreferrer" target={'_blank'}>
<Flexbox>
<Flexbox align={'center'} gap={12} horizontal>
{favicon && (
<img
alt={title || link}
className={styles.favicon}
height={24}
src={favicon}
width={24}
/>
)}
<Flexbox>
<Flexbox className={styles.desc}>{source}</Flexbox>
<Flexbox className={styles.displayLink}>{displayed_link}</Flexbox>
</Flexbox>
</Flexbox>
<Flexbox className={styles.title}>{title}</Flexbox>
</Flexbox>
</a>
<Flexbox className={styles.desc}>{date ? `${date} - ${content}` : content}</Flexbox>
</Flexbox>
</Flexbox>
);
},
);

export default ListItem;
100 changes: 34 additions & 66 deletions src/Render.tsx
Original file line number Diff line number Diff line change
@@ -1,87 +1,55 @@
import { PluginRenderProps } from '@lobehub/chat-plugin-sdk';
import { Icon } from '@lobehub/ui';
import { Segmented } from 'antd';
import { createStyles } from 'antd-style';
import { memo } from 'react';
import { LucideLayoutGrid, LucideList } from 'lucide-react';
import { memo, useState } from 'react';
import { Flexbox } from 'react-layout-kit';

import GridItem from './GridItem';
import ListItem from './ListItem';
import { Result } from './type';

const useStyles = createStyles(({ css, token, cx }) => {
const title = css`
margin-top: 4px;
font-size: 16px;
`;
const useStyles = createStyles(({ css }) => {
return {
container: css`
overflow: scroll;
max-height: 370px;
`,
desc: css`
color: ${token.colorTextTertiary};
grid: css`
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 12px;
`,
displayLink: css`
color: ${token.colorTextQuaternary};
`,
favicon: css`
border-radius: 50%;
`,
item: css`
:not(:last-child) {
border-bottom: 1px solid ${token.colorBorder};
}
`,
link: css`
&:hover {
.${cx(title)} {
text-decoration: underline;
}
}
`,
title,
};
});

const Render = memo<PluginRenderProps<Result>>(({ content }) => {
const { styles } = useStyles();
const { styles, cx } = useStyles();
const [mode, setMode] = useState('grid');

const isGrid = mode === 'grid';
return (
<Flexbox className={styles.container}>
{content.map((item, index) => (
<Flexbox
className={styles.item}
distribution={'space-between'}
horizontal
key={item.link}
padding={12}
>
<Flexbox>
<a className={styles.link} href={item.link!} rel="noreferrer" target={'_blank'}>
<Flexbox>
<Flexbox align={'center'} gap={12} horizontal>
{item.favicon && (
<img
alt={item.title || item.link}
className={styles.favicon}
height={24}
src={item.favicon}
width={24}
/>
)}
<Flexbox>
<Flexbox className={styles.desc}>{item.source}</Flexbox>
<Flexbox className={styles.displayLink}>{item.displayed_link}</Flexbox>
</Flexbox>
</Flexbox>
<Flexbox align={'baseline'} gap={2} horizontal>
<div>{index + 1}.</div>
<Flexbox className={styles.title}>{item.title}</Flexbox>
</Flexbox>
</Flexbox>
</a>
<Flexbox className={styles.desc}>
{item.date ? `${item.date} - ${item.content}` : item.content}
</Flexbox>
</Flexbox>
<Flexbox gap={8}>
<Flexbox align={'center'} horizontal justify={'space-between'}>
<Flexbox>Search Results:{content.length}</Flexbox>
<Flexbox>
<Segmented
onChange={(v) => setMode(v as any)}
options={[
{ icon: <Icon icon={LucideLayoutGrid} />, value: 'grid' },
{ icon: <Icon icon={LucideList} />, value: 'list' },
]}
size={'small'}
value={mode}
/>
</Flexbox>
))}
</Flexbox>
<div className={cx(styles.container, isGrid && styles.grid)}>
{content.map((item) =>
isGrid ? <GridItem {...item} key={item.link} /> : <ListItem {...item} key={item.link} />,
)}
</div>
</Flexbox>
);
});
Expand Down

0 comments on commit dd5e8a2

Please sign in to comment.