style: playground params styles
This commit is contained in:
@@ -1,6 +1,21 @@
|
|||||||
.m-b-20 {
|
.m-b-20 {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.m-l-10 {
|
.m-l-10 {
|
||||||
margin-left: 10px;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
@wrapheight: 54px;
|
@wrapheight: 54px;
|
||||||
@inputheight: 32px;
|
@inputheight: 32px;
|
||||||
@borderRadius: 20px;
|
@borderRadius: 20px;
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -13,6 +14,22 @@
|
|||||||
border-radius: @borderRadius;
|
border-radius: @borderRadius;
|
||||||
padding-inline: 12px;
|
padding-inline: 12px;
|
||||||
padding-block: 20px 0;
|
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 {
|
.extra {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 12px;
|
right: 12px;
|
||||||
@@ -23,8 +40,10 @@
|
|||||||
&.seal-input-wrapper-disabled {
|
&.seal-input-wrapper-disabled {
|
||||||
background-color: var(--ant-color-bg-container-disabled);
|
background-color: var(--ant-color-bg-container-disabled);
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: var(--ant-color-border);
|
border-color: var(--ant-color-border);
|
||||||
|
|
||||||
:global(.ant-input-search-button) {
|
:global(.ant-input-search-button) {
|
||||||
border-color: var(--ant-color-border) !important;
|
border-color: var(--ant-color-border) !important;
|
||||||
color: var(--ant-color-text-description) !important;
|
color: var(--ant-color-text-description) !important;
|
||||||
@@ -37,39 +56,47 @@
|
|||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.validate-status-error {
|
&.validate-status-error {
|
||||||
border-width: var(--ant-line-width);
|
border-width: var(--ant-line-width);
|
||||||
border-style: var(--ant-line-type);
|
border-style: var(--ant-line-type);
|
||||||
border-color: var(--ant-color-error);
|
border-color: var(--ant-color-error);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: var(--ant-color-error-border-hover);
|
border-color: var(--ant-color-error-border-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus-within {
|
&:focus-within {
|
||||||
border-color: var(--ant-color-error);
|
border-color: var(--ant-color-error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: var(--ant-input-hover-border-color);
|
border-color: var(--ant-input-hover-border-color);
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus-within {
|
&:focus-within {
|
||||||
border-color: var(--ant-input-active-border-color);
|
border-color: var(--ant-input-active-border-color);
|
||||||
box-shadow: var(--ant-input-active-shadow);
|
box-shadow: var(--ant-input-active-shadow);
|
||||||
outline: 0;
|
outline: 0;
|
||||||
background-color: var(--ant-input-active-bg);
|
background-color: var(--ant-input-active-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 24px;
|
left: 24px;
|
||||||
color: rgba(0, 0, 0, 0.45);
|
color: rgba(0, 0, 0, 45%);
|
||||||
font-size: var(--font-size-base);
|
font-size: var(--font-size-base);
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
z-index: 5;
|
z-index: 5;
|
||||||
|
|
||||||
&.isfoucs-has-value {
|
&.isfoucs-has-value {
|
||||||
top: 10px;
|
top: 10px;
|
||||||
transition: all 0.2s var(--seal-transition-func);
|
transition: all 0.2s var(--seal-transition-func);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.blur-no-value {
|
&.blur-no-value {
|
||||||
top: 21px;
|
top: 21px;
|
||||||
transition: all 0.2s var(--seal-transition-func);
|
transition: all 0.2s var(--seal-transition-func);
|
||||||
@@ -84,27 +111,32 @@
|
|||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
height: @inputheight !important;
|
height: @inputheight !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.ant-select-selector) {
|
:global(.ant-select-selector) {
|
||||||
border: none !important;
|
border: none !important;
|
||||||
padding-block: 5px;
|
padding-block: 5px;
|
||||||
padding-inline: 12px;
|
padding-inline: 12px;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.ant-select-selection-item) {
|
:global(.ant-select-selection-item) {
|
||||||
height: @inputheight !important;
|
height: @inputheight !important;
|
||||||
padding-block: 5px !important;
|
padding-block: 5px !important;
|
||||||
line-height: 22px !important;
|
line-height: 22px !important;
|
||||||
padding-inline-end: 0 !important;
|
padding-inline-end: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.ant-select-arrow) {
|
:global(.ant-select-arrow) {
|
||||||
top: 10px;
|
top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(
|
:global(
|
||||||
.ant-select-outlined.ant-select-disabled:not(.ant-select-customize-input)
|
.ant-select-outlined.ant-select-disabled:not(.ant-select-customize-input)
|
||||||
.ant-select-selector
|
.ant-select-selector
|
||||||
) {
|
) {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.ant-select-selection-search-input) {
|
:global(.ant-select-selection-search-input) {
|
||||||
height: @inputheight !important;
|
height: @inputheight !important;
|
||||||
}
|
}
|
||||||
@@ -119,6 +151,7 @@
|
|||||||
padding-inline: 12px;
|
padding-inline: 12px;
|
||||||
height: @inputheight !important;
|
height: @inputheight !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.ant-input-number) {
|
:global(.ant-input-number) {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -127,6 +160,7 @@
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
height: @inputheight !important;
|
height: @inputheight !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.ant-input-outlined) {
|
:global(.ant-input-outlined) {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -135,36 +169,46 @@
|
|||||||
padding-block: 5px;
|
padding-block: 5px;
|
||||||
padding-inline: 12px;
|
padding-inline: 12px;
|
||||||
height: @inputheight !important;
|
height: @inputheight !important;
|
||||||
|
|
||||||
&.seal-textarea {
|
&.seal-textarea {
|
||||||
min-height: 100px !important;
|
min-height: 100px !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.ant-input.ant-input-disabled) {
|
:global(.ant-input.ant-input-disabled) {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(input.ant-input-number-input) {
|
:global(input.ant-input-number-input) {
|
||||||
height: @inputheight !important;
|
height: @inputheight !important;
|
||||||
padding-block: 5px;
|
padding-block: 5px;
|
||||||
padding-inline: 12px;
|
padding-inline: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.ant-input-group) {
|
:global(.ant-input-group) {
|
||||||
position: static;
|
position: static;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.ant-input-group-addon) {
|
:global(.ant-input-group-addon) {
|
||||||
inset-inline-start: unset !important;
|
inset-inline-start: unset !important;
|
||||||
border-radius: 0 @borderRadius @borderRadius 0;
|
border-radius: 0 @borderRadius @borderRadius 0;
|
||||||
width: 30px;
|
width: 30px;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.ant-input-group-addon:hover) {
|
:global(.ant-input-group-addon:hover) {
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.ant-input-group-wrapper-disabled .ant-input-group-addon) {
|
:global(.ant-input-group-wrapper-disabled .ant-input-group-addon) {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.ant-input-group-wrapper-disabled .ant-input-group-addon:hover) {
|
:global(.ant-input-group-wrapper-disabled .ant-input-group-addon:hover) {
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.ant-input-search-button) {
|
:global(.ant-input-search-button) {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -20px;
|
top: -20px;
|
||||||
@@ -181,9 +225,7 @@
|
|||||||
top: -20px;
|
top: -20px;
|
||||||
height: @wrapheight - 2px;
|
height: @wrapheight - 2px;
|
||||||
}
|
}
|
||||||
:global(.ant-input-group-addon) {
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
:global(.ant-input-prefix) {
|
:global(.ant-input-prefix) {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 1px;
|
top: 1px;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ interface WrapperProps {
|
|||||||
className?: string;
|
className?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
extra?: React.ReactNode;
|
extra?: React.ReactNode;
|
||||||
|
variant?: string;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,6 +26,7 @@ const Wrapper: React.FC<WrapperProps> = ({
|
|||||||
description,
|
description,
|
||||||
required,
|
required,
|
||||||
extra,
|
extra,
|
||||||
|
variant,
|
||||||
onClick
|
onClick
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ interface WrapperProps {
|
|||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
variant?: string;
|
||||||
|
style?: React.CSSProperties;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,14 +22,19 @@ const Wrapper: React.FC<WrapperProps> = ({
|
|||||||
className,
|
className,
|
||||||
disabled,
|
disabled,
|
||||||
required,
|
required,
|
||||||
|
variant,
|
||||||
|
style,
|
||||||
description
|
description
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
style={{ ...style }}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
wrapperStyle.wrapper,
|
wrapperStyle.wrapper,
|
||||||
wrapperStyle[`validate-status-${status}`],
|
wrapperStyle[`validate-status-${status}`],
|
||||||
disabled ? wrapperStyle['seal-input-wrapper-disabled'] : '',
|
disabled ? wrapperStyle['seal-input-wrapper-disabled'] : '',
|
||||||
|
variant === 'filled' ? wrapperStyle['filled'] : '',
|
||||||
|
variant === 'borderless' ? wrapperStyle['borderless'] : '',
|
||||||
className ? wrapperStyle[className] : ''
|
className ? wrapperStyle[className] : ''
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const SealInputNumber: React.FC<InputNumberProps & SealFormItemProps> = (
|
|||||||
const handleClickWrapper = () => {
|
const handleClickWrapper = () => {
|
||||||
if (!props.disabled && !isFocus) {
|
if (!props.disabled && !isFocus) {
|
||||||
inputRef.current?.focus?.({
|
inputRef.current?.focus?.({
|
||||||
cursor: 'all'
|
cursor: 'end'
|
||||||
});
|
});
|
||||||
setIsFocus(true);
|
setIsFocus(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,111 +1,13 @@
|
|||||||
import type { InputProps } from 'antd';
|
import type { InputProps } from 'antd';
|
||||||
import { Form, Input } from 'antd';
|
import { Form, Input } from 'antd';
|
||||||
import type { TextAreaProps } from 'antd/es/input/TextArea';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
||||||
import Wrapper from './components/wrapper';
|
import Wrapper from './components/wrapper';
|
||||||
import SealInputNumber from './input-number';
|
import SealInputNumber from './input-number';
|
||||||
import SealInputSearch from './input-search';
|
import SealInputSearch from './input-search';
|
||||||
import SealPassword from './password';
|
import SealPassword from './password';
|
||||||
|
import SealTextArea from './seal-textarea';
|
||||||
import { SealFormItemProps } from './types';
|
import { SealFormItemProps } from './types';
|
||||||
|
|
||||||
const SealTextArea: React.FC<TextAreaProps & SealFormItemProps> = (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<any>(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 (
|
|
||||||
<Wrapper
|
|
||||||
status={status}
|
|
||||||
label={label || (placeholder as string)}
|
|
||||||
isFocus={isFocus}
|
|
||||||
required={required}
|
|
||||||
description={description}
|
|
||||||
className="seal-textarea-wrapper"
|
|
||||||
variant={variant}
|
|
||||||
extra={extra}
|
|
||||||
disabled={props.disabled}
|
|
||||||
onClick={handleClickWrapper}
|
|
||||||
>
|
|
||||||
<Input.TextArea
|
|
||||||
{...rest}
|
|
||||||
ref={inputRef}
|
|
||||||
style={{ minHeight: '80px', ...style }}
|
|
||||||
className="seal-textarea"
|
|
||||||
onFocus={handleOnFocus}
|
|
||||||
onBlur={handleOnBlur}
|
|
||||||
onInput={handleInput}
|
|
||||||
onChange={(e) => handleChange(e)}
|
|
||||||
></Input.TextArea>
|
|
||||||
</Wrapper>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const SealInput: React.FC<InputProps & SealFormItemProps> = (props) => {
|
const SealInput: React.FC<InputProps & SealFormItemProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
label,
|
label,
|
||||||
@@ -113,6 +15,7 @@ const SealInput: React.FC<InputProps & SealFormItemProps> = (props) => {
|
|||||||
required,
|
required,
|
||||||
description,
|
description,
|
||||||
isInFormItems = true,
|
isInFormItems = true,
|
||||||
|
variant,
|
||||||
...rest
|
...rest
|
||||||
} = props;
|
} = props;
|
||||||
const [isFocus, setIsFocus] = useState(false);
|
const [isFocus, setIsFocus] = useState(false);
|
||||||
@@ -132,7 +35,7 @@ const SealInput: React.FC<InputProps & SealFormItemProps> = (props) => {
|
|||||||
const handleClickWrapper = () => {
|
const handleClickWrapper = () => {
|
||||||
if (!props.disabled && !isFocus) {
|
if (!props.disabled && !isFocus) {
|
||||||
inputRef.current?.focus?.({
|
inputRef.current?.focus?.({
|
||||||
cursor: 'all'
|
cursor: 'end'
|
||||||
});
|
});
|
||||||
setIsFocus(true);
|
setIsFocus(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<TextAreaProps & SealFormItemProps> = (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<any>(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 (
|
||||||
|
<Wrapper
|
||||||
|
status={status}
|
||||||
|
label={label || (placeholder as string)}
|
||||||
|
isFocus={isFocus}
|
||||||
|
required={required}
|
||||||
|
description={description}
|
||||||
|
className="seal-textarea-wrapper"
|
||||||
|
extra={extra}
|
||||||
|
disabled={props.disabled}
|
||||||
|
onClick={handleClickWrapper}
|
||||||
|
>
|
||||||
|
<Input.TextArea
|
||||||
|
{...rest}
|
||||||
|
ref={inputRef}
|
||||||
|
style={{ minHeight: '80px', ...style }}
|
||||||
|
className="seal-textarea"
|
||||||
|
onFocus={handleOnFocus}
|
||||||
|
onBlur={handleOnBlur}
|
||||||
|
onInput={handleInput}
|
||||||
|
onChange={(e) => handleChange(e)}
|
||||||
|
></Input.TextArea>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SealTextArea;
|
||||||
@@ -3,37 +3,43 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&.bordered {
|
&.bordered {
|
||||||
border-width: var(--ant-line-width);
|
border-width: var(--ant-line-width);
|
||||||
border-style: var(--ant-line-type);
|
border-style: var(--ant-line-type);
|
||||||
border-color: var(--ant-color-border);
|
border-color: var(--ant-color-border);
|
||||||
background-color: var(--color-white-1);
|
background-color: var(--color-white-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.filled {
|
&.filled {
|
||||||
border-color: var(--ant-color-border);
|
border-color: var(--ant-color-border);
|
||||||
.content-wrapper {
|
|
||||||
|
.transition-content-wrapper {
|
||||||
background-color: var(--color-fill-1);
|
background-color: var(--color-fill-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
background-color: var(--color-fill-1);
|
background-color: var(--color-fill-1);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-wrapper {
|
.transition-content-wrapper {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: all 300ms ease-in-out;
|
transition: all 300ms ease-in-out;
|
||||||
.content {
|
|
||||||
|
.transition-content {
|
||||||
height: max-content;
|
height: max-content;
|
||||||
background-color: var(--color-white-1);
|
background-color: var(--color-white-1);
|
||||||
border-radius: var(--border-radius-base);
|
border-radius: var(--border-radius-base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-input {
|
.ant-input {
|
||||||
/* 只隐藏垂直滚动条轨道 */
|
/* 只隐藏垂直滚动条轨道 */
|
||||||
&::-webkit-scrollbar-track {
|
&::-webkit-scrollbar-track {
|
||||||
width: 0px !important;
|
width: 0 !important;
|
||||||
color: transparent;
|
color: transparent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,14 +62,14 @@ const TransitionWrapper: React.FC<TransitionWrapProps> = forwardRef(
|
|||||||
{header}
|
{header}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="content-wrapper"
|
className="transition-content-wrapper"
|
||||||
style={{
|
style={{
|
||||||
minHeight: isOpen ? height : 0,
|
minHeight: isOpen ? height : 0,
|
||||||
height: isOpen ? 'auto' : 0
|
height: isOpen ? 'auto' : 0
|
||||||
}}
|
}}
|
||||||
ref={contentRef}
|
ref={contentRef}
|
||||||
>
|
>
|
||||||
<div className="content">{children}</div>
|
<div className="transition-content">{children}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
+3
-1
@@ -2,12 +2,14 @@
|
|||||||
@import url('src/assets/styles/menu.less');
|
@import url('src/assets/styles/menu.less');
|
||||||
|
|
||||||
html {
|
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-1: #f3f6fa;
|
||||||
--color-fill-2: #fff;
|
--color-fill-2: #fff;
|
||||||
--color-fill-3: #f3f6fa;
|
--color-fill-3: #f3f6fa;
|
||||||
--menu-border-radius-base: 32px;
|
--menu-border-radius-base: 32px;
|
||||||
--border-radius-base: 16px;
|
--border-radius-base: 16px;
|
||||||
|
--border-radius-small: 8px;
|
||||||
--color-white-1: #fff;
|
--color-white-1: #fff;
|
||||||
--font-weight-normal: 500;
|
--font-weight-normal: 500;
|
||||||
--font-weight-bold: 700;
|
--font-weight-bold: 700;
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
export default {
|
export default {
|
||||||
'models.button.deploy': '部署模型'
|
'models.button.deploy': 'Deploy Model'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -318,7 +318,7 @@ const Models: React.FC = () => {
|
|||||||
{item.node_ip}:{item.port}
|
{item.node_ip}:{item.port}
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={5}>
|
<Col span={5}>
|
||||||
<span>{item.huggingface_repo_id}</span>
|
<span>{item.huggingface_filename}</span>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={4}>
|
<Col span={4}>
|
||||||
{dayjs(item.updated_at).format('YYYY-MM-DD HH:mm:ss')}
|
{dayjs(item.updated_at).format('YYYY-MM-DD HH:mm:ss')}
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ import SealInput from '@/components/seal-form/seal-input';
|
|||||||
import SealSelect from '@/components/seal-form/seal-select';
|
import SealSelect from '@/components/seal-form/seal-select';
|
||||||
import { INPUT_WIDTH } from '@/constants';
|
import { INPUT_WIDTH } from '@/constants';
|
||||||
import { queryModelsList } from '@/pages/llmodels/apis';
|
import { queryModelsList } from '@/pages/llmodels/apis';
|
||||||
import { Form, Slider } from 'antd';
|
import { Button, Form, InputNumber, Slider } from 'antd';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import CustomLabelStyles from '../style/custom-label.less';
|
||||||
|
|
||||||
type ParamsSettingsFormProps = {
|
type ParamsSettingsFormProps = {
|
||||||
seed?: number;
|
seed?: number;
|
||||||
@@ -90,9 +91,42 @@ const ParamsSettings: React.FC<ParamsSettingsProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleValuesChange = (changedValues: any, allValues: any) => {
|
const handleValuesChange = (changedValues: any, allValues: any) => {
|
||||||
console.log('handleValuesChange', changedValues, allValues);
|
|
||||||
setParams?.(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 (
|
||||||
|
<span
|
||||||
|
className={CustomLabelStyles.label}
|
||||||
|
style={{ width: INPUT_WIDTH.mini }}
|
||||||
|
>
|
||||||
|
<span className="text">{args.label}</span>
|
||||||
|
<InputNumber
|
||||||
|
className="label-val"
|
||||||
|
variant="outlined"
|
||||||
|
size="small"
|
||||||
|
value={form.getFieldValue(args.field)}
|
||||||
|
controls={false}
|
||||||
|
onChange={(val) => handleFieldValueChange(val, args.field)}
|
||||||
|
></InputNumber>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form
|
<Form
|
||||||
@@ -110,17 +144,32 @@ const ParamsSettings: React.FC<ParamsSettingsProps> = ({
|
|||||||
>
|
>
|
||||||
<SealSelect options={ModelList} label="Model"></SealSelect>
|
<SealSelect options={ModelList} label="Model"></SealSelect>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<h3 className="m-b-20 m-l-10">Parameters</h3>
|
<h3 className="m-b-20 m-l-10 flex-between flex-center">
|
||||||
|
<span>Parameters</span>
|
||||||
|
<Button size="small" onClick={handleResetParams}>
|
||||||
|
Reset
|
||||||
|
</Button>
|
||||||
|
</h3>
|
||||||
<Form.Item<ParamsSettingsFormProps>
|
<Form.Item<ParamsSettingsFormProps>
|
||||||
name="temperature"
|
name="temperature"
|
||||||
rules={[{ required: true }]}
|
rules={[{ required: true }]}
|
||||||
>
|
>
|
||||||
<FieldWrapper label="Temperature">
|
<FieldWrapper
|
||||||
|
label={renderLabel({
|
||||||
|
field: 'temperature',
|
||||||
|
label: 'Temperature'
|
||||||
|
})}
|
||||||
|
style={{ paddingLeft: 0 }}
|
||||||
|
variant="borderless"
|
||||||
|
>
|
||||||
<Slider
|
<Slider
|
||||||
defaultValue={1}
|
defaultValue={1}
|
||||||
max={2}
|
max={2}
|
||||||
step={0.1}
|
step={0.1}
|
||||||
style={{ marginBottom: 0 }}
|
style={{ marginBottom: 0 }}
|
||||||
|
tooltip={{ open: false }}
|
||||||
|
value={form.getFieldValue('temperature') || undefined}
|
||||||
|
onChange={(val) => handleFieldValueChange(val, 'temperature')}
|
||||||
></Slider>
|
></Slider>
|
||||||
</FieldWrapper>
|
</FieldWrapper>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -128,21 +177,49 @@ const ParamsSettings: React.FC<ParamsSettingsProps> = ({
|
|||||||
name="max_tokens"
|
name="max_tokens"
|
||||||
rules={[{ required: true }]}
|
rules={[{ required: true }]}
|
||||||
>
|
>
|
||||||
<SealInput.Number
|
<FieldWrapper
|
||||||
|
label={renderLabel({
|
||||||
|
field: 'max_tokens',
|
||||||
|
label: 'Max Tokens'
|
||||||
|
})}
|
||||||
|
style={{ paddingLeft: 0 }}
|
||||||
|
variant="borderless"
|
||||||
|
>
|
||||||
|
<Slider
|
||||||
|
defaultValue={1024}
|
||||||
|
max={16384}
|
||||||
|
step={1}
|
||||||
|
style={{ marginBottom: 0 }}
|
||||||
|
tooltip={{ open: false }}
|
||||||
|
value={form.getFieldValue('max_tokens') || undefined}
|
||||||
|
onChange={(val) => handleFieldValueChange(val, 'max_tokens')}
|
||||||
|
></Slider>
|
||||||
|
</FieldWrapper>
|
||||||
|
{/* <SealInput.Number
|
||||||
label="Max Tokens"
|
label="Max Tokens"
|
||||||
style={{ width: INPUT_WIDTH.mini }}
|
style={{ width: INPUT_WIDTH.mini }}
|
||||||
></SealInput.Number>
|
></SealInput.Number> */}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item<ParamsSettingsFormProps>
|
<Form.Item<ParamsSettingsFormProps>
|
||||||
name="top_p"
|
name="top_p"
|
||||||
rules={[{ required: true }]}
|
rules={[{ required: true }]}
|
||||||
>
|
>
|
||||||
<FieldWrapper label="Top P">
|
<FieldWrapper
|
||||||
|
label={renderLabel({
|
||||||
|
field: 'top_p',
|
||||||
|
label: 'Top P'
|
||||||
|
})}
|
||||||
|
style={{ paddingLeft: 0 }}
|
||||||
|
variant="borderless"
|
||||||
|
>
|
||||||
<Slider
|
<Slider
|
||||||
defaultValue={1}
|
defaultValue={1}
|
||||||
max={1}
|
max={1}
|
||||||
step={0.1}
|
step={0.1}
|
||||||
style={{ marginBottom: 0 }}
|
style={{ marginBottom: 0 }}
|
||||||
|
tooltip={{ open: false }}
|
||||||
|
value={form.getFieldValue('top_p') || undefined}
|
||||||
|
onChange={(val) => handleFieldValueChange(val, 'top_p')}
|
||||||
></Slider>
|
></Slider>
|
||||||
</FieldWrapper>
|
</FieldWrapper>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -150,10 +227,27 @@ const ParamsSettings: React.FC<ParamsSettingsProps> = ({
|
|||||||
name="seed"
|
name="seed"
|
||||||
rules={[{ required: true }]}
|
rules={[{ required: true }]}
|
||||||
>
|
>
|
||||||
<SealInput.Number
|
<FieldWrapper
|
||||||
|
label={renderLabel({
|
||||||
|
field: 'seed',
|
||||||
|
label: 'Seed'
|
||||||
|
})}
|
||||||
|
style={{ paddingLeft: 0 }}
|
||||||
|
variant="borderless"
|
||||||
|
>
|
||||||
|
<Slider
|
||||||
|
defaultValue={undefined}
|
||||||
|
step={1}
|
||||||
|
tooltip={{ open: false }}
|
||||||
|
value={form.getFieldValue('seed') || undefined}
|
||||||
|
onChange={(val) => handleFieldValueChange(val, 'seed')}
|
||||||
|
style={{ marginBottom: 0 }}
|
||||||
|
></Slider>
|
||||||
|
</FieldWrapper>
|
||||||
|
{/* <SealInput.Number
|
||||||
label="Seed"
|
label="Seed"
|
||||||
style={{ width: INPUT_WIDTH.mini }}
|
style={{ width: INPUT_WIDTH.mini }}
|
||||||
></SealInput.Number>
|
></SealInput.Number> */}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item<ParamsSettingsFormProps>
|
<Form.Item<ParamsSettingsFormProps>
|
||||||
name="stop"
|
name="stop"
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user