diff --git a/package.json b/package.json index b1c35fc..2362fc1 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "dependencies": { "@lobehub/chat-plugin-sdk": "^1", "antd-style": "^3", + "polished": "^4.2.2", "query-string": "^8", "react-layout-kit": "^1" }, diff --git a/src/GridItem.tsx b/src/GridItem.tsx new file mode 100644 index 0000000..b8aeb34 --- /dev/null +++ b/src/GridItem.tsx @@ -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(({ content, date, link, favicon, title, source }) => { + const { styles } = useStyles(); + + return ( + + + + + {title} + + {date ? `${date} - ${content}` : content} + + + {favicon && ( + {title + )} + + {source} + + + + + ); +}); + +export default GridItem; diff --git a/src/ListItem.tsx b/src/ListItem.tsx new file mode 100644 index 0000000..6433463 --- /dev/null +++ b/src/ListItem.tsx @@ -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( + ({ content, date, link, favicon, title, displayed_link, source }) => { + const { styles } = useStyles(); + + return ( + + + + + + {favicon && ( + {title + )} + + {source} + {displayed_link} + + + {title} + + + {date ? `${date} - ${content}` : content} + + + ); + }, +); + +export default ListItem; diff --git a/src/Render.tsx b/src/Render.tsx index 5771aae..03b47d6 100644 --- a/src/Render.tsx +++ b/src/Render.tsx @@ -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>(({ content }) => { - const { styles } = useStyles(); + const { styles, cx } = useStyles(); + const [mode, setMode] = useState('grid'); + + const isGrid = mode === 'grid'; return ( - - {content.map((item, index) => ( - - - - - - {item.favicon && ( - {item.title - )} - - {item.source} - {item.displayed_link} - - - -
{index + 1}.
- {item.title} -
-
-
- - {item.date ? `${item.date} - ${item.content}` : item.content} - -
+ + + Search Results:{content.length} + + setMode(v as any)} + options={[ + { icon: , value: 'grid' }, + { icon: , value: 'list' }, + ]} + size={'small'} + value={mode} + /> - ))} + +
+ {content.map((item) => + isGrid ? : , + )} +
); });