From 9f34452c68492583a26bec8a7cec41c294148120 Mon Sep 17 00:00:00 2001 From: jialin Date: Wed, 19 Jun 2024 09:35:18 +0800 Subject: [PATCH] style: playground params styles --- src/assets/styles/common.less | 15 +++ .../seal-form/components/wrapper.less | 50 +++++++- .../seal-form/components/wrapper.tsx | 2 + src/components/seal-form/field-wrapper.tsx | 7 ++ src/components/seal-form/input-number.tsx | 2 +- src/components/seal-form/seal-input.tsx | 105 +--------------- src/components/seal-form/seal-textarea.tsx | 104 ++++++++++++++++ src/components/transition/index.less | 14 ++- src/components/transition/index.tsx | 4 +- src/global.less | 4 +- src/locales/zh-CN/models.ts | 2 +- src/pages/llmodels/index.tsx | 2 +- .../playground/components/params-settings.tsx | 112 ++++++++++++++++-- src/pages/playground/style/custom-label.less | 19 +++ 14 files changed, 318 insertions(+), 124 deletions(-) create mode 100644 src/components/seal-form/seal-textarea.tsx create mode 100644 src/pages/playground/style/custom-label.less diff --git a/src/assets/styles/common.less b/src/assets/styles/common.less index 9e1f6047..a176d749 100644 --- a/src/assets/styles/common.less +++ b/src/assets/styles/common.less @@ -1,6 +1,21 @@ .m-b-20 { margin-bottom: 20px; } + .m-l-10 { margin-left: 10px; } + +.flex { + display: flex; +} +// space-between +.flex-between { + display: flex; + justify-content: space-between; +} +// align-items: center +.flex-center { + display: flex; + align-items: center; +} diff --git a/src/components/seal-form/components/wrapper.less b/src/components/seal-form/components/wrapper.less index f68ce422..accd22df 100644 --- a/src/components/seal-form/components/wrapper.less +++ b/src/components/seal-form/components/wrapper.less @@ -2,6 +2,7 @@ @wrapheight: 54px; @inputheight: 32px; @borderRadius: 20px; + position: relative; display: flex; flex-direction: column; @@ -13,6 +14,22 @@ border-radius: @borderRadius; padding-inline: 12px; padding-block: 20px 0; + + &.filled { + border: none; + box-shadow: none; + } + + &.borderless { + border: none; + box-shadow: none; + } + + &.borderless:focus-within { + border: none; + box-shadow: none; + } + .extra { position: absolute; right: 12px; @@ -23,8 +40,10 @@ &.seal-input-wrapper-disabled { background-color: var(--ant-color-bg-container-disabled); cursor: not-allowed; + &:hover { border-color: var(--ant-color-border); + :global(.ant-input-search-button) { border-color: var(--ant-color-border) !important; color: var(--ant-color-text-description) !important; @@ -37,39 +56,47 @@ padding-bottom: 10px; padding-right: 10px; } + &.validate-status-error { border-width: var(--ant-line-width); border-style: var(--ant-line-type); border-color: var(--ant-color-error); + &:hover { border-color: var(--ant-color-error-border-hover); } + &:focus-within { border-color: var(--ant-color-error); } } + &:hover { border-color: var(--ant-input-hover-border-color); transition: all 0.2s ease; } + &:focus-within { border-color: var(--ant-input-active-border-color); box-shadow: var(--ant-input-active-shadow); outline: 0; background-color: var(--ant-input-active-bg); } + .label { position: absolute; left: 24px; - color: rgba(0, 0, 0, 0.45); + color: rgba(0, 0, 0, 45%); font-size: var(--font-size-base); line-height: 1; pointer-events: all; z-index: 5; + &.isfoucs-has-value { top: 10px; transition: all 0.2s var(--seal-transition-func); } + &.blur-no-value { top: 21px; transition: all 0.2s var(--seal-transition-func); @@ -84,27 +111,32 @@ box-shadow: none; height: @inputheight !important; } + :global(.ant-select-selector) { border: none !important; padding-block: 5px; padding-inline: 12px; box-shadow: none !important; } + :global(.ant-select-selection-item) { height: @inputheight !important; padding-block: 5px !important; line-height: 22px !important; padding-inline-end: 0 !important; } + :global(.ant-select-arrow) { top: 10px; } + :global( .ant-select-outlined.ant-select-disabled:not(.ant-select-customize-input) .ant-select-selector ) { background-color: transparent; } + :global(.ant-select-selection-search-input) { height: @inputheight !important; } @@ -119,6 +151,7 @@ padding-inline: 12px; height: @inputheight !important; } + :global(.ant-input-number) { display: flex; align-items: center; @@ -127,6 +160,7 @@ padding: 0; height: @inputheight !important; } + :global(.ant-input-outlined) { display: flex; align-items: center; @@ -135,36 +169,46 @@ padding-block: 5px; padding-inline: 12px; height: @inputheight !important; + &.seal-textarea { min-height: 100px !important; } } + :global(.ant-input.ant-input-disabled) { background-color: transparent; } + :global(input.ant-input-number-input) { height: @inputheight !important; padding-block: 5px; padding-inline: 12px; } + :global(.ant-input-group) { position: static; } + :global(.ant-input-group-addon) { inset-inline-start: unset !important; border-radius: 0 @borderRadius @borderRadius 0; width: 30px; background-color: transparent; + border: none; } + :global(.ant-input-group-addon:hover) { background-color: transparent !important; } + :global(.ant-input-group-wrapper-disabled .ant-input-group-addon) { background-color: transparent; } + :global(.ant-input-group-wrapper-disabled .ant-input-group-addon:hover) { background-color: transparent !important; } + :global(.ant-input-search-button) { position: absolute; top: -20px; @@ -181,9 +225,7 @@ top: -20px; height: @wrapheight - 2px; } - :global(.ant-input-group-addon) { - border: none; - } + :global(.ant-input-prefix) { position: absolute; top: 1px; diff --git a/src/components/seal-form/components/wrapper.tsx b/src/components/seal-form/components/wrapper.tsx index 99fa028a..c0e1fb42 100644 --- a/src/components/seal-form/components/wrapper.tsx +++ b/src/components/seal-form/components/wrapper.tsx @@ -12,6 +12,7 @@ interface WrapperProps { className?: string; disabled?: boolean; extra?: React.ReactNode; + variant?: string; onClick?: () => void; } @@ -25,6 +26,7 @@ const Wrapper: React.FC = ({ description, required, extra, + variant, onClick }) => { return ( diff --git a/src/components/seal-form/field-wrapper.tsx b/src/components/seal-form/field-wrapper.tsx index 0ec678f5..1d5ddfd8 100644 --- a/src/components/seal-form/field-wrapper.tsx +++ b/src/components/seal-form/field-wrapper.tsx @@ -10,6 +10,8 @@ interface WrapperProps { disabled?: boolean; required?: boolean; description?: string; + variant?: string; + style?: React.CSSProperties; onClick?: () => void; } @@ -20,14 +22,19 @@ const Wrapper: React.FC = ({ className, disabled, required, + variant, + style, description }) => { return (
diff --git a/src/components/seal-form/input-number.tsx b/src/components/seal-form/input-number.tsx index d52f0e4a..8a7c95f5 100644 --- a/src/components/seal-form/input-number.tsx +++ b/src/components/seal-form/input-number.tsx @@ -32,7 +32,7 @@ const SealInputNumber: React.FC = ( const handleClickWrapper = () => { if (!props.disabled && !isFocus) { inputRef.current?.focus?.({ - cursor: 'all' + cursor: 'end' }); setIsFocus(true); } diff --git a/src/components/seal-form/seal-input.tsx b/src/components/seal-form/seal-input.tsx index 0c6ed4f5..9f4119b8 100644 --- a/src/components/seal-form/seal-input.tsx +++ b/src/components/seal-form/seal-input.tsx @@ -1,111 +1,13 @@ import type { InputProps } from 'antd'; import { Form, Input } from 'antd'; -import type { TextAreaProps } from 'antd/es/input/TextArea'; -import { useCallback, useEffect, useRef, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import Wrapper from './components/wrapper'; import SealInputNumber from './input-number'; import SealInputSearch from './input-search'; import SealPassword from './password'; +import SealTextArea from './seal-textarea'; import { SealFormItemProps } from './types'; -const SealTextArea: React.FC = (props) => { - const { - label, - placeholder, - onChange, - onFocus, - onBlur, - onInput, - style, - required, - isInFormItems = true, - description, - variant, - extra, - ...rest - } = props; - const [isFocus, setIsFocus] = useState(false); - const inputRef = useRef(null); - let status = ''; - if (isInFormItems) { - const statusData = Form?.Item?.useStatus?.(); - status = statusData?.status || ''; - } - - useEffect(() => { - if (props.value) { - setIsFocus(true); - } - }, [props.value]); - - const handleClickWrapper = useCallback(() => { - if (!props.disabled && !isFocus) { - inputRef.current?.focus?.({ - cursor: 'all' - }); - setIsFocus(true); - } - }, [props.disabled, isFocus]); - - const handleChange = useCallback( - (e: any) => { - onChange?.(e); - }, - [onChange] - ); - - const handleOnFocus = useCallback( - (e: any) => { - setIsFocus(true); - onFocus?.(e); - }, - [onFocus] - ); - - const handleOnBlur = useCallback( - (e: any) => { - if (!inputRef.current?.resizableTextArea?.textArea?.value) { - setIsFocus(false); - onBlur?.(e); - } - }, - [onBlur] - ); - - const handleInput = useCallback( - (e: any) => { - onInput?.(e); - }, - [onInput] - ); - - return ( - - handleChange(e)} - > - - ); -}; - const SealInput: React.FC = (props) => { const { label, @@ -113,6 +15,7 @@ const SealInput: React.FC = (props) => { required, description, isInFormItems = true, + variant, ...rest } = props; const [isFocus, setIsFocus] = useState(false); @@ -132,7 +35,7 @@ const SealInput: React.FC = (props) => { const handleClickWrapper = () => { if (!props.disabled && !isFocus) { inputRef.current?.focus?.({ - cursor: 'all' + cursor: 'end' }); setIsFocus(true); } diff --git a/src/components/seal-form/seal-textarea.tsx b/src/components/seal-form/seal-textarea.tsx new file mode 100644 index 00000000..5f90fe6a --- /dev/null +++ b/src/components/seal-form/seal-textarea.tsx @@ -0,0 +1,104 @@ +import { Form, Input } from 'antd'; +import type { TextAreaProps } from 'antd/es/input/TextArea'; +import { useCallback, useEffect, useRef, useState } from 'react'; +import Wrapper from './components/wrapper'; +import { SealFormItemProps } from './types'; + +const SealTextArea: React.FC = (props) => { + const { + label, + placeholder, + onChange, + onFocus, + onBlur, + onInput, + style, + required, + isInFormItems = true, + description, + variant, + extra, + ...rest + } = props; + const [isFocus, setIsFocus] = useState(false); + const inputRef = useRef(null); + let status = ''; + if (isInFormItems) { + const statusData = Form?.Item?.useStatus?.(); + status = statusData?.status || ''; + } + + useEffect(() => { + if (props.value) { + setIsFocus(true); + } + }, [props.value]); + + const handleClickWrapper = useCallback(() => { + if (!props.disabled && !isFocus) { + inputRef.current?.focus?.({ + cursor: 'all' + }); + setIsFocus(true); + } + }, [props.disabled, isFocus]); + + const handleChange = useCallback( + (e: any) => { + onChange?.(e); + }, + [onChange] + ); + + const handleOnFocus = useCallback( + (e: any) => { + setIsFocus(true); + onFocus?.(e); + }, + [onFocus] + ); + + const handleOnBlur = useCallback( + (e: any) => { + if (!inputRef.current?.resizableTextArea?.textArea?.value) { + setIsFocus(false); + onBlur?.(e); + } + }, + [onBlur] + ); + + const handleInput = useCallback( + (e: any) => { + onInput?.(e); + }, + [onInput] + ); + + return ( + + handleChange(e)} + > + + ); +}; + +export default SealTextArea; diff --git a/src/components/transition/index.less b/src/components/transition/index.less index e1b2911a..f2643814 100644 --- a/src/components/transition/index.less +++ b/src/components/transition/index.less @@ -3,37 +3,43 @@ display: flex; flex-direction: column; overflow: hidden; + &.bordered { border-width: var(--ant-line-width); border-style: var(--ant-line-type); border-color: var(--ant-color-border); background-color: var(--color-white-1); } + &.filled { border-color: var(--ant-color-border); - .content-wrapper { + + .transition-content-wrapper { background-color: var(--color-fill-1); } } + .header { background-color: var(--color-fill-1); cursor: pointer; padding: 8px 16px; } - .content-wrapper { + .transition-content-wrapper { overflow: hidden; transition: all 300ms ease-in-out; - .content { + + .transition-content { height: max-content; background-color: var(--color-white-1); border-radius: var(--border-radius-base); } } + .ant-input { /* 只隐藏垂直滚动条轨道 */ &::-webkit-scrollbar-track { - width: 0px !important; + width: 0 !important; color: transparent; } } diff --git a/src/components/transition/index.tsx b/src/components/transition/index.tsx index 4bdb37ae..4852001b 100644 --- a/src/components/transition/index.tsx +++ b/src/components/transition/index.tsx @@ -62,14 +62,14 @@ const TransitionWrapper: React.FC = forwardRef( {header}
-
{children}
+
{children}
); diff --git a/src/global.less b/src/global.less index 43407303..7f1857fc 100644 --- a/src/global.less +++ b/src/global.less @@ -2,12 +2,14 @@ @import url('src/assets/styles/menu.less'); html { - --color-fill-1: rgba(0, 0, 0, 4%); + --ant-color-fill-tertiary: rgba(0, 0, 0, 4%); + --color-fill-1: var(--ant-color-fill-tertiary); // --color-fill-1: #f3f6fa; --color-fill-2: #fff; --color-fill-3: #f3f6fa; --menu-border-radius-base: 32px; --border-radius-base: 16px; + --border-radius-small: 8px; --color-white-1: #fff; --font-weight-normal: 500; --font-weight-bold: 700; diff --git a/src/locales/zh-CN/models.ts b/src/locales/zh-CN/models.ts index 00c3308a..12cd8e71 100644 --- a/src/locales/zh-CN/models.ts +++ b/src/locales/zh-CN/models.ts @@ -1,3 +1,3 @@ export default { - 'models.button.deploy': '部署模型' + 'models.button.deploy': 'Deploy Model' }; diff --git a/src/pages/llmodels/index.tsx b/src/pages/llmodels/index.tsx index adaf9328..b50c864c 100644 --- a/src/pages/llmodels/index.tsx +++ b/src/pages/llmodels/index.tsx @@ -318,7 +318,7 @@ const Models: React.FC = () => { {item.node_ip}:{item.port} - {item.huggingface_repo_id} + {item.huggingface_filename} {dayjs(item.updated_at).format('YYYY-MM-DD HH:mm:ss')} diff --git a/src/pages/playground/components/params-settings.tsx b/src/pages/playground/components/params-settings.tsx index 5e28218b..7390554a 100644 --- a/src/pages/playground/components/params-settings.tsx +++ b/src/pages/playground/components/params-settings.tsx @@ -3,9 +3,10 @@ import SealInput from '@/components/seal-form/seal-input'; import SealSelect from '@/components/seal-form/seal-select'; import { INPUT_WIDTH } from '@/constants'; import { queryModelsList } from '@/pages/llmodels/apis'; -import { Form, Slider } from 'antd'; +import { Button, Form, InputNumber, Slider } from 'antd'; import _ from 'lodash'; import { useEffect, useState } from 'react'; +import CustomLabelStyles from '../style/custom-label.less'; type ParamsSettingsFormProps = { seed?: number; @@ -90,9 +91,42 @@ const ParamsSettings: React.FC = ({ }; const handleValuesChange = (changedValues: any, allValues: any) => { - console.log('handleValuesChange', changedValues, allValues); setParams?.(allValues); }; + const handleFieldValueChange = (val: any, field: string) => { + const values = form.getFieldsValue(); + form.setFieldsValue({ + ...values, + [field]: val + }); + setParams({ + ...values, + [field]: val + }); + }; + + const handleResetParams = () => { + form.setFieldsValue(initialValues); + setParams(initialValues); + }; + const renderLabel = (args: { field: string; label: string }) => { + return ( + + {args.label} + handleFieldValueChange(val, args.field)} + > + + ); + }; return (
= ({ > -

Parameters

+

+ Parameters + +

name="temperature" rules={[{ required: true }]} > - + handleFieldValueChange(val, 'temperature')} > @@ -128,21 +177,49 @@ const ParamsSettings: React.FC = ({ name="max_tokens" rules={[{ required: true }]} > - + handleFieldValueChange(val, 'max_tokens')} + > + + {/* + > */} name="top_p" rules={[{ required: true }]} > - + handleFieldValueChange(val, 'top_p')} > @@ -150,10 +227,27 @@ const ParamsSettings: React.FC = ({ name="seed" rules={[{ required: true }]} > - + handleFieldValueChange(val, 'seed')} + style={{ marginBottom: 0 }} + > + + {/* + > */} name="stop" diff --git a/src/pages/playground/style/custom-label.less b/src/pages/playground/style/custom-label.less new file mode 100644 index 00000000..ea488240 --- /dev/null +++ b/src/pages/playground/style/custom-label.less @@ -0,0 +1,19 @@ +:local(.label) { + display: flex; + justify-content: space-between; + align-items: flex-start; + width: 100%; + + :global(.label-val) { + position: absolute; + top: -14px; + right: 26px; + width: 80px; + border-radius: var(--border-radius-small); + text-align: center; + + :global(.ant-input-number-input) { + text-align: center !important; + } + } +}