109 changed files with 881 additions and 2883 deletions
@ -0,0 +1,35 @@ |
|||
import { generateAntColors, primaryColor } from '../config/themeConfig'; |
|||
import { getThemeVariables } from 'ant-design-vue/dist/theme'; |
|||
import { resolve } from 'path'; |
|||
|
|||
/** |
|||
* less global variable |
|||
*/ |
|||
export function generateModifyVars(dark = false) { |
|||
const palettes = generateAntColors(primaryColor); |
|||
const primary = palettes[5]; |
|||
|
|||
const primaryColorObj: Record<string, string> = {}; |
|||
|
|||
for (let index = 0; index < 10; index++) { |
|||
primaryColorObj[`primary-${index + 1}`] = palettes[index]; |
|||
} |
|||
|
|||
const modifyVars = getThemeVariables({ dark }); |
|||
return { |
|||
...modifyVars, |
|||
// Used for global import to avoid the need to import each style file separately
|
|||
// reference: Avoid repeated references
|
|||
hack: `${modifyVars.hack} @import (reference) "${resolve('src/design/config.less')}";`, |
|||
'primary-color': primary, |
|||
...primaryColorObj, |
|||
'info-color': primary, |
|||
'processing-color': primary, |
|||
'success-color': '#55D187', // Success color
|
|||
'error-color': '#ED6F6F', // False color
|
|||
'warning-color': '#EFBD47', // Warning color
|
|||
'font-size-base': '14px', // Main font size
|
|||
'border-radius-base': '2px', // Component/float fillet
|
|||
'link-color': primary, // Link color
|
|||
}; |
|||
} |
|||
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
@ -0,0 +1,111 @@ |
|||
<template> |
|||
<div |
|||
v-if="getShowDarkModeToggle" |
|||
:class="[ |
|||
prefixCls, |
|||
`${prefixCls}--${size}`, |
|||
{ |
|||
[`${prefixCls}--dark`]: isDark, |
|||
}, |
|||
]" |
|||
@click="toggleDarkMode" |
|||
> |
|||
<div :class="`${prefixCls}-inner`"> </div> |
|||
<SvgIcon size="14" name="sun" /> |
|||
<SvgIcon size="14" name="moon" /> |
|||
</div> |
|||
</template> |
|||
<script lang="ts"> |
|||
import { defineComponent, computed } from 'vue'; |
|||
|
|||
import { useDesign } from '/@/hooks/web/useDesign'; |
|||
|
|||
import { SvgIcon } from '/@/components/Icon'; |
|||
import { useRootSetting } from '/@/hooks/setting/useRootSetting'; |
|||
import { updateHeaderBgColor, updateSidebarBgColor } from '/@/logics/theme/updateBackground'; |
|||
import { updateDarkTheme } from '/@/logics/theme/dark'; |
|||
|
|||
import { ThemeEnum } from '/@/enums/appEnum'; |
|||
|
|||
export default defineComponent({ |
|||
name: 'DarkModeToggle', |
|||
components: { SvgIcon }, |
|||
props: { |
|||
size: { |
|||
type: String, |
|||
default: 'default', |
|||
validate: (val) => ['default', 'large'].includes(val), |
|||
}, |
|||
}, |
|||
setup() { |
|||
const { prefixCls } = useDesign('dark-mode-toggle'); |
|||
const { getDarkMode, setDarkMode, getShowDarkModeToggle } = useRootSetting(); |
|||
const isDark = computed(() => getDarkMode.value === ThemeEnum.DARK); |
|||
function toggleDarkMode() { |
|||
const darkMode = getDarkMode.value === ThemeEnum.DARK ? ThemeEnum.LIGHT : ThemeEnum.DARK; |
|||
setDarkMode(darkMode); |
|||
updateDarkTheme(darkMode); |
|||
updateHeaderBgColor(); |
|||
updateSidebarBgColor(); |
|||
} |
|||
|
|||
return { |
|||
isDark, |
|||
prefixCls, |
|||
toggleDarkMode, |
|||
getShowDarkModeToggle, |
|||
}; |
|||
}, |
|||
}); |
|||
</script> |
|||
<style lang="less" scoped> |
|||
@prefix-cls: ~'@{namespace}-dark-mode-toggle'; |
|||
|
|||
html[data-theme='dark'] { |
|||
.@{prefix-cls} { |
|||
border: 1px solid rgb(196, 188, 188); |
|||
} |
|||
} |
|||
|
|||
.@{prefix-cls} { |
|||
position: relative; |
|||
display: flex; |
|||
width: 50px; |
|||
height: 26px; |
|||
padding: 0 6px; |
|||
margin-left: auto; |
|||
cursor: pointer; |
|||
background-color: #151515; |
|||
border-radius: 30px; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
|
|||
&-inner { |
|||
position: absolute; |
|||
z-index: 1; |
|||
width: 18px; |
|||
height: 18px; |
|||
background-color: #fff; |
|||
border-radius: 50%; |
|||
transition: transform 0.5s, background-color 0.5s; |
|||
will-change: transform; |
|||
} |
|||
|
|||
&--dark { |
|||
.@{prefix-cls}-inner { |
|||
transform: translateX(calc(100% + 2px)); |
|||
} |
|||
} |
|||
|
|||
&--large { |
|||
width: 72px; |
|||
height: 34px; |
|||
padding: 0 10px; |
|||
|
|||
.@{prefix-cls}-inner { |
|||
width: 26px; |
|||
height: 26px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,31 @@ |
|||
.bg-white { |
|||
background: @component-background !important; |
|||
} |
|||
|
|||
html[data-theme='light'] { |
|||
.text-secondary { |
|||
color: rgba(0, 0, 0, 0.45); |
|||
} |
|||
} |
|||
|
|||
html[data-theme='dark'] { |
|||
.text-secondary { |
|||
color: #8b949e; |
|||
} |
|||
|
|||
.ant-card-grid-hoverable:hover { |
|||
box-shadow: 0 3px 6px -4px rgb(0 0 0 / 48%), 0 6px 16px 0 rgb(0 0 0 / 32%), |
|||
0 9px 28px 8px rgb(0 0 0 / 20%); |
|||
} |
|||
|
|||
.ant-alert-message, |
|||
.ant-alert-with-description .ant-alert-message, |
|||
.ant-alert-description { |
|||
color: rgba(0, 0, 0, 0.85); |
|||
} |
|||
|
|||
.ant-checkbox-checked .ant-checkbox-inner::after { |
|||
border-top: 0; |
|||
border-left: 0; |
|||
} |
|||
} |
|||
@ -1,57 +0,0 @@ |
|||
import { useTimeoutFn } from '/@/hooks/core/useTimeout'; |
|||
import { unref, Ref, nextTick } from 'vue'; |
|||
import { tryOnUnmounted } from '@vueuse/core'; |
|||
|
|||
interface CallBackFn { |
|||
(instance: Nullable<ApexCharts>): void; |
|||
} |
|||
|
|||
export function useApexCharts(elRef: Ref<HTMLDivElement>) { |
|||
let chartInstance: Nullable<ApexCharts> = null; |
|||
|
|||
function setOptions(options: any, callback?: CallBackFn) { |
|||
nextTick(() => { |
|||
useTimeoutFn(async () => { |
|||
const el = unref(elRef); |
|||
|
|||
if (!el || !unref(el)) return; |
|||
const ApexCharts = await (await import('apexcharts')).default; |
|||
chartInstance = new ApexCharts(el, options); |
|||
|
|||
chartInstance && chartInstance.render(); |
|||
|
|||
// The callback method is added to setOptions to return the chartInstance to facilitate the re-operation of the chart, such as calling the updateOptions method to update the chart
|
|||
callback && callback(chartInstance); |
|||
}, 30); |
|||
}); |
|||
} |
|||
|
|||
// Call the updateOptions method of ApexCharts to update the chart
|
|||
function updateOptions( |
|||
chartInstance: Nullable<ApexCharts>, |
|||
options: any, |
|||
redraw = false, |
|||
animate = true, |
|||
updateSyncedCharts = true, |
|||
callback: CallBackFn |
|||
) { |
|||
nextTick(() => { |
|||
useTimeoutFn(() => { |
|||
chartInstance && chartInstance.updateOptions(options, redraw, animate, updateSyncedCharts); |
|||
|
|||
callback && callback(chartInstance); |
|||
}, 30); |
|||
}); |
|||
} |
|||
|
|||
tryOnUnmounted(() => { |
|||
if (!chartInstance) return; |
|||
chartInstance?.destroy?.(); |
|||
chartInstance = null; |
|||
}); |
|||
|
|||
return { |
|||
setOptions, |
|||
updateOptions, |
|||
}; |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
import { darkCssIsReady, loadDarkThemeCss } from 'vite-plugin-theme/es/client'; |
|||
|
|||
export async function updateDarkTheme(mode: string | null = 'light') { |
|||
const htmlRoot = document.getElementById('htmlRoot'); |
|||
if (mode === 'dark') { |
|||
if (import.meta.env.PROD && !darkCssIsReady) { |
|||
await loadDarkThemeCss(); |
|||
} |
|||
htmlRoot?.setAttribute('data-theme', 'dark'); |
|||
} else { |
|||
htmlRoot?.setAttribute('data-theme', 'light'); |
|||
} |
|||
} |
|||
@ -1,58 +0,0 @@ |
|||
<template> |
|||
<div ref="chartRef" :style="{ width: '100%' }"></div> |
|||
</template> |
|||
<script lang="ts"> |
|||
import { defineComponent, ref, Ref, onMounted } from 'vue'; |
|||
|
|||
import { useApexCharts } from '/@/hooks/web/useApexCharts'; |
|||
|
|||
export default defineComponent({ |
|||
setup() { |
|||
const chartRef = ref<HTMLDivElement | null>(null); |
|||
const { setOptions } = useApexCharts(chartRef as Ref<HTMLDivElement>); |
|||
|
|||
onMounted(() => { |
|||
setOptions({ |
|||
series: [ |
|||
{ |
|||
name: 'series1', |
|||
data: [31, 40, 28, 51, 42, 109, 100], |
|||
}, |
|||
{ |
|||
name: 'series2', |
|||
data: [11, 32, 45, 32, 34, 52, 41], |
|||
}, |
|||
], |
|||
chart: { |
|||
height: 350, |
|||
type: 'area', |
|||
}, |
|||
dataLabels: { |
|||
enabled: false, |
|||
}, |
|||
stroke: { |
|||
curve: 'smooth', |
|||
}, |
|||
xaxis: { |
|||
type: 'datetime', |
|||
categories: [ |
|||
'2018-09-19T00:00:00.000Z', |
|||
'2018-09-19T01:30:00.000Z', |
|||
'2018-09-19T02:30:00.000Z', |
|||
'2018-09-19T03:30:00.000Z', |
|||
'2018-09-19T04:30:00.000Z', |
|||
'2018-09-19T05:30:00.000Z', |
|||
'2018-09-19T06:30:00.000Z', |
|||
], |
|||
}, |
|||
tooltip: { |
|||
x: { |
|||
format: 'dd/MM/yy HH:mm', |
|||
}, |
|||
}, |
|||
}); |
|||
}); |
|||
return { chartRef }; |
|||
}, |
|||
}); |
|||
</script> |
|||
@ -1,52 +0,0 @@ |
|||
<template> |
|||
<div ref="chartRef" :style="{ width: '100%' }"></div> |
|||
</template> |
|||
<script lang="ts"> |
|||
import { defineComponent, ref, Ref, onMounted } from 'vue'; |
|||
|
|||
import { useApexCharts } from '/@/hooks/web/useApexCharts'; |
|||
|
|||
export default defineComponent({ |
|||
setup() { |
|||
const chartRef = ref<HTMLDivElement | null>(null); |
|||
const { setOptions } = useApexCharts(chartRef as Ref<HTMLDivElement>); |
|||
|
|||
onMounted(() => { |
|||
setOptions({ |
|||
series: [ |
|||
{ |
|||
data: [400, 430, 448, 470, 540, 580, 690, 1100, 1200, 1380], |
|||
}, |
|||
], |
|||
chart: { |
|||
type: 'bar', |
|||
height: 350, |
|||
}, |
|||
plotOptions: { |
|||
bar: { |
|||
horizontal: true, |
|||
}, |
|||
}, |
|||
dataLabels: { |
|||
enabled: false, |
|||
}, |
|||
xaxis: { |
|||
categories: [ |
|||
'South Korea', |
|||
'Canada', |
|||
'United Kingdom', |
|||
'Netherlands', |
|||
'Italy', |
|||
'France', |
|||
'Japan', |
|||
'United States', |
|||
'China', |
|||
'Germany', |
|||
], |
|||
}, |
|||
}); |
|||
}); |
|||
return { chartRef }; |
|||
}, |
|||
}); |
|||
</script> |
|||
@ -1,53 +0,0 @@ |
|||
<template> |
|||
<div ref="chartRef" :style="{ width: '100%' }"></div> |
|||
</template> |
|||
<script lang="ts"> |
|||
import { defineComponent, ref, Ref, onMounted } from 'vue'; |
|||
|
|||
import { useApexCharts } from '/@/hooks/web/useApexCharts'; |
|||
|
|||
export default defineComponent({ |
|||
setup() { |
|||
const chartRef = ref<HTMLDivElement | null>(null); |
|||
const { setOptions } = useApexCharts(chartRef as Ref<HTMLDivElement>); |
|||
|
|||
onMounted(() => { |
|||
setOptions({ |
|||
series: [ |
|||
{ |
|||
name: 'Desktops', |
|||
data: [10, 41, 35, 51, 49, 62, 69, 91, 148], |
|||
}, |
|||
], |
|||
chart: { |
|||
height: 350, |
|||
type: 'line', |
|||
zoom: { |
|||
enabled: false, |
|||
}, |
|||
}, |
|||
dataLabels: { |
|||
enabled: false, |
|||
}, |
|||
stroke: { |
|||
curve: 'straight', |
|||
}, |
|||
title: { |
|||
text: 'Product Trends by Month', |
|||
align: 'left', |
|||
}, |
|||
grid: { |
|||
row: { |
|||
colors: ['#f3f3f3', 'transparent'], // takes an array which will be repeated on columns |
|||
opacity: 0.5, |
|||
}, |
|||
}, |
|||
xaxis: { |
|||
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep'], |
|||
}, |
|||
}); |
|||
}); |
|||
return { chartRef }; |
|||
}, |
|||
}); |
|||
</script> |
|||
@ -1,138 +0,0 @@ |
|||
<template> |
|||
<div ref="chartRef" :style="{ width: '100%' }"></div> |
|||
</template> |
|||
<script lang="ts"> |
|||
import { defineComponent, ref, Ref, onMounted } from 'vue'; |
|||
|
|||
import { useApexCharts } from '/@/hooks/web/useApexCharts'; |
|||
|
|||
export default defineComponent({ |
|||
setup() { |
|||
const chartRef = ref<HTMLDivElement | null>(null); |
|||
const { setOptions } = useApexCharts(chartRef as Ref<HTMLDivElement>); |
|||
|
|||
onMounted(() => { |
|||
setOptions({ |
|||
series: [ |
|||
{ |
|||
name: 'Income', |
|||
type: 'column', |
|||
data: [1.4, 2, 2.5, 1.5, 2.5, 2.8, 3.8, 4.6], |
|||
}, |
|||
{ |
|||
name: 'Cashflow', |
|||
type: 'column', |
|||
data: [1.1, 3, 3.1, 4, 4.1, 4.9, 6.5, 8.5], |
|||
}, |
|||
{ |
|||
name: 'Revenue', |
|||
type: 'line', |
|||
data: [20, 29, 37, 36, 44, 45, 50, 58], |
|||
}, |
|||
], |
|||
chart: { |
|||
height: 350, |
|||
type: 'line', |
|||
stacked: false, |
|||
}, |
|||
dataLabels: { |
|||
enabled: false, |
|||
}, |
|||
stroke: { |
|||
width: [1, 1, 4], |
|||
}, |
|||
title: { |
|||
text: 'XYZ - Stock Analysis (2009 - 2016)', |
|||
align: 'left', |
|||
offsetX: 110, |
|||
}, |
|||
xaxis: { |
|||
categories: [2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016], |
|||
}, |
|||
yaxis: [ |
|||
{ |
|||
axisTicks: { |
|||
show: true, |
|||
}, |
|||
axisBorder: { |
|||
show: true, |
|||
color: '#008FFB', |
|||
}, |
|||
labels: { |
|||
style: { |
|||
colors: '#008FFB', |
|||
}, |
|||
}, |
|||
title: { |
|||
text: 'Income (thousand crores)', |
|||
style: { |
|||
color: '#008FFB', |
|||
}, |
|||
}, |
|||
tooltip: { |
|||
enabled: true, |
|||
}, |
|||
}, |
|||
{ |
|||
seriesName: 'Income', |
|||
opposite: true, |
|||
axisTicks: { |
|||
show: true, |
|||
}, |
|||
axisBorder: { |
|||
show: true, |
|||
color: '#00E396', |
|||
}, |
|||
labels: { |
|||
style: { |
|||
colors: '#00E396', |
|||
}, |
|||
}, |
|||
title: { |
|||
text: 'Operating Cashflow (thousand crores)', |
|||
style: { |
|||
color: '#00E396', |
|||
}, |
|||
}, |
|||
}, |
|||
{ |
|||
seriesName: 'Revenue', |
|||
opposite: true, |
|||
axisTicks: { |
|||
show: true, |
|||
}, |
|||
axisBorder: { |
|||
show: true, |
|||
color: '#FEB019', |
|||
}, |
|||
labels: { |
|||
style: { |
|||
colors: '#FEB019', |
|||
}, |
|||
}, |
|||
title: { |
|||
text: 'Revenue (thousand crores)', |
|||
style: { |
|||
color: '#FEB019', |
|||
}, |
|||
}, |
|||
}, |
|||
], |
|||
tooltip: { |
|||
fixed: { |
|||
enabled: true, |
|||
position: 'topLeft', // topRight, topLeft, bottomRight, bottomLeft |
|||
offsetY: 30, |
|||
offsetX: 60, |
|||
}, |
|||
}, |
|||
legend: { |
|||
horizontalAlign: 'left', |
|||
offsetX: 40, |
|||
}, |
|||
}); |
|||
}); |
|||
return { chartRef }; |
|||
}, |
|||
}); |
|||
</script> |
|||
@ -1,61 +0,0 @@ |
|||
<template> |
|||
<div ref="chartRef" :style="{ width: '100%' }"></div> |
|||
</template> |
|||
<script lang="ts"> |
|||
import { defineComponent, Ref, ref, onMounted } from 'vue'; |
|||
|
|||
import { useApexCharts } from '/@/hooks/web/useApexCharts'; |
|||
|
|||
export default defineComponent({ |
|||
setup() { |
|||
const chartRef = ref<HTMLDivElement | null>(null); |
|||
const { setOptions } = useApexCharts(chartRef as Ref<HTMLDivElement>); |
|||
onMounted(() => { |
|||
setOptions({ |
|||
series: [ |
|||
{ name: 'Visits', data: [90, 50, 86, 40, 100, 20] }, |
|||
{ name: 'Sales', data: [70, 75, 70, 76, 20, 85] }, |
|||
], |
|||
chart: { |
|||
height: 350, |
|||
type: 'radar', |
|||
toolbar: { |
|||
show: false, |
|||
}, |
|||
}, |
|||
yaxis: { |
|||
show: false, |
|||
}, |
|||
|
|||
title: { |
|||
show: false, |
|||
}, |
|||
markers: { |
|||
// size: 0, |
|||
}, |
|||
xaxis: { |
|||
categories: ['2016', '2017', '2018', '2019', '2020', '2021'], |
|||
}, |
|||
stroke: { |
|||
width: 0, |
|||
}, |
|||
colors: ['#9f8ed7', '#1edec5'], |
|||
|
|||
fill: { |
|||
type: 'gradient', |
|||
gradient: { |
|||
shade: 'dark', |
|||
gradientToColors: ['#8e9ad6', '#1fcadb'], |
|||
shadeIntensity: 1, |
|||
type: 'horizontal', |
|||
opacityFrom: 1, |
|||
opacityTo: 1, |
|||
stops: [0, 100, 100, 100], |
|||
}, |
|||
}, |
|||
}); |
|||
}); |
|||
return { chartRef }; |
|||
}, |
|||
}); |
|||
</script> |
|||
@ -1,46 +0,0 @@ |
|||
<template> |
|||
<div class="apex-demo p-4"> |
|||
<div class="demo-box"> |
|||
<Line /> |
|||
</div> |
|||
<div class="demo-box"> |
|||
<Bar /> |
|||
</div> |
|||
<div class="demo-box"> |
|||
<Area /> |
|||
</div> |
|||
<div class="demo-box"> |
|||
<Mixed /> |
|||
</div> |
|||
<div class="demo-box"> |
|||
<SaleRadar /> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script> |
|||
import { defineComponent } from 'vue'; |
|||
|
|||
import Line from './Line.vue'; |
|||
import Bar from './Bar.vue'; |
|||
import Area from './Area.vue'; |
|||
import Mixed from './Mixed.vue'; |
|||
import SaleRadar from './SaleRadar.vue'; |
|||
export default defineComponent({ |
|||
components: { Line, Bar, Area, Mixed, SaleRadar }, |
|||
setup() {}, |
|||
}); |
|||
</script> |
|||
<style lang="less" scoped> |
|||
.apex-demo { |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
justify-content: space-between; |
|||
|
|||
.demo-box { |
|||
width: 49%; |
|||
margin-bottom: 20px; |
|||
background: #fff; |
|||
border-radius: 10px; |
|||
} |
|||
} |
|||
</style> |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue