chore: images create

This commit is contained in:
jialin
2024-11-22 10:00:34 +08:00
parent c3473673da
commit dde937f460
52 changed files with 1883 additions and 941 deletions
+39
View File
@@ -0,0 +1,39 @@
import { WarningOutlined } from '@ant-design/icons';
import { Typography } from 'antd';
import React from 'react';
interface AlertInfoProps {
type: 'danger' | 'warning';
message: string;
rows?: number;
icon?: React.ReactNode;
}
const AlertInfo: React.FC<AlertInfoProps> = (props) => {
const { message, type, rows = 1 } = props;
if (!message) {
return null;
}
return (
<Typography.Paragraph
type={type}
ellipsis={{
rows: rows,
tooltip: message
}}
style={{
textAlign: 'center',
padding: '2px 5px',
borderRadius: 'var(--border-radius-base)',
margin: 0,
backgroundColor: 'var(--ant-color-error-bg)'
}}
>
<WarningOutlined className="m-r-8" />
{message}
</Typography.Paragraph>
);
};
export default React.memo(AlertInfo);
+2 -1
View File
@@ -61,7 +61,7 @@ const AudioPlayer: React.FC<AudioPlayerProps> = forwardRef((props, ref) => {
setPlayOn(false);
setAudioState((prestate: any) => {
return {
currentTime: 0,
currentTime: audioRef.current?.ended ? 0 : prestate.currentTime,
duration: prestate.duration
};
});
@@ -87,6 +87,7 @@ const AudioPlayer: React.FC<AudioPlayerProps> = forwardRef((props, ref) => {
const handleLoadedMetadata = useCallback(
(data: any) => {
console.log('loadmetadata++++++++');
const duration = Math.ceil(audioRef.current?.duration || 0);
setAudioState({
currentTime: 0,
+27 -6
View File
@@ -1,3 +1,4 @@
import fallbackImg from '@/assets/images/img_fallback.png';
import {
DownloadOutlined,
EyeOutlined,
@@ -13,9 +14,16 @@ import { round } from 'lodash';
import React, { useCallback, useEffect, useState } from 'react';
import './index.less';
const AutoImage: React.FC<ImageProps & { height: number }> = (props) => {
const { height = 100, ...rest } = props;
const [width, setWidth] = useState(0);
const AutoImage: React.FC<
ImageProps & {
height: number | string;
width?: number | string;
autoSize?: boolean;
}
> = (props) => {
const { height = 100, width: w, autoSize, ...rest } = props;
const [width, setWidth] = useState(w || 0);
const [isError, setIsError] = useState(false);
const getImgRatio = useCallback((url: string): Promise<{ ratio: number }> => {
return new Promise((resolve) => {
@@ -31,8 +39,15 @@ const AutoImage: React.FC<ImageProps & { height: number }> = (props) => {
}, []);
const handleOnLoad = useCallback(async () => {
if (autoSize) {
return;
}
const { ratio } = await getImgRatio(props.src || '');
setWidth(height * ratio);
if (typeof height === 'number') {
setWidth(height * ratio);
} else {
throw new Error('Height must be a number');
}
}, [getImgRatio, height, props.src]);
const onDownload = () => {
@@ -47,6 +62,10 @@ const AutoImage: React.FC<ImageProps & { height: number }> = (props) => {
link.remove();
};
const handleOnError = () => {
setIsError(true);
};
useEffect(() => {
handleOnLoad();
}, [handleOnLoad]);
@@ -54,8 +73,10 @@ const AutoImage: React.FC<ImageProps & { height: number }> = (props) => {
return (
<AntImage
{...rest}
height={height}
width={width}
height={isError ? 'auto' : height}
width={isError ? '100%' : width}
onError={handleOnError}
fallback={fallbackImg}
preview={{
mask: <EyeOutlined />,
toolbarRender: (
+2
View File
@@ -12,6 +12,7 @@ import type {
TooltipComponentOption
} from 'echarts/components';
import {
DataZoomComponent,
DatasetComponent,
GridComponent,
LegendComponent,
@@ -44,6 +45,7 @@ echarts.use([
GridComponent,
DatasetComponent,
TransformComponent,
DataZoomComponent,
BarChart,
LineChart,
ScatterChart,
+38 -32
View File
@@ -17,35 +17,47 @@ const options: any = {
borderRadius: 4
},
xAxis: {
min: -1,
max: 1,
scale: false,
slient: true,
splitNumber: 15,
splitLine: {
lineStyle: {
color: 'rgba(5,5,5,0.06)'
color: '#F2F2F2'
}
},
axisLine: {
show: false
show: false,
lineStyle: {
color: '#F2F2F2'
}
},
axisTick: {
show: false
},
axisLabel: {
show: false
}
},
boundaryGap: [0.05, 0.05]
},
yAxis: {
min: -1,
max: 1,
scale: false,
slient: true,
splitNumber: 10,
boundaryGap: [0.05, 0.05],
splitLine: {
lineStyle: {
color: 'rgba(5,5,5,0.06)'
color: '#F2F2F2'
}
},
axisLine: {
show: false
show: false,
lineStyle: {
color: '#F2F2F2'
}
},
axisTick: {
show: false
@@ -54,6 +66,7 @@ const options: any = {
show: false
}
},
symbol: 'roundRect',
label: {
show: true,
@@ -67,16 +80,7 @@ const options: any = {
};
const Scatter: React.FC<ChartProps> = (props) => {
const {
seriesData,
xAxisData,
height,
width,
showEmpty,
labelFormatter,
legendData,
title
} = props;
const { seriesData, xAxisData, height, width, showEmpty, title } = props;
const chart = useRef<any>(null);
@@ -118,18 +122,21 @@ const Scatter: React.FC<ChartProps> = (props) => {
[]
);
const dataOptions = useMemo((): any => {
if (!seriesData.length) {
options.xAxis.min = 0;
options.xAxis.max = 1;
options.yAxis.min = 0;
options.yAxis.max = 1;
} else {
options.xAxis.min = null;
options.xAxis.max = null;
options.yAxis.min = null;
options.yAxis.max = null;
const renderNameInTooltip = useCallback((dataList: any[]) => {
if (!dataList.length || dataList.length < 2) {
return null;
}
const renderText = (item: any) => {
return `<span class="tooltip-item-name">
<span style="display:flex;justify-content:center;align-items: center;color:#fff;
margin-right:0;border-radius:4px;width:14px;
height:14px;background-color:${item?.itemStyle?.color};"
>${item.name}</span>
</span>`;
};
return renderText;
}, []);
const dataOptions = useMemo((): any => {
const seriseDataList = seriesData.map((item: any, index: number) => {
return {
...item,
@@ -147,15 +154,11 @@ const Scatter: React.FC<ChartProps> = (props) => {
formatter(params: any, callback?: (val: any) => any) {
const dataList = findOverlappingPoints(seriseDataList, params.data);
let result = '';
const renderText: any = renderNameInTooltip(dataList);
dataList.forEach((item: any) => {
result += `
<span class="tooltip-item" style="justify-content: flex-start;">
<span class="tooltip-item-name">
<span style="display:flex;justify-content:center;align-items: center;color:#fff;
margin-right:0;border-radius:4px;width:14px;
height:14px;background-color:${item.itemStyle?.color};"
>${item.name}</span>
</span>
${renderText ? renderText(item) : ''}
<span class="tooltip-value">${item.text}</span>
</span>`;
});
@@ -168,6 +171,9 @@ const Scatter: React.FC<ChartProps> = (props) => {
},
series: {
type: 'scatter',
labelLayout: {
hideOverlap: true
},
data: seriseDataList
}
};
@@ -9,6 +9,7 @@ interface CodeViewerProps {
ignoreIllegals?: boolean;
copyable?: boolean;
height?: string | number;
style?: React.CSSProperties;
}
const DarkViewer: React.FC<CodeViewerProps> = (props) => {
const {
@@ -22,6 +23,7 @@ const DarkViewer: React.FC<CodeViewerProps> = (props) => {
return (
<CodeViewer
style={props.style}
height={height}
code={code}
lang={lang}
@@ -9,6 +9,7 @@ interface CodeViewerProps {
ignoreIllegals?: boolean;
copyable?: boolean;
height?: string | number;
style?: React.CSSProperties;
}
const LightViewer: React.FC<CodeViewerProps> = (props) => {
const {
@@ -17,11 +18,13 @@ const LightViewer: React.FC<CodeViewerProps> = (props) => {
autodetect,
ignoreIllegals,
copyable,
style,
height = 'auto'
} = props || {};
return (
<CodeViewer
style={style}
height={height}
code={code}
lang={lang}
@@ -12,6 +12,7 @@ interface CodeViewerProps {
copyable?: boolean;
height?: string | number;
theme?: 'light' | 'dark';
style?: React.CSSProperties;
}
const CodeViewer: React.FC<CodeViewerProps> = (props) => {
const {
@@ -20,7 +21,8 @@ const CodeViewer: React.FC<CodeViewerProps> = (props) => {
autodetect = true,
ignoreIllegals = true,
copyable = true,
height = 'auto'
height = 'auto',
style
} = props || {};
const highlightedCode = useMemo(() => {
@@ -69,7 +71,8 @@ const CodeViewer: React.FC<CodeViewerProps> = (props) => {
}
)}
style={{
height: height
height: height,
...style
}}
>
<code
+4
View File
@@ -9,8 +9,10 @@ const HighlightCode: React.FC<{
copyable?: boolean;
theme?: 'light' | 'dark';
height?: string | number;
style?: React.CSSProperties;
}> = (props) => {
const {
style,
code,
lang = 'bash',
copyable = true,
@@ -26,9 +28,11 @@ const HighlightCode: React.FC<{
code={code}
copyable={copyable}
height={height}
style={style}
/>
) : (
<CodeViewerLight
style={style}
lang={lang}
code={code}
copyable={copyable}
@@ -13,6 +13,10 @@
border-radius: @borderRadius;
background-color: var(--color-white-1);
&.seal-input-number {
padding-right: 0;
}
&.borderless {
border: none;
box-shadow: none;
@@ -97,6 +101,12 @@
padding-block: 20px 0;
max-width: 100%;
&:hover {
:global(.ant-input-number-handler-wrap) {
width: 34px !important;
}
}
&.no-wrapper-style {
padding-block: 0;
}
@@ -201,6 +211,7 @@
height: @inputheight !important;
}
// ==================== input ====================
:global(.ant-input),
:global(.ant-input-password) {
// width: 100%;
@@ -221,6 +232,7 @@
}
:global(.ant-input-number) {
position: static;
display: flex;
align-items: center;
border: none;
@@ -228,6 +240,15 @@
padding: 0;
height: @inputheight !important;
background-color: @bgColor;
&:hover .ant-input-number-handler-wrap,
&-focused .ant-input-number-handler-wrap {
width: 34px !important;
}
&:hover {
cursor: text;
}
}
:global(.ant-input-outlined) {
@@ -293,13 +314,7 @@
}
:global(.ant-input-number-handler-wrap) {
top: -20px;
top: 0;
height: @wrapheight - 2px;
}
// :global(.ant-input-prefix) {
// position: absolute;
// top: 1px;
// left: -4px;
// }
}
@@ -68,6 +68,7 @@ const SealInputNumber: React.FC<InputNumberProps & SealFormItemProps> = (
description={description}
disabled={props.disabled}
onClick={handleClickWrapper}
className="seal-input-number"
>
<InputNumber
{...rest}
+5 -4
View File
@@ -10,11 +10,12 @@ interface SystemMessageProps {
value: string;
placeholder?: string;
label?: React.ReactNode;
height?: number;
onChange: (e: any) => void;
}
const RowTextarea: React.FC<SystemMessageProps> = (props) => {
const { value, onChange, style, label, placeholder } = props;
const { value, onChange, style, label, placeholder, height = 46 } = props;
const intl = useIntl();
const rowTextAreaRef = React.useRef<any>(null);
const [autoSize, setAutoSize] = useState<{
@@ -64,7 +65,7 @@ const RowTextarea: React.FC<SystemMessageProps> = (props) => {
style={{ display: autoSize.focus ? 'block' : 'none' }}
className="textarea-wrapper"
>
<span className="textarea-label">{label}</span>
{label && <span className="textarea-label">{label}</span>}
<Input.TextArea
className="custome-scrollbar"
ref={rowTextAreaRef}
@@ -87,8 +88,8 @@ const RowTextarea: React.FC<SystemMessageProps> = (props) => {
}
{!autoSize.focus && (
<div className="content-wrap" onClick={handleFocus}>
<div className="content">
<span className="title">{label}</span>
<div className="content" style={{ height: height }}>
{label && <span className="title">{label}</span>}
{value || (
<span style={{ color: 'var(--ant-color-text-tertiary)' }}>
{placeholder}
+19 -1
View File
@@ -1,7 +1,9 @@
import { isNotEmptyValue } from '@/utils/index';
import { useIntl } from '@umijs/max';
import type { SelectProps } from 'antd';
import { Form, Select } from 'antd';
import { useEffect, useRef, useState } from 'react';
import { cloneDeep } from 'lodash';
import { useEffect, useMemo, useRef, useState } from 'react';
import Wrapper from './components/wrapper';
import { SealFormItemProps } from './types';
@@ -12,9 +14,11 @@ const SealSelect: React.FC<SelectProps & SealFormItemProps> = (props) => {
children,
required,
description,
options,
isInFormItems = true,
...rest
} = props;
const intl = useIntl();
const [isFocus, setIsFocus] = useState(false);
const inputRef = useRef<any>(null);
let status = '';
@@ -23,6 +27,19 @@ const SealSelect: React.FC<SelectProps & SealFormItemProps> = (props) => {
status = statusData?.status || '';
}
const _options = useMemo(() => {
if (!options?.length) {
return [];
}
const list = cloneDeep(options);
return list.map((item: any) => {
if (item.locale) {
item.label = intl.formatMessage({ id: item.label as string });
}
return item;
});
}, [options, intl]);
useEffect(() => {
if (isNotEmptyValue(props.value)) {
setIsFocus(true);
@@ -70,6 +87,7 @@ const SealSelect: React.FC<SelectProps & SealFormItemProps> = (props) => {
<Select
{...rest}
ref={inputRef}
options={_options}
onFocus={handleOnFocus}
onBlur={handleOnBlur}
onChange={handleChange}
@@ -2,7 +2,7 @@
position: relative;
&.focus {
padding-top: 9px;
// padding-top: 9px;
}
.content-wrap {
@@ -15,7 +15,7 @@
&:hover {
.clear-btn {
display: block;
display: flex;
}
}
}
@@ -29,7 +29,8 @@
display: none;
position: absolute;
right: 6px;
top: 6px;
top: 50%;
transform: translateY(-50%);
}
.textarea-label {
@@ -41,8 +42,8 @@
.content {
flex: 1;
width: 100px;
height: 40px;
line-height: 24px;
height: 46px;
line-height: 30px;
padding: 8px 14px;
padding-right: 4px;
text-overflow: ellipsis;
+2 -2
View File
@@ -9,11 +9,11 @@ interface SpeechContentProps {
const SpeechContent: React.FC<SpeechContentProps> = (props) => {
console.log('SpeechContent', props);
return (
<div>
<>
{props.dataList.map((item) => (
<SpeechItem key={item.uid} {...item} />
))}
</div>
</>
);
};