From 4b748ee43a2836850dc21b0d8644307802e19f9a Mon Sep 17 00:00:00 2001 From: jialin Date: Fri, 25 Apr 2025 19:26:03 +0800 Subject: [PATCH] style: overlay scroller --- .eslintrc.js | 3 +- src/components/auto-tooltip/index.tsx | 27 +++----- src/components/auto-tooltip/title-tip.tsx | 17 ++--- src/components/editor-wrap/index.less | 17 +---- src/components/highlight-code/code-viewer.tsx | 2 +- src/components/highlight-code/index.tsx | 7 ++- src/components/logs-viewer/logs-list.tsx | 4 +- .../markdown-viewer/full-markdown.tsx | 5 +- src/components/markdown-viewer/index.less | 1 - src/components/overlay-scroller/index.tsx | 55 ++++++++++++---- src/components/simple-table/index.tsx | 23 ++----- src/components/status-tag/copy-btn.less | 5 -- src/components/status-tag/index.tsx | 63 +++++++++---------- src/global.less | 11 ++-- src/hooks/use-overlay-scroller.ts | 33 +++++++--- .../llmodels/components/instance-item.tsx | 16 +++-- src/pages/llmodels/style/hf-model-file.less | 2 +- .../components/multiple-chat/model-item.tsx | 2 +- 18 files changed, 144 insertions(+), 149 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index b809b228..2d38a7d7 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -8,7 +8,8 @@ module.exports = { '@typescript-eslint/class-name-casing': 'off' }, globals: { - Global: 'readonly' + Global: 'readonly', + React: 'readonly' }, ignorePatterns: ['public/static/'] }; diff --git a/src/components/auto-tooltip/index.tsx b/src/components/auto-tooltip/index.tsx index c3e15230..504a08d9 100644 --- a/src/components/auto-tooltip/index.tsx +++ b/src/components/auto-tooltip/index.tsx @@ -8,7 +8,7 @@ import React, { useRef, useState } from 'react'; -import TitleTip from './title-tip'; +import { TooltipOverlayScroller } from '../overlay-scroller'; // type TagProps = React.ComponentProps; @@ -91,23 +91,12 @@ const AutoTooltip: React.FC = ({ ); return ( - - {children} - - ) : ( - false - ) - } - {...tooltipProps} + {ghost ? (
@@ -139,7 +128,7 @@ const AutoTooltip: React.FC = ({ {children} )} - + ); }; diff --git a/src/components/auto-tooltip/title-tip.tsx b/src/components/auto-tooltip/title-tip.tsx index b267f05d..71c38de4 100644 --- a/src/components/auto-tooltip/title-tip.tsx +++ b/src/components/auto-tooltip/title-tip.tsx @@ -1,4 +1,4 @@ -import useOverlayScroller from '@/hooks/use-overlay-scroller'; +import { OverlayScroller } from '@/components/overlay-scroller'; import React from 'react'; interface TitleTipProps { @@ -10,27 +10,18 @@ interface TitleTipProps { const TitleTip: React.FC = (props) => { const { isOverflowing, showTitle, title, children } = props; - const { initialize } = useOverlayScroller(); - const scrollRef = React.useRef(null); - - React.useEffect(() => { - if (scrollRef.current) { - initialize(scrollRef.current); - } - }, [initialize, scrollRef.current]); return ( -
+
{isOverflowing || showTitle ? title || children : ''}
-
+ ); }; diff --git a/src/components/editor-wrap/index.less b/src/components/editor-wrap/index.less index f8059b42..65e6edeb 100644 --- a/src/components/editor-wrap/index.less +++ b/src/components/editor-wrap/index.less @@ -13,24 +13,9 @@ padding-inline: 12px 10px; justify-content: space-between; align-items: center; - background-color: rgb(56, 56, 56); - - .ant-select-selector { - background-color: rgba(255, 255, 255, 9%) !important; - color: rgba(255, 255, 255, 70%); - border-radius: var(--border-radius-2px); - - .ant-select-selection-item { - color: rgba(255, 255, 255, 70%); - } - } - - .ant-select-arrow { - color: rgba(255, 255, 255, 70%); - } + background-color: var(--color-editor-header-bg); } // set scrollbar style - .scrollbar { .slider { border-radius: 6px; diff --git a/src/components/highlight-code/code-viewer.tsx b/src/components/highlight-code/code-viewer.tsx index 93f09185..8b5210ff 100644 --- a/src/components/highlight-code/code-viewer.tsx +++ b/src/components/highlight-code/code-viewer.tsx @@ -36,7 +36,7 @@ const CodeHeaderWrapper = styled.div` border-top-left-radius: 4px; border-top-right-radius: 4px; &.dark { - background-color: #383838; + background-color: var(--color-editor-header-bg); color: rgba(255, 255, 255, 0.65); } `; diff --git a/src/components/highlight-code/index.tsx b/src/components/highlight-code/index.tsx index 15c41a8f..0d74d08c 100644 --- a/src/components/highlight-code/index.tsx +++ b/src/components/highlight-code/index.tsx @@ -9,6 +9,7 @@ const HighlightCode: React.FC<{ lang?: string; copyable?: boolean; theme?: 'light' | 'dark'; + fixedTheme?: 'light' | 'dark'; height?: string | number; style?: React.CSSProperties; copyValue?: string; @@ -19,14 +20,16 @@ const HighlightCode: React.FC<{ copyValue, lang = 'bash', copyable = true, - theme = 'dark', + theme, height = 'auto' } = props; const { userSettings } = useUserSettings(); const currentTheme = React.useMemo(() => { - return theme || userSettings.theme === 'realDark' ? 'dark' : 'light'; + const res = theme || userSettings.theme === 'realDark' ? 'dark' : 'light'; + console.log('currentTheme:', res, userSettings.theme, '===>', theme); + return res; }, [theme, userSettings.theme]); return ( diff --git a/src/components/logs-viewer/logs-list.tsx b/src/components/logs-viewer/logs-list.tsx index 08662b96..143d4c3d 100644 --- a/src/components/logs-viewer/logs-list.tsx +++ b/src/components/logs-viewer/logs-list.tsx @@ -31,7 +31,9 @@ const LogsList: React.FC = forwardRef((props, ref) => { initialized } = useOverlayScroller({ options: { - theme: 'os-theme-light' + scrollbars: { + theme: 'os-theme-light' + } } }); const [innerHieght, setInnerHeight] = useState( diff --git a/src/components/markdown-viewer/full-markdown.tsx b/src/components/markdown-viewer/full-markdown.tsx index ef1060a9..c5e34ae9 100644 --- a/src/components/markdown-viewer/full-markdown.tsx +++ b/src/components/markdown-viewer/full-markdown.tsx @@ -33,10 +33,7 @@ const CodeViewer = (props: any) => { ); }; -const FullMarkdown: React.FC = ({ - content, - theme = 'light' -}) => { +const FullMarkdown: React.FC = ({ content, theme }) => { const escapedContent = useMemo(() => { return escapeMhchem(escapeBrackets(escapeDollarNumber(content))); }, [content]); diff --git a/src/components/markdown-viewer/index.less b/src/components/markdown-viewer/index.less index 61338ac7..57bd7240 100644 --- a/src/components/markdown-viewer/index.less +++ b/src/components/markdown-viewer/index.less @@ -1,5 +1,4 @@ .markdown-viewer { - font-family: var(--font-family) !important; word-break: break-word; font-size: var(--font-size-base); diff --git a/src/components/overlay-scroller/index.tsx b/src/components/overlay-scroller/index.tsx index 48e8bcb1..d069ade1 100644 --- a/src/components/overlay-scroller/index.tsx +++ b/src/components/overlay-scroller/index.tsx @@ -1,4 +1,6 @@ -import useOverlayScroller from '@/hooks/use-overlay-scroller'; +import useOverlayScroller, { + OverlayScrollerOptions +} from '@/hooks/use-overlay-scroller'; import { Tooltip, TooltipProps } from 'antd'; import React from 'react'; import styled from 'styled-components'; @@ -10,16 +12,18 @@ const Wrapper = styled.div<{ $maxHeight?: number }>` width: 100%; `; -const OverlayScroller: React.FC = ({ - children, - maxHeight, - theme, - style -}) => { +export const OverlayScroller: React.FC< + OverlayScrollerOptions & { + maxHeight?: number; + style?: React.CSSProperties; + children: React.ReactNode; + } +> = ({ children, maxHeight, scrollbars, oppositeTheme, style }) => { const scroller = React.useRef(null); const { initialize } = useOverlayScroller({ options: { - theme: theme || 'os-theme-light' + scrollbars, + oppositeTheme } }); @@ -36,7 +40,6 @@ const OverlayScroller: React.FC = ({ className="overlay-scroller-wrapper" $maxHeight={maxHeight || 200} hidden={false} - as="div" style={{ paddingInlineStart: 8, paddingInlineEnd: 8, @@ -48,17 +51,43 @@ const OverlayScroller: React.FC = ({ ); }; +/** + * + * @param maxHeight: use for scrollbars + * @param theme: because this component is used for tooltip, so the default theme always is light + * @returns + */ export const TooltipOverlayScroller: React.FC< - TooltipProps & { maxHeight?: number } -> = ({ children, maxHeight, title, ...rest }) => { + OverlayScrollerOptions & { + maxHeight?: number; + title?: React.ReactNode; + children: React.ReactNode; + toolTipProps?: TooltipProps; + } +> = ({ + children, + maxHeight, + title, + toolTipProps, + scrollbars, + oppositeTheme +}) => { + const { overlayInnerStyle, ...rest } = toolTipProps || {}; return ( {title} + + {title} + ) } {...rest} diff --git a/src/components/simple-table/index.tsx b/src/components/simple-table/index.tsx index fb44f8aa..77bd4930 100644 --- a/src/components/simple-table/index.tsx +++ b/src/components/simple-table/index.tsx @@ -1,4 +1,3 @@ -import useOverlayScroller from '@/hooks/use-overlay-scroller'; import classNames from 'classnames'; import React from 'react'; import 'simplebar-react/dist/simplebar.min.css'; @@ -37,29 +36,19 @@ export interface ColumnProps { interface SimpleTableProps { theme?: 'dark' | 'light'; + maxHeight?: number | string; columns: ColumnProps[]; dataSource: any[]; bordered?: boolean; - rowKey?: string; + rowKey: string; } const SimpleTabel: React.FC = (props) => { - const { - columns, - dataSource, - rowKey, - bordered = true, - theme = 'dark' - } = props; - const scroller = React.useRef(null); - const { initialize } = useOverlayScroller(); + const { columns, dataSource, rowKey, bordered = true } = props; - React.useEffect(() => { - initialize(scroller.current); - }, [initialize]); return ( -
+
@@ -74,7 +63,7 @@ const SimpleTabel: React.FC = (props) => { rowIndex={index} columns={columns} dataList={dataSource} - key={rowKey ? item[rowKey] : index} + key={item[rowKey]} > ); })} diff --git a/src/components/status-tag/copy-btn.less b/src/components/status-tag/copy-btn.less index d05c2567..f0b3b9c1 100644 --- a/src/components/status-tag/copy-btn.less +++ b/src/components/status-tag/copy-btn.less @@ -25,8 +25,3 @@ } } } - -.simplebar-scrollbar::before { - background: var(--color-scroll-bg); - width: var(--scrollbar-size); -} diff --git a/src/components/status-tag/index.tsx b/src/components/status-tag/index.tsx index 30f23b36..175db791 100644 --- a/src/components/status-tag/index.tsx +++ b/src/components/status-tag/index.tsx @@ -3,10 +3,10 @@ import { StatusType } from '@/config/types'; import { InfoCircleOutlined } from '@ant-design/icons'; import { Button, Divider, Tooltip } from 'antd'; import classNames from 'classnames'; -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useMemo } from 'react'; import 'simplebar-react/dist/simplebar.min.css'; import CopyButton from '../copy-button'; -import SimpleOverlay from '../simple-overlay'; +import { TooltipOverlayScroller } from '../overlay-scroller'; import CopyStyle from './copy-btn.less'; import './index.less'; @@ -47,17 +47,13 @@ const StatusTag: React.FC = ({ type = 'tag' }) => { const { text, status } = statusValue; - const [statusColor, setStatusColor] = useState<{ + + const statusColor = useMemo<{ text: string; bg: string; border?: string; - }>({ - text: '', - bg: '' - }); - - useEffect(() => { - setStatusColor(StatusColorMap[status]); + }>(() => { + return StatusColorMap[status]; }, [status]); const statusMessage = useMemo(() => { @@ -85,6 +81,7 @@ const StatusTag: React.FC = ({ } return {text}; }; + const renderTitle = useMemo(() => { return (
@@ -118,24 +115,21 @@ const StatusTag: React.FC = ({ })}
- -
- {statusMessage} - {statusMessage && } - {extra} - {messageLink && ( - - )} -
-
+
+ {statusMessage} + {statusMessage && } + {extra} + {messageLink && ( + + )} +
); }, [statusValue]); @@ -150,11 +144,14 @@ const StatusTag: React.FC = ({ }} > {statusValue.message ? ( - @@ -162,7 +159,7 @@ const StatusTag: React.FC = ({ {renderContent()} - + ) : ( {renderContent()} )} diff --git a/src/global.less b/src/global.less index 322d931a..68bd0207 100644 --- a/src/global.less +++ b/src/global.less @@ -13,6 +13,7 @@ html { --scrollbar-handle-hover-bg: rgba(0, 0, 0, 55%); --color-editor-dark: #282c34; --color-editor-light: #fafafa; + --color-editor-header-bg: #383838; --color-scrollbar-track: #f4f5f4; // according to: --ant-color-fill-tertiary --color-fill-sider: #f4f5f4; --color-bg-1: #f4f5f4; @@ -69,13 +70,10 @@ html { --seal-transition-func: cubic-bezier(0, 0, 1, 1); --color-green-fill-light: rgb(243 251 248); --ant-rate-star-color: #fadb14; - --color-fill-mask: rgba(255, 255, 255, 60%); + --color-fill-spin-bg: rgba(255, 255, 255, 60%); --width-tooltip-max: 300px; --color-bg-tooltip: '#fff'; // ======== input ============ - --ant-input-active-shadow: 0 0 0 2px rgba(5, 255, 105, 6%); - --ant-input-active-border-color: #007bff; - --ant-input-hover-border-color: #2997ff; --box-shadow-base: 0 4px 6px rgba(227, 232, 240, 70%); --ant-border-radius-lg: 4px; --color-selected-bg: rgba(230, 230, 230, 88%); @@ -88,10 +86,11 @@ html[data-theme='realDark'] { --color-logs-bg: #141414; --color-white-1: #141414; --color-fill-sider: #1f1f1f; - --color-editor-dark: #141414; + --color-editor-dark: #00101f; --color-editor-light: #fafafa; - --color-fill-mask: rgba(255, 255, 255, 10%); + --color-fill-spin-bg: rgba(55, 55, 55, 50%); --color-bg-tooltip: #424242; + --color-editor-header-bg: #292929; background: #141414; } diff --git a/src/hooks/use-overlay-scroller.ts b/src/hooks/use-overlay-scroller.ts index f91a9e51..d54cf67d 100644 --- a/src/hooks/use-overlay-scroller.ts +++ b/src/hooks/use-overlay-scroller.ts @@ -1,11 +1,20 @@ -import { userSettingsHelperAtom } from '@/atoms/settings'; -import { useAtom } from 'jotai'; import { throttle } from 'lodash'; import { UseOverlayScrollbarsParams, useOverlayScrollbars } from 'overlayscrollbars-react'; import React, { useEffect } from 'react'; +import useUserSettings from './use-user-settings'; + +export interface OverlayScrollerOptions { + oppositeTheme?: boolean; + scrollbars?: { + theme?: 'os-theme-light' | 'os-theme-dark'; + autoHide?: 'never' | 'scroll' | 'leave' | 'move'; + autoHideDelay?: number; + clickScroll?: boolean | 'instant'; + }; +} export const overlaySollerOptions: UseOverlayScrollbarsParams = { options: { @@ -25,13 +34,19 @@ export const overlaySollerOptions: UseOverlayScrollbarsParams = { defer: true }; +/** + * + * @param options.theme: if set theme, it will fix the theme + * @returns + */ export default function useOverlayScroller(data?: { - options?: any; + options?: OverlayScrollerOptions; events?: any; defer?: boolean; }) { - const [useSettings] = useAtom(userSettingsHelperAtom); + const { userSettings } = useUserSettings(); const { options, events, defer = true } = data || {}; + const { scrollbars, oppositeTheme } = options || {}; const scrollEventElement = React.useRef(null); const instanceRef = React.useRef(null); const initialized = React.useRef(false); @@ -47,13 +62,13 @@ export default function useOverlayScroller(data?: { x: 'hidden' }, scrollbars: { - theme: - options?.theme || useSettings.theme === 'light' - ? 'os-theme-dark' - : 'os-theme-light', autoHide: 'scroll', autoHideDelay: 600, - clickScroll: 'instant' + clickScroll: 'instant', + ...scrollbars, + theme: + scrollbars?.theme || + (userSettings.theme === 'light' ? 'os-theme-dark' : 'os-theme-light') } }, events: { diff --git a/src/pages/llmodels/components/instance-item.tsx b/src/pages/llmodels/components/instance-item.tsx index 2a3b963f..5c533483 100644 --- a/src/pages/llmodels/components/instance-item.tsx +++ b/src/pages/llmodels/components/instance-item.tsx @@ -1,6 +1,7 @@ import AutoTooltip from '@/components/auto-tooltip'; import DropdownButtons from '@/components/drop-down-buttons'; import IconFont from '@/components/icon-font'; +import { TooltipOverlayScroller } from '@/components/overlay-scroller'; import RowChildren from '@/components/seal-table/components/row-children'; import SimpleTabel, { ColumnProps } from '@/components/simple-table'; import InfoColumn from '@/components/simple-table/info-column'; @@ -137,6 +138,7 @@ const RenderRayactorDownloading = (props: { @@ -473,11 +475,13 @@ const InstanceItem: React.FC = ({ return null; } return ( - @@ -501,7 +505,7 @@ const InstanceItem: React.FC = ({ id: 'models.table.acrossworker' })} - + ); }; diff --git a/src/pages/llmodels/style/hf-model-file.less b/src/pages/llmodels/style/hf-model-file.less index 5c87d034..b98a1201 100644 --- a/src/pages/llmodels/style/hf-model-file.less +++ b/src/pages/llmodels/style/hf-model-file.less @@ -58,7 +58,7 @@ top: 0; padding-top: 150px; text-align: center; - background-color: var(--color-fill-mask); + background-color: var(--color-fill-spin-bg); } } diff --git a/src/pages/playground/components/multiple-chat/model-item.tsx b/src/pages/playground/components/multiple-chat/model-item.tsx index 8738c70e..f9e3466d 100644 --- a/src/pages/playground/components/multiple-chat/model-item.tsx +++ b/src/pages/playground/components/multiple-chat/model-item.tsx @@ -284,7 +284,7 @@ const ModelItem: React.FC = forwardRef((props, ref) => {