chore: dark config

main
jialin 12 months ago
parent d4d7148f16
commit ce9c31f368

@ -1,7 +1,6 @@
.ant-pro-layout {
.ant-pro-sider {
.ant-layout-sider-children {
background-color: var(--color-fill-1);
border-inline: none;
border-radius: 0;
// padding-inline: 16px;

@ -0,0 +1,21 @@
import { atom } from 'jotai';
import { atomWithStorage } from 'jotai/utils';
type UserSettings = {
theme: 'light' | 'realDark';
};
export const userSettingsAtom = atomWithStorage<UserSettings>('userSettings', {
theme: 'light'
});
export const userSettingsHelperAtom = atom(
(get) => get(userSettingsAtom),
(get, set, update: Partial<UserSettings>) => {
const prev = get(userSettingsAtom);
set(userSettingsAtom, {
...prev,
...(update || {})
});
}
);

@ -3,5 +3,5 @@
background-color: var(--color-white-1);
box-shadow: none;
padding: 10px;
border: 1px solid var(--color-border-1);
border: 1px solid var(--ant-color-border);
}

@ -1,16 +1,8 @@
import Chart from '@/components/echarts/chart';
import {
barItemConfig,
grid,
legend,
title as titleConfig,
tooltip,
xAxis,
yAxis
} from '@/components/echarts/config';
import useChartConfig from '@/components/echarts/config';
import EmptyData from '@/components/empty-data';
import _ from 'lodash';
import { memo, useMemo } from 'react';
import React, { memo, useMemo } from 'react';
import { ChartProps } from './types';
const BarChart: React.FC<ChartProps> = (props) => {
@ -23,6 +15,15 @@ const BarChart: React.FC<ChartProps> = (props) => {
legendData,
title
} = props;
const {
barItemConfig,
grid,
legend,
title: titleConfig,
tooltip,
xAxis,
yAxis
} = useChartConfig();
const options = {
title: {

@ -0,0 +1,75 @@
import React from 'react';
import styled from 'styled-components';
const TooltipWrapper = styled.div`
display: flex;
flex-direction: column;
gap: 4px;
font-size: 11px;
background-color: rgba(255, 255, 255, 80%);
min-width: 100px;
max-width: 360px;
.tooltip-x-name {
font-size: var(--font-size-base);
color: var(--ant-color-text-tertiary);
}
.tooltip-item {
color: var(--ant-color-text-secondary);
display: flex;
justify-content: space-between;
align-items: center;
.tooltip-item-title {
margin-right: 2px;
}
.tooltip-value {
margin-left: 10px;
color: var(--ant-color-text);
text-overflow: ellipsis;
overflow: hidden;
}
}
`;
const ItemSymbol = styled.span<{ $color: string }>`
background-color: ${(props) => props.$color};
display: inline-block;
marginright: 5px;
borderradius: 8px;
width: 8px;
height: 8px;
`;
interface ChartTooltipProps {
params: any[];
callback?: (val: any) => any;
}
const ChartTooltip: React.FC<ChartTooltipProps> = (props) => {
const { params, callback } = props;
console.log('params====', params);
return (
<TooltipWrapper>
<span className="tooltip-x-name">{params[0]?.axisValue}</span>
<>
{params.map((item: any, index: number) => {
let value = callback?.(item.data.value) || item.data.value;
return (
<span className="tooltip-item" key={index}>
<span className="tooltip-item-name">
<ItemSymbol $color={item.color}></ItemSymbol>
<span className="tooltip-title">{item.seriesName}</span>:
</span>
<span className="tooltip-value">{value}</span>
</span>
);
})}
</>
</TooltipWrapper>
);
};
export default ChartTooltip;

@ -1,5 +1,5 @@
import { throttle } from 'lodash';
import {
import React, {
forwardRef,
useCallback,
useEffect,
@ -36,13 +36,16 @@ const Chart: React.FC<{
chart.current?.resize();
}, []);
const setOption = useCallback((options: ECOption) => {
chart.current?.clear();
chart.current?.setOption(options, {
notMerge: true,
lazyUpdate: true
});
}, []);
const setOption = useCallback(
(options: ECOption) => {
chart.current?.clear();
chart.current?.setOption(options, {
notMerge: true,
lazyUpdate: true
});
},
[options]
);
useEffect(() => {
if (container.current) {
@ -79,17 +82,6 @@ const Chart: React.FC<{
};
}, []);
// resize on window resize
// useEffect(() => {
// const handleResize = throttle(() => {
// chart.current?.resize();
// }, 100);
// window.addEventListener('resize', handleResize);
// return () => {
// window.removeEventListener('resize', handleResize);
// };
// }, []);
return (
<div className="chart-wrapper" style={{ width: width, height }}>
<div ref={container} style={{ width: width, height }}></div>

@ -1,8 +1,7 @@
import useUserSettings from '@/hooks/use-user-settings';
import { theme } from 'antd';
import { isFunction } from 'lodash';
const chartColorMap = {
tickLineColor: 'rgba(217,217,217,0.5)',
axislabelColor: 'rgba(0, 0, 0, 0.4)'
};
import { useMemo } from 'react';
const formatLargeNumber = (value: number) => {
if (typeof value !== 'number' || isNaN(value)) {
@ -20,29 +19,6 @@ const formatLargeNumber = (value: number) => {
}
};
export const tooltip = {
trigger: 'axis',
// axisPointer: {
// type: 'shadow'
// }
formatter(params: any, callback?: (val: any) => any) {
let result = `<span class="tooltip-x-name">${params[0].axisValue}</span>`;
params.forEach((item: any) => {
let value = isFunction(callback)
? callback?.(item.data.value)
: item.data.value;
result += `<span class="tooltip-item">
<span class="tooltip-item-name">
<span style="display:inline-block;margin-right:5px;border-radius:8px;width:8px;height:8px;background-color:${item.color};"></span>
<span class="tooltip-title">${item.seriesName}</span>:
</span>
<span class="tooltip-value">${value}</span>
</span>`;
});
return `<div class="tooltip-wrapper">${result}</div>`;
}
};
export const grid = {
left: 0,
right: 20,
@ -50,159 +26,216 @@ export const grid = {
containLabel: true
};
export const legend = {
itemWidth: 8,
itemHeight: 8
};
export default function useChartConfig() {
const { userSettings, isDarkTheme } = useUserSettings();
const { useToken } = theme;
const { token, hashId } = useToken();
console.log('token+++++++++++++++', token, hashId);
export const xAxis = {
type: 'category',
axisTick: {
show: true,
lineStyle: {
color: chartColorMap.tickLineColor
}
},
axisLabel: {
color: chartColorMap.axislabelColor,
fontSize: 12
},
axisLine: {
show: false
}
};
const chartColorMap = useMemo(() => {
return {
titleColor: token.colorText,
splitLineColor: token.colorBorder,
tickLineColor: token.colorSplit,
axislabelColor: token.colorTextTertiary,
gaugeSplitLineColor: 'rgba(255, 255, 255, 0.38)',
colorBgBase: token.colorBgBase
};
}, [userSettings.theme]);
export const yAxis = {
// max: 100,
// min: 0,
nameTextStyle: {
padding: [0, 0, 0, -20]
},
splitLine: {
show: true,
lineStyle: {
type: 'dashed'
const tooltip = {
trigger: 'axis',
backgroundColor: chartColorMap.colorBgBase,
borderColor: 'transparent',
formatter(params: any, callback?: (val: any) => any) {
let result = `<span class="tooltip-x-name">${params[0].axisValue}</span>`;
params.forEach((item: any) => {
let value = isFunction(callback)
? callback?.(item.data.value)
: item.data.value;
result += `<span class="tooltip-item">
<span class="tooltip-item-name">
<span style="display:inline-block;margin-right:5px;border-radius:8px;width:8px;height:8px;background-color:${item.color};"></span>
<span class="tooltip-title">${item.seriesName}</span>:
</span>
<span class="tooltip-value">${value}</span>
</span>`;
});
return `<div class="tooltip-wrapper">${result}</div>`;
}
},
axisLabel: {
color: chartColorMap.axislabelColor,
fontSize: 12,
formatter: formatLargeNumber
},
axisTick: {
show: false
},
type: 'value'
};
};
export const title = {
show: true,
left: 'center',
textStyle: {
fontSize: 12,
color: '#000'
// fontWeight: 500
},
text: ''
};
const legend = {
itemWidth: 8,
itemHeight: 8,
padding: 0,
textStyle: {
color: chartColorMap.axislabelColor
}
};
export const barItemConfig = {
type: 'bar',
barMaxWidth: 20,
barMinWidth: 8,
// stack: 'total',
barGap: '30%',
barCategoryGap: '50%'
};
const xAxis = {
type: 'category',
axisTick: {
show: true,
lineStyle: {
color: chartColorMap.tickLineColor
}
},
axisLabel: {
color: chartColorMap.axislabelColor,
fontSize: 12
},
axisLine: {
show: false
}
};
export const lineItemConfig = {
type: 'line',
smooth: true,
showSymbol: false,
itemStyle: {},
lineStyle: {
width: 1.5,
opacity: 0.7
}
};
const yAxis = {
// max: 100,
// min: 0,
nameTextStyle: {
padding: [0, 0, 0, -20]
},
splitLine: {
show: true,
lineStyle: {
type: 'dashed',
color: chartColorMap.splitLineColor
}
},
axisLabel: {
color: chartColorMap.axislabelColor,
fontSize: 12,
formatter: formatLargeNumber
},
axisTick: {
show: false
},
type: 'value'
};
export const gaugeItemConfig = {
type: 'gauge',
radius: '88%',
center: ['50%', '65%'],
startAngle: 190,
endAngle: -10,
min: 0,
max: 100,
splitNumber: 5,
progress: {
const title = {
show: true,
roundCap: false,
width: 12
},
pointer: {
length: '80%',
width: 4,
itemStyle: {
color: 'auto'
}
},
axisLine: {
roundCap: false,
lineStyle: {
width: 12,
// color: [[1, 'rgba(221, 221, 221, 0.5)']],
color: [
[0.5, 'rgba(84, 204, 152, 80%)'],
[0.8, 'rgba(250, 173, 20, 80%)'],
[1, 'rgba(255, 77, 79, 80%)']
]
}
},
axisTick: {
distance: -12,
length: 6,
splitNumber: 5,
lineStyle: {
width: 1.5,
color: 'rgba(255, 255, 255, 1)'
}
},
splitLine: {
distance: -12,
length: 12,
left: 'center',
textStyle: {
fontSize: 12,
color: chartColorMap.titleColor
},
text: ''
};
const barItemConfig = {
type: 'bar',
barMaxWidth: 20,
barMinWidth: 8,
// stack: 'total',
barGap: '30%',
barCategoryGap: '50%'
};
const lineItemConfig = {
type: 'line',
smooth: true,
showSymbol: false,
itemStyle: {},
lineStyle: {
width: 1.5,
color: 'rgba(255, 255, 255, 1)'
opacity: 0.7
}
},
axisLabel: {
distance: 14,
color: 'rgba(0, 0, 0, .5)',
fontSize: 12
},
detail: {
lineHeight: 40,
height: 40,
offsetCenter: [5, 30],
valueAnimation: false,
fontSize: 20,
color: 'rgba(0, 0, 0, 0.88)',
formatter(value: any) {
return '{value|' + value + '}{unit|%}';
};
const gaugeItemConfig = {
type: 'gauge',
radius: '88%',
center: ['50%', '65%'],
startAngle: 190,
endAngle: -10,
min: 0,
max: 100,
splitNumber: 5,
progress: {
show: true,
roundCap: false,
width: 12
},
pointer: {
length: '80%',
width: 4,
itemStyle: {
color: 'auto'
}
},
axisLine: {
roundCap: false,
lineStyle: {
width: 12,
color: [
[0.5, 'rgba(84, 204, 152, 80%)'],
[0.8, 'rgba(250, 173, 20, 80%)'],
[1, 'rgba(255, 77, 79, 80%)']
]
}
},
rich: {
value: {
fontSize: 16,
fontWeight: '500',
color: 'rgba(0, 0, 0, 0.88)'
axisTick: {
distance: -12,
length: 6,
splitNumber: 5,
lineStyle: {
width: 1.5,
color: chartColorMap.gaugeSplitLineColor
}
},
splitLine: {
distance: -6,
length: 6,
lineStyle: {
width: 1.5,
color: chartColorMap.gaugeSplitLineColor
}
},
axisLabel: {
distance: 14,
color: chartColorMap.axislabelColor,
fontSize: 12
},
detail: {
lineHeight: 40,
height: 40,
offsetCenter: [5, 30],
valueAnimation: false,
fontSize: 20,
color: chartColorMap.titleColor,
formatter(value: any) {
return '{value|' + value + '}{unit|%}';
},
unit: {
fontSize: 14,
color: 'rgba(0, 0, 0, 0.88)',
fontWeight: '500',
padding: [0, 0, 0, 2]
rich: {
value: {
fontSize: 16,
fontWeight: '500',
color: chartColorMap.titleColor
},
unit: {
fontSize: 14,
color: chartColorMap.titleColor,
fontWeight: '500',
padding: [0, 0, 0, 2]
}
}
}
}
};
};
return {
tooltip,
grid,
legend,
xAxis,
yAxis,
title,
chartColorMap,
barItemConfig,
lineItemConfig,
gaugeItemConfig,
isDark: isDarkTheme
};
}

@ -1,15 +1,13 @@
import Chart from '@/components/echarts/chart';
import {
gaugeItemConfig,
title as titleConfig
} from '@/components/echarts/config';
import useChartConfig from '@/components/echarts/config';
import EmptyData from '@/components/empty-data';
import { memo } from 'react';
import React, { memo } from 'react';
import { ChartProps } from './types';
const GaugeChart: React.FC<Omit<ChartProps, 'seriesData' | 'xAxisData'>> = (
props
) => {
const { gaugeItemConfig, title: titleConfig } = useChartConfig();
const { value, height, width, labelFormatter, title, color } = props;
if (!value && value !== 0) {
return <EmptyData height={height} title={title}></EmptyData>;

@ -1,15 +1,8 @@
import Chart from '@/components/echarts/chart';
import {
grid,
legend,
title as titleConfig,
tooltip,
xAxis,
yAxis
} from '@/components/echarts/config';
import useChartConfig from '@/components/echarts/config';
import EmptyData from '@/components/empty-data';
import _ from 'lodash';
import { memo, useMemo } from 'react';
import React, { memo, useMemo } from 'react';
import { ChartProps } from './types';
const BarChart: React.FC<ChartProps> = (props) => {
@ -22,6 +15,14 @@ const BarChart: React.FC<ChartProps> = (props) => {
legendData,
title
} = props;
const {
grid,
legend,
title: titleConfig,
tooltip,
xAxis,
yAxis
} = useChartConfig();
const options = {
title: {

@ -1,16 +1,8 @@
import Chart from '@/components/echarts/chart';
import {
grid,
legend,
lineItemConfig,
title as titleConfig,
tooltip,
xAxis,
yAxis
} from '@/components/echarts/config';
import useChartConfig from '@/components/echarts/config';
import EmptyData from '@/components/empty-data';
import _ from 'lodash';
import { memo, useMemo } from 'react';
import React, { memo, useMemo } from 'react';
import { ChartProps } from './types';
const LineChart: React.FC<ChartProps> = (props) => {
@ -26,6 +18,15 @@ const LineChart: React.FC<ChartProps> = (props) => {
smooth,
title
} = props;
const {
grid,
legend,
lineItemConfig,
title: titleConfig,
tooltip,
xAxis,
yAxis
} = useChartConfig();
const options = {
title: {
@ -93,7 +94,7 @@ const LineChart: React.FC<ChartProps> = (props) => {
},
series: data
};
}, [seriesData, xAxisData, yAxisName, title, smooth, legendData]);
}, [seriesData, xAxisData, yAxisName, title, smooth, legendData, options]);
return (
<>

@ -1,89 +1,106 @@
import Chart from '@/components/echarts/chart';
import { grid, title as titleConfig } from '@/components/echarts/config';
import useChartConfig from '@/components/echarts/config';
import EmptyData from '@/components/empty-data';
import _ from 'lodash';
import { memo, useCallback, useMemo, useRef } from 'react';
import React, { memo, useCallback, useMemo, useRef } from 'react';
import { ChartProps } from './types';
const options: any = {
animation: false,
grid: {
...grid,
right: 10,
top: 10,
bottom: 2,
left: 2,
containLabel: true,
borderRadius: 4
},
xAxis: {
min: -1,
max: 1,
scale: false,
slient: true,
splitNumber: 15,
splitLine: {
lineStyle: {
color: '#F2F2F2'
}
},
axisLine: {
show: true,
lineStyle: {
color: '#DCDCDC'
}
},
axisTick: {
show: false
},
axisLabel: {
show: true
},
boundaryGap: [0.05, 0.05]
},
yAxis: {
min: -1,
max: 1,
scale: false,
slient: true,
splitNumber: 10,
boundaryGap: [0.05, 0.05],
splitLine: {
lineStyle: {
color: '#F2F2F2'
}
},
axisLine: {
show: true,
lineStyle: {
color: '#DCDCDC'
}
},
axisTick: {
show: false
},
axisLabel: {
show: true
}
},
symbol: 'roundRect',
label: {
show: true,
shadowColor: 'none',
textBorderColor: 'none',
formatter: (params: any) => {
return params.name;
}
},
series: []
};
const Scatter: React.FC<ChartProps> = (props) => {
const { grid, title: titleConfig, isDark, chartColorMap } = useChartConfig();
const { seriesData, xAxisData, height, width, showEmpty, title } = props;
const chart = useRef<any>(null);
const options = useMemo(() => {
const colorMap = isDark
? {
split: chartColorMap.splitLineColor,
axis: chartColorMap.axislabelColor,
label: chartColorMap.axislabelColor
}
: {
split: '#F2F2F2',
axis: '#dcdcdc',
label: '#dcdcdc'
};
return {
animation: false,
grid: {
...grid,
right: 10,
top: 10,
bottom: 2,
left: 2,
containLabel: true,
borderRadius: 4
},
xAxis: {
min: -1,
max: 1,
scale: false,
slient: true,
splitNumber: 15,
splitLine: {
lineStyle: {
color: colorMap.split
}
},
axisLine: {
show: true,
lineStyle: {
color: colorMap.axis
}
},
axisTick: {
show: false
},
axisLabel: {
show: true,
color: colorMap.label
},
boundaryGap: [0.05, 0.05]
},
yAxis: {
min: -1,
max: 1,
scale: false,
slient: true,
splitNumber: 10,
boundaryGap: [0.05, 0.05],
splitLine: {
lineStyle: {
color: colorMap.split
}
},
axisLine: {
show: true,
lineStyle: {
color: colorMap.axis
}
},
axisTick: {
show: false
},
axisLabel: {
show: true,
color: colorMap.label
}
},
symbol: 'roundRect',
label: {
show: true,
shadowColor: 'none',
textBorderColor: 'none',
formatter: (params: any) => {
return params.name;
}
},
series: []
};
}, [isDark]);
const findOverlappingPoints = useCallback(
(data: any[], currentPoint: any) => {
const overlappingPoints = [];
@ -151,6 +168,8 @@ const Scatter: React.FC<ChartProps> = (props) => {
tooltip: {
trigger: 'item',
borderWidth: 0,
backgroundColor: chartColorMap.colorBgBase,
borderColor: 'transparent',
formatter(params: any, callback?: (val: any) => any) {
const dataList = findOverlappingPoints(seriseDataList, params.data);
let result = '';
@ -177,7 +196,7 @@ const Scatter: React.FC<ChartProps> = (props) => {
data: seriseDataList
}
};
}, [seriesData, xAxisData, title, findOverlappingPoints]);
}, [seriesData, xAxisData, title, options, findOverlappingPoints]);
return (
<>

@ -4,7 +4,7 @@ export interface ChartProps {
xAxisData: string[];
legendData?: string[];
labelFormatter?: (val?: any) => string;
tooltipValueFormatter?: (val?: any) => string;
tooltipValueFormatter?: (val: any) => string;
height: string | number;
width?: string | number;
title?: string;

@ -6,7 +6,7 @@
padding: 20px 0;
text-align: center;
font-size: var(--font-size-middle);
color: var(--color-text-2);
color: var(--ant-color-text-secondary);
.footer-content-left-text {
display: flex;

@ -2,7 +2,7 @@
display: flex;
justify-content: flex-start;
align-items: center;
color: rgba(0, 0, 0, 45%);
color: var(--ant-color-text-tertiary);
font-size: var(--font-size-base);
.note-info {

@ -72,7 +72,7 @@ const SealSlider: React.FC<SealSliderProps> = (props) => {
);
}, [label, labelWidth, description, value, max, min, step, defaultValue]);
return (
<SliderWrapper>
<SliderWrapper className="slider-wrapper">
<Wrapper
required={required}
status={checkStatus || status}

@ -34,7 +34,7 @@ const WrapperBox = styled.div`
border-style: var(--ant-line-type);
border-color: var(--ant-color-border);
border-radius: var(--border-radius-base);
background-color: var(--color-white-1);
// background-color: var(--color-white-1);
&.borderless {
border: none;
box-shadow: none;

@ -39,6 +39,7 @@ const SliderWrapper = styled.div`
.ant-input-number-input {
text-align: center !important;
background-color: var(--color-white-1);
}
}
}

@ -2,6 +2,7 @@ import { CaretDownOutlined, CaretUpOutlined } from '@ant-design/icons';
import classNames from 'classnames';
import React from 'react';
import '../styles/header.less';
import { TableHeaderProps } from '../types';
const TableHeader: React.FC<TableHeaderProps> = (props) => {

@ -1,12 +1,24 @@
import { Pagination, Spin, type PaginationProps } from 'antd';
import { Pagination, Spin, theme, type PaginationProps } from 'antd';
import _ from 'lodash';
import React, { useMemo } from 'react';
import styled from 'styled-components';
import Header from './components/header';
import HeaderPrefix from './components/header-prefix';
import TableBody from './components/table-body';
import './styles/index.less';
import { SealColumnProps, SealTableProps } from './types';
const Wrapper = styled.div<{ $token: any }>`
--ant-table-cell-padding-inline: ${(props) =>
props.$token.cellPaddingInline}px;
--ant-table-cell-padding-block: ${(props) => props.$token.cellPaddingBlock}px;
--ant-table-header-border-radius: ${(props) =>
props.$token.headerBorderRadius}px;
--ant-table-header-split-color: ${(props) => props.$token.headerSplitColor};
--ant-table-row-selected-bg: var(--ant-table-row-selected-bg);
--ant-table-row-selected-hover-bg: var(--ant-table-row-selected-hover-bg);
`;
const SealTable: React.FC<SealTableProps & { pagination: PaginationProps }> = (
props
) => {
@ -32,7 +44,7 @@ const SealTable: React.FC<SealTableProps & { pagination: PaginationProps }> = (
loadChildren,
loadChildrenAPI
} = props;
const { token } = theme.useToken();
const parsedColumns = useMemo(() => {
if (columns) return columns;
@ -122,7 +134,7 @@ const SealTable: React.FC<SealTableProps & { pagination: PaginationProps }> = (
};
return (
<>
<Wrapper $token={token.Table}>
<div className="seal-table-container">
<div className="header-row-wrapper">
<HeaderPrefix
@ -166,7 +178,7 @@ const SealTable: React.FC<SealTableProps & { pagination: PaginationProps }> = (
></Pagination>
</div>
)}
</>
</Wrapper>
);
};

@ -11,11 +11,10 @@
.header-row-wrapper {
height: 50px;
// margin-bottom: 10px;
display: flex;
justify-content: flex-start;
align-items: center;
background-color: var(--color-fill-sider);
background-color: var(--ant-color-fill-tertiary);
border-radius: var(--ant-table-header-border-radius)
var(--ant-table-header-border-radius) 0 0;
@ -29,17 +28,12 @@
}
.row-box {
// margin-bottom: 20px;
// border-radius: var(--ant-table-header-border-radius);
overflow: hidden;
border-bottom: 1px solid var(--ant-color-split);
// box-shadow: var(--box-shadow-base);
}
.expanded-row {
// background-color: var(--color-white-1);
padding: 16px;
// border: 1px solid var(--color-fill-1);
border-top: 0;
border-radius: 0 0 var(--ant-table-header-border-radius)
var(--ant-table-header-border-radius);
@ -53,7 +47,6 @@
display: flex;
justify-content: flex-start;
align-items: center;
// background-color: var(--color-fill-sider);
transition: all 0.2s ease;
&:hover {

@ -0,0 +1,89 @@
export default {
'root-entry-name': 'variable',
cssVar: true,
hashed: false,
components: {
Input: {
inputFontSize: 14,
inputFontSizeLG: 14
},
Table: {
headerBorderRadius: 4,
cellPaddingInline: 16,
cellPaddingBlock: 6,
cellFontSize: 14,
rowSelectedHoverBg: 'rgb(24 25 27)',
rowHoverBg: 'rgb(24 25 27)',
rowSelectedBg: 'transparent'
},
Button: {
contentFontSizeLG: 14,
primaryShadow: 'none',
defaultShadow: 'none',
dangerShadow: 'none'
},
Tabs: {
titleFontSizeLG: 14,
cardBg: '#1D1E20'
},
Menu: {
iconSize: 16,
iconMarginInlineEnd: 12,
itemBorderRadius: 4,
itemHeight: 44,
itemSelectedColor: '#007BFF',
darkItemSelectedBg: 'rgb(24 25 27)',
darkItemHoverBg: 'rgb(24 25 27)',
groupTitleColor: 'rgba(0,0,0,1)',
itemHoverColor: 'rgba(0,0,0,1)',
itemColor: 'rgba(0,0,0,1)',
itemHoverBg: 'rgb(24 25 27)',
itemActiveBg: 'rgb(24 25 27)'
},
Progress: {
lineBorderRadius: 2
},
Select: {
optionSelectedBg: 'rgba(230, 230, 230, 88%)',
fontSizeLG: 14
},
Message: {
contentPadding: '12px 16px'
},
Tooltip: {
colorBgSpotlight: '#1D1E20'
},
Cascader: {
dropdownHeight: 240
},
Slider: {
handleSize: 8,
handleSizeHover: 8,
trackBg: 'rgba(0,0,0,0.15)',
handleColor: 'rgba(0,0,0,0.2)',
trackHoverBg: 'rgba(0,0,0,0.25)',
handleActiveColor: 'rgba(0,0,0,0.3)',
dotActiveBorderColor: 'rgba(0,0,0,0.25)',
handleActiveOutlineColor: 'rgba(0,0,0,0.25)',
dotBorderColor: 'rgba(0,0,0,0.25)'
}
},
token: {
fontFamily:
"Helvetica Neue, -apple-system, BlinkMacSystemFont, Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'",
colorText: '#ccc',
colorPrimary: '#007BFF',
colorSuccess: '#54cc98',
borderRadius: 4,
borderRadiusSM: 2,
fontSize: 14,
motion: true,
colorFill: 'rgb(0,0,0)',
colorFillTertiary: '#1D1E20',
colorBgContainer: '#141414',
colorBgBase: '#000',
colorBorder: '#353535',
colorSplit: '#262626',
colorBorderSecondary: '#262626'
}
};

@ -0,0 +1,7 @@
import dark from './dark';
import light from './light';
export default {
light,
dark
};

@ -8,6 +8,9 @@ export default {
inputFontSizeLG: 14
},
Table: {
headerBorderRadius: 4,
cellPaddingInline: 16,
cellPaddingBlock: 6,
cellFontSize: 14,
rowSelectedHoverBg: 'rgb(249 249 249)',
rowHoverBg: 'rgb(249 249 249)',
@ -70,7 +73,9 @@ export default {
colorSuccess: '#54cc98',
borderRadius: 4,
borderRadiusSM: 2,
colorBgContainer: '#fff',
fontSize: 14,
motion: true
motion: true,
colorFillTertiary: '#f4f5f4'
}
};

@ -5,15 +5,15 @@
html {
--font-family: 'noto sans', sans-serif;
--ant-color-text-secondary: rgba(0, 0, 0, 65%);
--ant-color-text-tertiary: rgba(0, 0, 0, 45%);
--ant-color-text-quaternary: rgba(0, 0, 0, 25%);
--ant-color-fill: rgba(223, 168, 168, 15%);
--ant-color-fill-secondary: rgba(0, 0, 0, 6%);
--ant-color-fill-tertiary: rgba(0, 0, 0, 4%);
--ant-color-fill-quaternary: rgba(0, 0, 0, 2%);
// --ant-color-text-secondary: rgba(0, 0, 0, 65%);
// --ant-color-text-tertiary: rgba(0, 0, 0, 45%);
// --ant-color-text-quaternary: rgba(0, 0, 0, 25%);
// --ant-color-fill: rgba(223, 168, 168, 15%);
// --ant-color-fill-secondary: rgba(0, 0, 0, 6%);
// --ant-color-fill-tertiary: rgba(0, 0, 0, 4%);
// --ant-color-fill-quaternary: rgba(0, 0, 0, 2%);
--color-text-light-1: rgba(255, 255, 255, 90%);
--color-fill-1: var(--ant-color-fill-tertiary);
--color-fill-1: var(--ant-color-bg-container);
--color-scrollbar-thumb: rgba(193, 193, 193, 80%);
--scrollbar-size: 6px;
--scrollbar-handle-bg: rgba(0, 0, 0, 44%);
@ -22,7 +22,6 @@ html {
--color-editor-dark: #282c34;
--color-editor-light: #fafafa;
--color-scrollbar-track: var(--ant-color-fill-tertiary);
--ant-color-text: #000;
--color-bg-1: #f4f5f4;
--color-scroll-bg: #d9d9d9;
--color-fill-2: #fff;
@ -41,7 +40,7 @@ html {
--border-radius-mini: 4px;
--border-radius-2px: 2px;
--color-white-1: rgba(255, 255, 255, 100%);
--color-fill-sider: #f4f5f4;
--color-fill-sider: var(--ant-color-fill-tertiary);
--font-weight-500: 500;
--font-weight-normal: 400;
--font-weight-medium: 600;
@ -56,7 +55,6 @@ html {
--color-white-light-4: rgba(255, 255, 255, 45%);
--color-gray-fill-4: rgba(92, 92, 92, 45%);
--color-gray-fill-3: rgba(92, 92, 92, 35%);
--color-text-1: var(--ant-color-text);
--color-text-3: rgba(0, 0, 0, 45%);
--color-text-2: rgba(0, 0, 0, 65%);
--color-bg-light-1: #e6f6ff;
@ -73,20 +71,19 @@ html {
--ant-color-error: #ff4d4f;
--ant-box-shadow-secondary: 0 6px 16px 0 rgba(0, 0, 0, 8%),
0 3px 6px -4px rgba(0, 0, 0, 12%), 0 9px 28px 8px rgba(0, 0, 0, 5%);
--ant-table-cell-padding-inline: 16px;
--ant-table-cell-padding-block: 6px;
--ant-table-header-border-radius: 4px;
--ant-table-header-split-color: #f0f0f0;
--ant-table-row-selected-bg: #e6f6ff;
--ant-table-row-selected-hover-bg: rgb(249 249 249);
--ant-table-row-hover-bg: rgb(249 249 249);
--table-cell-padding-inline: var(--ant-table-cell-padding-inline);
--table-cell-padding-block: var(--ant-table-cell-padding-block);
--table-header-border-radius: var(--ant-table-header-border-radius);
--table-header-split-color: var(--ant-table-header-split-color);
--table-row-selected-bg: var(--ant-table-row-selected-bg);
--table-row-selected-hover-bg: var(--ant-table-row-selected-hover-bg);
--table-row-hover-bg: var(--ant-table-row-hover-bg);
--color-chart-red: rgba(255, 77, 79, 80%);
--color-chart-green: rgb(84, 204, 152, 80%);
--color-chart-glod: rgba(250, 173, 20, 80%);
--seal-transition-func: cubic-bezier(0, 0, 1, 1);
--color-progress-green: rgba(84, 204, 152, 100%);
--color-green-fill-light: rgb(243 251 248);
--color-border-1: rgba(217, 217, 217, 100%);
--ant-rate-star-color: #fadb14;
--color-fill-mask: rgba(255, 255, 255, 60%);
--width-tooltip-max: 300px;
@ -159,8 +156,8 @@ html {
}
}
body * {
// font-weight: var(--font-weight-normal);
html[data-theme='realDark'] {
--color-white-1: #1d1e20;
}
body {
@ -224,22 +221,12 @@ body {
border: none;
padding-block: 0;
height: 50px;
background-color: var(--color-fill-sider);
background-color: var(--ant-color-fill-tertiary);
}
tr > td {
border-bottom: none;
height: 68px;
// &:first-child {
// border-top-left-radius: var(--table-td-radius);
// border-bottom-left-radius: var(--table-td-radius);
// }
// &:last-child {
// border-top-right-radius: var(--table-td-radius);
// border-bottom-right-radius: var(--table-td-radius);
// }
}
}
@ -343,7 +330,7 @@ body {
}
.ant-pro-sider .ant-layout-sider-children {
background-color: var(--color-fill-sider);
background-color: var(--ant-color-fill-tertiary);
// box-shadow:
// 0px 1px 2px 0px rgb(0 0 0 / 30%),
// 0px 2px 6px 2px rgb(0 0 0 / 15%);
@ -363,7 +350,6 @@ body {
.ant-table-tbody {
.ant-table-row {
border-radius: var(--table-td-radius);
// background-color: var(--color-fill-sider);
> td {
background-color: unset;
@ -397,6 +383,7 @@ body {
.ant-layout {
min-height: 100vh;
background: var(--ant-color-bg-container);
}
.ant-pro-layout-bg-list {
@ -406,6 +393,7 @@ body {
.ant-pro-layout-container {
overflow-x: auto;
min-height: 100vh;
background: var(--ant-color-bg-container);
}
.ant-pro-sider {
@ -725,8 +713,6 @@ body {
}
.ant-pro-page-container {
background: transparent;
.ant-page-header-heading {
min-width: max-content;
}
@ -857,12 +843,12 @@ body {
flex-direction: column;
gap: 4px;
font-size: 11px;
background-color: rgba(255, 255, 255, 80%);
background-color: transparent;
min-width: 100px;
max-width: 360px;
.tooltip-x-name {
font-size: var(--font-size-base);
font-size: var(--font-size-small);
color: var(--ant-color-text-tertiary);
}

@ -1,3 +1,5 @@
import { userSettingsHelperAtom } from '@/atoms/settings';
import { useAtom } from 'jotai';
import { throttle } from 'lodash';
import {
UseOverlayScrollbarsParams,
@ -28,6 +30,7 @@ export default function useOverlayScroller(data?: {
events?: any;
defer?: boolean;
}) {
const [useSettings] = useAtom(userSettingsHelperAtom);
const { options, events, defer = true } = data || {};
const scrollEventElement = React.useRef<any>(null);
const instanceRef = React.useRef<any>(null);
@ -44,7 +47,10 @@ export default function useOverlayScroller(data?: {
x: 'hidden'
},
scrollbars: {
theme: options?.theme || 'os-theme-dark',
theme:
options?.theme || useSettings.theme === 'light'
? 'os-theme-dark'
: 'os-theme-light',
autoHide: 'scroll',
autoHideDelay: 600,
clickScroll: 'instant'

@ -0,0 +1,46 @@
import { userSettingsHelperAtom } from '@/atoms/settings';
import themeConfig from '@/config/theme';
import { useAtom } from 'jotai';
import { useEffect, useMemo } from 'react';
type Theme = 'light' | 'realDark';
export default function useUserSettings() {
const { light, dark } = themeConfig;
const [userSettings, setUserSettings] = useAtom(userSettingsHelperAtom);
const setHtmlThemeAttr = (theme: string) => {
const html = document.querySelector('html');
if (html) {
html.setAttribute('data-theme', theme);
}
};
const themeData = useMemo(() => {
return {
...(userSettings.theme === 'realDark' ? dark : light)
};
}, [userSettings.theme]);
const isDarkTheme = useMemo(() => {
return userSettings.theme === 'realDark';
}, [userSettings.theme]);
const setTheme = (theme: Theme) => {
setHtmlThemeAttr(theme);
setUserSettings({ ...userSettings, theme: theme });
};
useEffect(() => {
setHtmlThemeAttr(userSettings.theme);
}, [userSettings.theme]);
return {
userSettings,
setUserSettings,
setTheme,
isDarkTheme,
themeData,
componentSize: 'large'
};
}

@ -7,9 +7,9 @@ import ShortCuts, {
} from '@/components/short-cuts';
import VersionInfo, { modalConfig } from '@/components/version-info';
import routeCachekey from '@/config/route-cachekey';
import theme from '@/config/theme';
import useBodyScroll from '@/hooks/use-body-scroll';
import useOverlayScroller from '@/hooks/use-overlay-scroller';
import useUserSettings from '@/hooks/use-user-settings';
import { logout } from '@/pages/login/apis';
import { useAccessMarkedRoutes } from '@@/plugin-access';
import { useModel } from '@@/plugin-model';
@ -99,6 +99,7 @@ export default (props: any) => {
const { initialize: initialize } = useOverlayScroller({
defer: false
});
const { themeData, setTheme, userSettings } = useUserSettings();
const { saveScrollHeight, restoreScrollHeight } = useBodyScroll();
const { initialize: initializeMenu } = useOverlayScroller();
const [userInfo] = useAtom(userAtom);
@ -160,6 +161,7 @@ export default (props: any) => {
}
}
};
const runtimeConfig = {
...initialInfo,
logout: async (userInfo) => {
@ -172,6 +174,10 @@ export default (props: any) => {
showShortcuts: () => {
return showShortcuts();
},
toggleTheme: () => {
const newTheme = userSettings.theme === 'realDark' ? 'light' : 'realDark';
setTheme(newTheme);
},
notFound: <span>404 not found</span>
};
@ -288,7 +294,7 @@ export default (props: any) => {
return dom;
},
[intl, showUpgrade]
[intl, showUpgrade, userSettings.theme]
);
const itemRender = useCallback((route, _, routes) => {
@ -400,13 +406,12 @@ export default (props: any) => {
};
return (
<ConfigProvider componentSize="large" theme={theme}>
<div className="background"></div>
<ConfigProvider componentSize="large" theme={themeData}>
<ProLayout
route={route}
location={location}
title={userConfig.title}
navTheme="light"
navTheme={userSettings.theme}
layout="side"
contentStyle={{
paddingBlock: 0,

@ -10,6 +10,7 @@ import {
HomeOutlined,
InfoCircleOutlined,
LogoutOutlined,
MoonOutlined,
QuestionCircleOutlined,
ReadOutlined,
SettingOutlined
@ -250,6 +251,14 @@ export const getRightRenderContent = (opts: {
</span>
),
children: [
{
key: 'theme',
label: 'Appearance',
icon: <MoonOutlined />,
onClick: () => {
opts.runtimeConfig.toggleTheme();
}
},
{
key: 'settings',
label: (

@ -6,7 +6,7 @@
display: flex;
justify-content: space-around;
border-radius: var(--ant-border-radius-lg);
border: 1px solid var(--color-border-1);
border: 1px solid var(--ant-color-border);
}
}

@ -16,7 +16,7 @@ const renderCardItem = (data: {
return (
<Card
bordered={false}
style={{ background: bgColor }}
style={{ background: 'var(--color-white-1)' }}
className={styles['card-body']}
>
<div className={styles.content}>

@ -1,6 +1,8 @@
import { userAtom } from '@/atoms/user';
import Footer from '@/components/footer';
import useUserSettings from '@/hooks/use-user-settings';
import { useModel } from '@umijs/max';
import { ConfigProvider } from 'antd';
import { useAtom } from 'jotai';
import { useEffect } from 'react';
import LoginForm from './components/login-form';
@ -9,6 +11,7 @@ import styles from './components/styles.less';
import { checkDefaultPage } from './utils';
const Login = () => {
const { themeData } = useUserSettings();
const [userInfo, setUserInfo] = useAtom(userAtom);
const { initialState, setInitialState } = useModel('@@initialState') || {};
@ -33,7 +36,7 @@ const Login = () => {
}, []);
return (
<>
<ConfigProvider componentSize="large" theme={themeData}>
<div className="login-wrapper"></div>
<div className={styles.box}>
<div className={styles['login-form-wrapper']}>
@ -41,7 +44,7 @@ const Login = () => {
</div>
<Footer />
</div>
</>
</ConfigProvider>
);
};

@ -48,8 +48,6 @@ interface MessageProps {
const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
const { modelList } = props;
const acceptType =
'.txt, .doc, .docx, .xls, .xlsx, .csv, .md, .pdf, .eml, .msg, .ppt, .pptx, .xml, .epub, .html';
const messageId = useRef<number>(0);
const intl = useIntl();
@ -266,15 +264,6 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
setShow(false);
};
const handleUpdateFileList = (
files: { text: string; name: string; uid: number | string }[]
) => {
console.log('files:', files);
setFileList((preList) => {
return [...preList, ...files];
});
};
const handleScaleOutputSize = (
e: any,
direction: string,
@ -445,18 +434,6 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
[]
);
// useHotkeys(
// HotKeys.SUBMIT,
// (e: any) => {
// e.preventDefault();
// handleSendMessage();
// },
// {
// enabled: !loading,
// preventDefault: true
// }
// );
useEffect(() => {
if (scroller.current) {
initialize(scroller.current);

@ -10,11 +10,11 @@
justify-content: space-between;
padding: 0;
padding-right: 6px;
overflow: hidden;
cursor: pointer;
transition: background-color 0.3s ease;
border-radius: var(--border-radius-base);
border: 1px solid var(--ant-color-border);
background-color: #fff;
.btn-group {
display: none;

@ -14,7 +14,6 @@
padding-top: 16px;
position: sticky;
top: 0;
background: var(--color-white-1);
z-index: 100;
align-items: center;
}

@ -6,7 +6,7 @@
display: flex;
justify-content: space-around;
border-radius: var(--ant-border-radius-lg);
border: 1px solid var(--color-border-1);
border: 1px solid var(--ant-color-border);
}
}

Loading…
Cancel
Save