v1.8.1 - hotfix - move theme settings from HTML root to Gantt Component root.

This commit is contained in:
LINING-PC\lining
2026-02-05 16:24:31 +08:00
parent 90f0f5bc60
commit e1d0180c92
22 changed files with 340 additions and 306 deletions

1
.gitignore vendored
View File

@@ -37,3 +37,4 @@ ehthumbs.db
Desktop.ini Desktop.ini
yarn.lock yarn.lock
.ai/

View File

@@ -1864,7 +1864,6 @@ const handleCustomMenuAction = (action: string, task: Task) => {
:tasks="tasks" :tasks="tasks"
:milestones="milestones" :milestones="milestones"
:locale="controlMode === 'props' ? propsLocale : undefined" :locale="controlMode === 'props' ? propsLocale : undefined"
:theme="controlMode === 'props' ? propsTheme : undefined"
:time-scale="controlMode === 'props' ? propsTimeScale : undefined" :time-scale="controlMode === 'props' ? propsTimeScale : undefined"
:fullscreen="controlMode === 'props' ? propsFullscreen : undefined" :fullscreen="controlMode === 'props' ? propsFullscreen : undefined"
:expand-all="controlMode === 'props' ? propsExpandAll : undefined" :expand-all="controlMode === 'props' ? propsExpandAll : undefined"

View File

@@ -492,5 +492,19 @@
"🎉 Optimized: The assignee and avatar properties of the Task object now accept arrays to mark multiple assignees", "🎉 Optimized: The assignee and avatar properties of the Task object now accept arrays to mark multiple assignees",
"<span style=\"font-weight: bold; color: #f00;\">Special thanks to yunlbs/fhjfhj/jakepan@gitee for their use and suggestions</span>" "<span style=\"font-weight: bold; color: #f00;\">Special thanks to yunlbs/fhjfhj/jakepan@gitee for their use and suggestions</span>"
] ]
},
{
"version": "1.8.1",
"date": "2026-02-05",
"notes": [
"🎉 优化重构组件Theme作用域从全局调整至局部.gantt-root",
"🎉 优化重构组件Theme自动跟随系统设置",
"🎉 优化重构组件完美支持Nuxt3、TailwindCSS等框架",
"<span style=\"font-weight: bold; color: #f00;\">特别感谢andrijor@gmail.com的专业反馈</span>",
"🎉 Optimized: Refactored components, Theme scope adjusted from global to local .gantt-root",
"🎉 Optimized: Refactored components, Theme automatically follows system settings",
"🎉 Optimized: Refactored components, Perfectly supports Nuxt3, TailwindCSS and other frameworks",
"<span style=\"font-weight: bold; color: #f00;\">Special thanks to andrijor@gmail.com for their professional feedback</span>"
]
} }
] ]

View File

@@ -1,6 +1,6 @@
{ {
"name": "jordium-gantt-vue3", "name": "jordium-gantt-vue3",
"version": "1.8.0", "version": "1.8.1",
"type": "module", "type": "module",
"main": "npm-package/dist/jordium-gantt-vue3.cjs.js", "main": "npm-package/dist/jordium-gantt-vue3.cjs.js",
"module": "npm-package/dist/jordium-gantt-vue3.es.js", "module": "npm-package/dist/jordium-gantt-vue3.es.js",

View File

@@ -1,4 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch, computed } from 'vue' import { ref, watch, computed } from 'vue'
import { useI18n } from '../composables/useI18n' import { useI18n } from '../composables/useI18n'
const props = defineProps({ const props = defineProps({
@@ -78,7 +78,7 @@ const messageTaskName = computed(() => {
gap: 16px; gap: 16px;
} }
:global(html[data-theme='dark']) .confirm-timer-dialog { :global(.gantt-root[data-theme='dark']) .confirm-timer-dialog {
background: var(--gantt-bg-primary, #6b6b6b); background: var(--gantt-bg-primary, #6b6b6b);
} }
.dialog-message { .dialog-message {

View File

@@ -1,4 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue' import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue'
import { useI18n } from '../composables/useI18n' import { useI18n } from '../composables/useI18n'
@@ -1519,48 +1519,48 @@ const timePickerStyle = computed(() => {
} }
/* 暗黑模式适配 */ /* 暗黑模式适配 */
:global(html[data-theme='dark']) .el-input__wrapper { :global(.gantt-root[data-theme='dark']) .el-input__wrapper {
background-color: var(--gantt-bg-secondary, #2c2c2c); background-color: var(--gantt-bg-secondary, #2c2c2c);
box-shadow: 0 0 0 1px var(--gantt-border-dark, #414243) inset; box-shadow: 0 0 0 1px var(--gantt-border-dark, #414243) inset;
} }
:global(html[data-theme='dark']) .el-input__inner, :global(.gantt-root[data-theme='dark']) .el-input__inner,
:global(html[data-theme='dark']) .el-range-input__start, :global(.gantt-root[data-theme='dark']) .el-range-input__start,
:global(html[data-theme='dark']) .el-range-input__end, :global(.gantt-root[data-theme='dark']) .el-range-input__end,
:global(html[data-theme='dark']) .el-range-separator { :global(.gantt-root[data-theme='dark']) .el-range-separator {
color: var(--gantt-text-white, #ffffff); color: var(--gantt-text-white, #ffffff);
} }
:global(html[data-theme='dark']) .el-input__inner-input::placeholder, :global(.gantt-root[data-theme='dark']) .el-input__inner-input::placeholder,
:global(html[data-theme='dark']) .el-range-input__start::placeholder, :global(.gantt-root[data-theme='dark']) .el-range-input__start::placeholder,
:global(html[data-theme='dark']) .el-range-input__end::placeholder { :global(.gantt-root[data-theme='dark']) .el-range-input__end::placeholder {
color: var(--gantt-text-muted, #9e9e9e); color: var(--gantt-text-muted, #9e9e9e);
} }
:global(html[data-theme='dark']) .el-date-picker.is-focused .el-input__wrapper { :global(.gantt-root[data-theme='dark']) .el-date-picker.is-focused .el-input__wrapper {
box-shadow: 0 0 0 1px var(--gantt-primary, #409eff) inset; box-shadow: 0 0 0 1px var(--gantt-primary, #409eff) inset;
} }
:global(html[data-theme='dark']) .el-date-picker:hover .el-input__wrapper { :global(.gantt-root[data-theme='dark']) .el-date-picker:hover .el-input__wrapper {
box-shadow: 0 0 0 1px var(--gantt-border-hover, #606266) inset; box-shadow: 0 0 0 1px var(--gantt-border-hover, #606266) inset;
} }
:global(html[data-theme='dark']) .el-date-picker.is-focused:hover .el-input__wrapper { :global(.gantt-root[data-theme='dark']) .el-date-picker.is-focused:hover .el-input__wrapper {
box-shadow: 0 0 0 1px var(--gantt-primary, #409eff) inset; box-shadow: 0 0 0 1px var(--gantt-primary, #409eff) inset;
} }
:global(html[data-theme='dark']) .el-date-picker.is-disabled .el-input__wrapper { :global(.gantt-root[data-theme='dark']) .el-date-picker.is-disabled .el-input__wrapper {
background-color: var(--gantt-bg-disabled, #3c3e40); background-color: var(--gantt-bg-disabled, #3c3e40);
box-shadow: 0 0 0 1px var(--gantt-border-disabled, #4c4d4f) inset; box-shadow: 0 0 0 1px var(--gantt-border-disabled, #4c4d4f) inset;
} }
:global(html[data-theme='dark']) .el-date-picker.is-disabled .el-input__inner, :global(.gantt-root[data-theme='dark']) .el-date-picker.is-disabled .el-input__inner,
:global(html[data-theme='dark']) .el-date-picker.is-disabled .el-range-input__start, :global(.gantt-root[data-theme='dark']) .el-date-picker.is-disabled .el-range-input__start,
:global(html[data-theme='dark']) .el-date-picker.is-disabled .el-range-input__end { :global(.gantt-root[data-theme='dark']) .el-date-picker.is-disabled .el-range-input__end {
color: var(--gantt-text-disabled, #73767a); color: var(--gantt-text-disabled, #73767a);
} }
:global(html[data-theme='dark']) .el-input__clear:hover { :global(.gantt-root[data-theme='dark']) .el-input__clear:hover {
color: var(--gantt-text-secondary, #909399); color: var(--gantt-text-secondary, #909399);
} }
@@ -1894,51 +1894,51 @@ const timePickerStyle = computed(() => {
} }
/* 暗黑模式下的日期选择器面板 */ /* 暗黑模式下的日期选择器面板 */
:global(html[data-theme='dark']) .el-picker-panel { :global(.gantt-root[data-theme='dark']) .el-picker-panel {
background: var(--gantt-bg-secondary, #2c2c2c); background: var(--gantt-bg-secondary, #2c2c2c);
border-color: var(--gantt-border-dark, #414243); border-color: var(--gantt-border-dark, #414243);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
} }
:global(html[data-theme='dark']) .el-date-picker__header { :global(.gantt-root[data-theme='dark']) .el-date-picker__header {
border-bottom-color: var(--gantt-border-dark, #414243); border-bottom-color: var(--gantt-border-dark, #414243);
} }
:global(html[data-theme='dark']) .el-date-picker__header-label { :global(.gantt-root[data-theme='dark']) .el-date-picker__header-label {
color: var(--gantt-text-white, #ffffff); color: var(--gantt-text-white, #ffffff);
} }
:global(html[data-theme='dark']) .el-picker-panel__icon-btn { :global(.gantt-root[data-theme='dark']) .el-picker-panel__icon-btn {
color: var(--gantt-text-secondary, #909399); color: var(--gantt-text-secondary, #909399);
} }
:global(html[data-theme='dark']) .el-picker-panel__icon-btn:hover { :global(.gantt-root[data-theme='dark']) .el-picker-panel__icon-btn:hover {
background: var(--gantt-bg-hover-dark, #3c3e40); background: var(--gantt-bg-hover-dark, #3c3e40);
color: var(--gantt-text-white, #ffffff); color: var(--gantt-text-white, #ffffff);
} }
:global(html[data-theme='dark']) .el-date-table__header-cell { :global(.gantt-root[data-theme='dark']) .el-date-table__header-cell {
color: var(--gantt-text-secondary, #909399); color: var(--gantt-text-secondary, #909399);
} }
:global(html[data-theme='dark']) .el-date-table__cell:hover { :global(.gantt-root[data-theme='dark']) .el-date-table__cell:hover {
background: var(--gantt-bg-hover-dark, #3c3e40); background: var(--gantt-bg-hover-dark, #3c3e40);
} }
:global(html[data-theme='dark']) .el-date-table__cell-inner { :global(.gantt-root[data-theme='dark']) .el-date-table__cell-inner {
color: var(--gantt-text-white, #ffffff); color: var(--gantt-text-white, #ffffff);
} }
:global(html[data-theme='dark']) .el-date-table__cell.is-other-month .el-date-table__cell-inner { :global(.gantt-root[data-theme='dark']) .el-date-table__cell.is-other-month .el-date-table__cell-inner {
color: var(--gantt-text-muted, #73767a); color: var(--gantt-text-muted, #73767a);
} }
:global(html[data-theme='dark']) .el-date-table__cell.is-in-range { :global(.gantt-root[data-theme='dark']) .el-date-table__cell.is-in-range {
background: rgba(64, 158, 255, 0.2); background: rgba(64, 158, 255, 0.2);
} }
/* 暗黑模式下的日期选择器确认按钮 */ /* 暗黑模式下的日期选择器确认按钮 */
:global(html[data-theme='dark']) .el-date-picker-footer { :global(.gantt-root[data-theme='dark']) .el-date-picker-footer {
border-top-color: var(--gantt-border-dark, #414243); border-top-color: var(--gantt-border-dark, #414243);
} }
@@ -2182,69 +2182,69 @@ const timePickerStyle = computed(() => {
} }
/* 暗黑模式下的时间选择器 */ /* 暗黑模式下的时间选择器 */
:global(html[data-theme='dark']) .el-time-picker-input { :global(.gantt-root[data-theme='dark']) .el-time-picker-input {
border-top-color: var(--gantt-border-dark, #414243); border-top-color: var(--gantt-border-dark, #414243);
} }
:global(html[data-theme='dark']) .el-time-picker-label { :global(.gantt-root[data-theme='dark']) .el-time-picker-label {
color: var(--gantt-text-secondary, #909399); color: var(--gantt-text-secondary, #909399);
} }
:global(html[data-theme='dark']) .el-time-input { :global(.gantt-root[data-theme='dark']) .el-time-input {
background: var(--gantt-bg-secondary, #2c2c2c); background: var(--gantt-bg-secondary, #2c2c2c);
border-color: var(--gantt-border-dark, #414243); border-color: var(--gantt-border-dark, #414243);
color: var(--gantt-text-white, #ffffff); color: var(--gantt-text-white, #ffffff);
} }
:global(html[data-theme='dark']) .el-time-input:hover { :global(.gantt-root[data-theme='dark']) .el-time-input:hover {
border-color: var(--gantt-border-hover, #606266); border-color: var(--gantt-border-hover, #606266);
} }
:global(html[data-theme='dark']) .el-time-picker-panel { :global(.gantt-root[data-theme='dark']) .el-time-picker-panel {
background: var(--gantt-bg-secondary, #2c2c2c); background: var(--gantt-bg-secondary, #2c2c2c);
border-color: var(--gantt-border-dark, #414243); border-color: var(--gantt-border-dark, #414243);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
} }
:global(html[data-theme='dark']) .el-time-picker-header { :global(.gantt-root[data-theme='dark']) .el-time-picker-header {
border-bottom-color: var(--gantt-border-dark, #414243); border-bottom-color: var(--gantt-border-dark, #414243);
} }
:global(html[data-theme='dark']) .el-time-picker-title { :global(.gantt-root[data-theme='dark']) .el-time-picker-title {
color: var(--gantt-text-white, #ffffff); color: var(--gantt-text-white, #ffffff);
} }
:global(html[data-theme='dark']) .el-time-column-header { :global(.gantt-root[data-theme='dark']) .el-time-column-header {
color: var(--gantt-text-white, #ffffff); color: var(--gantt-text-white, #ffffff);
} }
:global(html[data-theme='dark']) .el-time-column-list { :global(.gantt-root[data-theme='dark']) .el-time-column-list {
border-color: var(--gantt-border-dark, #414243); border-color: var(--gantt-border-dark, #414243);
} }
:global(html[data-theme='dark']) .el-time-column-list:hover::-webkit-scrollbar-thumb { :global(.gantt-root[data-theme='dark']) .el-time-column-list:hover::-webkit-scrollbar-thumb {
background: var(--gantt-border-hover, #606266); background: var(--gantt-border-hover, #606266);
} }
:global(html[data-theme='dark']) .el-time-item { :global(.gantt-root[data-theme='dark']) .el-time-item {
color: var(--gantt-text-white, #ffffff); color: var(--gantt-text-white, #ffffff);
} }
:global(html[data-theme='dark']) .el-time-item:hover { :global(.gantt-root[data-theme='dark']) .el-time-item:hover {
background: var(--gantt-bg-hover-dark, #3c3e40); background: var(--gantt-bg-hover-dark, #3c3e40);
} }
:global(html[data-theme='dark']) .el-time-picker-footer { :global(.gantt-root[data-theme='dark']) .el-time-picker-footer {
border-top-color: var(--gantt-border-dark, #414243); border-top-color: var(--gantt-border-dark, #414243);
} }
:global(html[data-theme='dark']) .el-time-picker-btn--cancel { :global(.gantt-root[data-theme='dark']) .el-time-picker-btn--cancel {
background: var(--gantt-bg-secondary, #2c2c2c); background: var(--gantt-bg-secondary, #2c2c2c);
border-color: var(--gantt-border-dark, #414243); border-color: var(--gantt-border-dark, #414243);
color: var(--gantt-text-white, #ffffff); color: var(--gantt-text-white, #ffffff);
} }
:global(html[data-theme='dark']) .el-time-picker-btn--cancel:hover { :global(.gantt-root[data-theme='dark']) .el-time-picker-btn--cancel:hover {
background: var(--gantt-bg-hover-dark, #3c3e40); background: var(--gantt-bg-hover-dark, #3c3e40);
border-color: var(--gantt-border-hover, #606266); border-color: var(--gantt-border-hover, #606266);
} }

View File

@@ -1,4 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onUnmounted, onMounted, computed, watch, nextTick, useSlots, provide } from 'vue' import { ref, onUnmounted, onMounted, computed, watch, nextTick, useSlots, provide } from 'vue'
import type { StyleValue } from 'vue' import type { StyleValue } from 'vue'
import TaskList from './TaskList/TaskList.vue' import TaskList from './TaskList/TaskList.vue'
@@ -27,6 +27,9 @@ import type { TaskBarConfig } from '../models/configs/TaskBarConfig'
import { TimelineScale, SCALE_CONFIGS } from '../models/types/TimelineScale' import { TimelineScale, SCALE_CONFIGS } from '../models/types/TimelineScale'
import { useMessage } from '../composables/useMessage' import { useMessage } from '../composables/useMessage'
// 根元素引用
const ganttRootRef = ref<HTMLElement>()
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
tasks: () => [], tasks: () => [],
milestones: () => [], milestones: () => [],
@@ -65,7 +68,7 @@ const props = withDefaults(defineProps<Props>(), {
expandAll: true, expandAll: true,
locale: 'zh-CN', locale: 'zh-CN',
timeScale: 'week', timeScale: 'week',
theme: 'light', theme: undefined, // 不设置默认值,允许自动检测系统主题
}) })
const emit = defineEmits([ const emit = defineEmits([
@@ -111,6 +114,20 @@ provide('enable-task-bar-context-menu', computed(() => props.enableTaskBarContex
// 提供 LinkAnchor 配置给子组件 // 提供 LinkAnchor 配置给子组件
provide('enable-link-anchor', computed(() => props.enableLinkAnchor)) provide('enable-link-anchor', computed(() => props.enableLinkAnchor))
// 检测系统主题偏好
const detectSystemTheme = (): 'light' | 'dark' => {
if (typeof window !== 'undefined' && window.matchMedia) {
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches
return isDark ? 'dark' : 'light'
}
return 'light'
}
// 提供当前主题给子组件用于GanttLinks等组件
// 初始值:先设置为'light'在onMounted中根据props或系统主题设置
const currentThemeMode = ref<'light' | 'dark'>('light')
provide('gantt-theme', currentThemeMode)
// 使用声明式右键菜单 composables // 使用声明式右键菜单 composables
const { hasDeclarativeContextMenu: hasDeclarativeTaskListContextMenu, declarativeContextMenu: declarativeTaskListContextMenu } = const { hasDeclarativeContextMenu: hasDeclarativeTaskListContextMenu, declarativeContextMenu: declarativeTaskListContextMenu } =
useTaskListContextMenu(slots) useTaskListContextMenu(slots)
@@ -238,7 +255,6 @@ interface Props {
// 总计: 1160px (已在 TaskListConfig 中定义) // 总计: 1160px (已在 TaskListConfig 中定义)
// 甘特图容器宽度 // 甘特图容器宽度
const ganttRootRef = ref<HTMLElement | null>(null)
const ganttContainerWidth = ref(1920) // 默认使用常见的屏幕宽度作为初始值 const ganttContainerWidth = ref(1920) // 默认使用常见的屏幕宽度作为初始值
// 监听容器宽度变化 // 监听容器宽度变化
@@ -295,6 +311,16 @@ onMounted(() => {
updateContainerWidth() updateContainerWidth()
// 使用节流版本监听窗口大小变化 // 使用节流版本监听窗口大小变化
window.addEventListener('resize', throttledUpdateContainerWidth) window.addEventListener('resize', throttledUpdateContainerWidth)
// 确保主题在DOM挂载后正确应用
nextTick(() => {
if (ganttRootRef.value) {
// 如果明确设置了props.theme使用设置的值否则检测系统主题
const initialTheme = props.theme ?? detectSystemTheme()
ganttRootRef.value.setAttribute('data-theme', initialTheme)
currentThemeMode.value = initialTheme
}
})
}) })
onUnmounted(() => { onUnmounted(() => {
@@ -940,8 +966,7 @@ onUnmounted(() => {
window.removeEventListener('context-menu', handleTaskContextMenu as EventListener) window.removeEventListener('context-menu', handleTaskContextMenu as EventListener)
}) })
// 主题状态管理 // 主题状态管理已在上面provide部分定义
const currentThemeMode = ref<'light' | 'dark'>('light')
/** /**
* 设置主题模式 * 设置主题模式
@@ -950,7 +975,10 @@ const currentThemeMode = ref<'light' | 'dark'>('light')
const setTheme = (mode?: 'light' | 'dark') => { const setTheme = (mode?: 'light' | 'dark') => {
const targetMode = mode || 'dark' const targetMode = mode || 'dark'
currentThemeMode.value = targetMode currentThemeMode.value = targetMode
document.documentElement.setAttribute('data-theme', targetMode) // 在组件根元素上设置data-theme而不是document.documentElement
if (ganttRootRef.value) {
ganttRootRef.value.setAttribute('data-theme', targetMode)
}
} }
/** /**
@@ -964,13 +992,37 @@ const currentTheme = (): string => {
watch( watch(
() => props.theme, () => props.theme,
(newTheme) => { (newTheme) => {
if (newTheme && newTheme !== currentThemeMode.value) { // 只在组件已挂载后处理
setTheme(newTheme) if (!ganttRootRef.value) return
// 如果明确设置了theme使用设置的值如果是undefined检测系统主题
const targetTheme = newTheme ?? detectSystemTheme()
if (targetTheme !== currentThemeMode.value) {
setTheme(targetTheme)
} }
}, },
{ immediate: true },
) )
// 监听系统主题变化仅在未明确设置theme时生效
if (typeof window !== 'undefined' && window.matchMedia) {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
const handleSystemThemeChange = (e: MediaQueryListEvent) => {
// 只有在用户未明确设置theme prop时才跟随系统
if (!props.theme) {
const systemTheme = e.matches ? 'dark' : 'light'
setTheme(systemTheme)
}
}
// 添加监听器
mediaQuery.addEventListener('change', handleSystemThemeChange)
// 组件卸载时清理
onUnmounted(() => {
mediaQuery.removeEventListener('change', handleSystemThemeChange)
})
}
// 全屏状态管理 // 全屏状态管理
const isFullscreen = ref(false) const isFullscreen = ref(false)
@@ -1599,6 +1651,12 @@ const handleTimelineScaleChanged = (scale: TimelineScale) => {
}) })
} }
// 主题变化处理函数
const handleThemeChange = (isDark: boolean) => {
const newTheme = isDark ? 'dark' : 'light'
setTheme(newTheme)
}
// === 时间维度相关方法 === // === 时间维度相关方法 ===
// 时间刻度顺序定义 // 时间刻度顺序定义
const TIME_SCALE_ORDER: TimelineScale[] = ['hour', 'day', 'week', 'month', 'quarter', 'year'] const TIME_SCALE_ORDER: TimelineScale[] = ['hour', 'day', 'week', 'month', 'quarter', 'year']
@@ -2755,6 +2813,7 @@ defineExpose({
@add-milestone="milestoneAddHandler" @add-milestone="milestoneAddHandler"
@expand-all="handleExpandAll" @expand-all="handleExpandAll"
@collapse-all="handleCollapseAll" @collapse-all="handleCollapseAll"
@theme-change="handleThemeChange"
/> />
<!-- 甘特图主体 --> <!-- 甘特图主体 -->
@@ -3111,42 +3170,42 @@ defineExpose({
} }
/* 暗色主题支持 */ /* 暗色主题支持 */
:global(html[data-theme='dark']) .gantt-root { :global(.gantt-root[data-theme='dark']) .gantt-root {
background: #1e1e1e !important; background: #1e1e1e !important;
color: #e5e5e5 !important; color: #e5e5e5 !important;
} }
:global(html[data-theme='dark']) .gantt-panel { :global(.gantt-root[data-theme='dark']) .gantt-panel {
background: #2c2c2c !important; background: #2c2c2c !important;
} }
:global(html[data-theme='dark']) .gantt-panel-left { :global(.gantt-root[data-theme='dark']) .gantt-panel-left {
border-right-color: #4c4c4c !important; border-right-color: #4c4c4c !important;
} }
:global(html[data-theme='dark']) .focus-close-button { :global(.gantt-root[data-theme='dark']) .focus-close-button {
background: #d85555; background: #d85555;
border-color: #d85555; border-color: #d85555;
box-shadow: 0 4px 12px rgba(216, 85, 85, 0.4); box-shadow: 0 4px 12px rgba(216, 85, 85, 0.4);
} }
:global(html[data-theme='dark']) .focus-close-button:hover { :global(.gantt-root[data-theme='dark']) .focus-close-button:hover {
background: #e67676; background: #e67676;
border-color: #e67676; border-color: #e67676;
box-shadow: 0 6px 16px rgba(216, 85, 85, 0.5); box-shadow: 0 6px 16px rgba(216, 85, 85, 0.5);
} }
:global(html[data-theme='dark']) .focus-close-button .close-icon, :global(.gantt-root[data-theme='dark']) .focus-close-button .close-icon,
:global(html[data-theme='dark']) .focus-close-button .close-text { :global(.gantt-root[data-theme='dark']) .focus-close-button .close-text {
color: #ffffff; color: #ffffff;
} }
:global(html[data-theme='dark']) .focus-close-button:hover .close-icon, :global(.gantt-root[data-theme='dark']) .focus-close-button:hover .close-icon,
:global(html[data-theme='dark']) .focus-close-button:hover .close-text { :global(.gantt-root[data-theme='dark']) .focus-close-button:hover .close-text {
color: #ffffff; color: #ffffff;
} }
:global(html[data-theme='dark']) .gantt-splitter { :global(.gantt-root[data-theme='dark']) .gantt-splitter {
background: linear-gradient( background: linear-gradient(
to right, to right,
transparent, transparent,
@@ -3157,7 +3216,7 @@ defineExpose({
box-shadow: inset 0 0 2px rgba(255, 255, 255, 0.1) !important; box-shadow: inset 0 0 2px rgba(255, 255, 255, 0.1) !important;
} }
:global(html[data-theme='dark']) .gantt-splitter:hover { :global(.gantt-root[data-theme='dark']) .gantt-splitter:hover {
background: linear-gradient( background: linear-gradient(
to right, to right,
transparent, transparent,
@@ -3173,24 +3232,24 @@ defineExpose({
} }
/* 暗色主题支持 - TaskList切换按钮 */ /* 暗色主题支持 - TaskList切换按钮 */
:global(html[data-theme='dark']) .task-list-toggle { :global(.gantt-root[data-theme='dark']) .task-list-toggle {
background: rgba(42, 42, 42, 0.95) !important; background: rgba(42, 42, 42, 0.95) !important;
border-color: #555555 !important; border-color: #555555 !important;
color: #cccccc !important; color: #cccccc !important;
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.4) !important; box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.4) !important;
} }
:global(html[data-theme='dark']) .task-list-toggle.collapsed { :global(.gantt-root[data-theme='dark']) .task-list-toggle.collapsed {
box-shadow: -1px 1px 4px rgba(0, 0, 0, 0.4) !important; box-shadow: -1px 1px 4px rgba(0, 0, 0, 0.4) !important;
} }
:global(html[data-theme='dark']) .task-list-toggle:hover { :global(.gantt-root[data-theme='dark']) .task-list-toggle:hover {
background: rgba(42, 42, 42, 1) !important; background: rgba(42, 42, 42, 1) !important;
color: #569cd6 !important; color: #569cd6 !important;
box-shadow: 1px 2px 8px rgba(86, 156, 214, 0.3) !important; box-shadow: 1px 2px 8px rgba(86, 156, 214, 0.3) !important;
} }
:global(html[data-theme='dark']) .task-list-toggle.collapsed:hover { :global(.gantt-root[data-theme='dark']) .task-list-toggle.collapsed:hover {
box-shadow: -1px 2px 8px rgba(86, 156, 214, 0.3) !important; box-shadow: -1px 2px 8px rgba(86, 156, 214, 0.3) !important;
} }
@@ -3245,11 +3304,11 @@ defineExpose({
} }
/* 暗色主题下的全屏模式 */ /* 暗色主题下的全屏模式 */
:global(html[data-theme='dark']) .gantt-fullscreen { :global(.gantt-root[data-theme='dark']) .gantt-fullscreen {
background: #1e1e1e !important; background: #1e1e1e !important;
} }
:global(html[data-theme='dark']) .gantt-fullscreen .gantt-toolbar { :global(.gantt-root[data-theme='dark']) .gantt-fullscreen .gantt-toolbar {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important;
} }

View File

@@ -1,4 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
import '../styles/app.css' import '../styles/app.css'
const props = defineProps({ const props = defineProps({
visible: Boolean, visible: Boolean,
@@ -102,7 +102,7 @@ const onNo = () => emit('no')
gap: 12px; gap: 12px;
} }
:global(html[data-theme='dark']) .gantt-confirm-dialog { :global(.gantt-root[data-theme='dark']) .gantt-confirm-dialog {
background: var(--gantt-bg-secondary, #f8f9fa) !important; background: var(--gantt-bg-secondary, #f8f9fa) !important;
border-color: var(--gantt-border-dark, #999999) !important; border-color: var(--gantt-border-dark, #999999) !important;
} }

View File

@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch, nextTick, onMounted, onUnmounted } from 'vue' import { ref, watch, nextTick, onMounted, onUnmounted, computed, inject, type Ref } from 'vue'
import type { Task } from '../models/classes/Task' import type { Task } from '../models/classes/Task'
import { getPredecessorIds } from '../utils/predecessorUtils' import { getPredecessorIds } from '../utils/predecessorUtils'
import { CanvasContextManager } from '../utils/canvasUtils' import { CanvasContextManager } from '../utils/canvasUtils'
@@ -32,6 +32,7 @@ interface Props {
// 月份分隔线配置 // 月份分隔线配置
verticalLines?: VerticalLine[] verticalLines?: VerticalLine[]
showVerticalLines?: boolean showVerticalLines?: boolean
// 主题模式通过inject获取不再需要props
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
@@ -41,6 +42,9 @@ const props = withDefaults(defineProps<Props>(), {
offsetTop: 0, offsetTop: 0,
}) })
// 通过inject获取主题
const injectedTheme = inject<Ref<'light' | 'dark'>>('gantt-theme', ref('light'))
// Canvas 引用 // Canvas 引用
const canvasRef = ref<HTMLCanvasElement | null>(null) const canvasRef = ref<HTMLCanvasElement | null>(null)
@@ -50,16 +54,9 @@ const canvasManager = new CanvasContextManager()
// requestAnimationFrame 防抖控制 // requestAnimationFrame 防抖控制
let rafId: number | null = null let rafId: number | null = null
let pendingRedraw = false let pendingRedraw = false
let themeObserver: MutationObserver | null = null
// 当前主题(用于分隔线颜色) // 当前主题(用于分隔线颜色)
const isDarkTheme = ref(document.documentElement.getAttribute('data-theme') === 'dark') const isDarkTheme = computed(() => injectedTheme.value === 'dark')
// 监听主题变化
const updateTheme = () => {
isDarkTheme.value = document.documentElement.getAttribute('data-theme') === 'dark'
scheduleRedraw()
}
/** /**
* 绘制关系线到 Canvas * 绘制关系线到 Canvas
@@ -445,6 +442,7 @@ watch(
() => props.showVerticalLines, () => props.showVerticalLines,
() => props.offsetLeft, // 监听虚拟渲染的偏移量变化 () => props.offsetLeft, // 监听虚拟渲染的偏移量变化
() => props.offsetTop, () => props.offsetTop,
injectedTheme, // 监听inject的主题变化computed会自动响应
], ],
() => { () => {
// 使用 RAF 调度重绘,合并连续的多次变化为单次绘制 // 使用 RAF 调度重绘,合并连续的多次变化为单次绘制
@@ -455,21 +453,7 @@ watch(
// 组件挂载后初始化绘制 // 组件挂载后初始化绘制
onMounted(() => { onMounted(() => {
// 监听主题变化 // 不再监听 document.documentElement直接使用props.theme
themeObserver = new MutationObserver(mutations => {
for (const mutation of mutations) {
if (mutation.attributeName === 'data-theme') {
updateTheme()
break
}
}
})
themeObserver.observe(document.documentElement, {
attributes: true,
attributeFilter: ['data-theme'],
})
nextTick(() => { nextTick(() => {
drawLinks() drawLinks()
}) })
@@ -477,12 +461,6 @@ onMounted(() => {
// 组件卸载时清理 // 组件卸载时清理
onUnmounted(() => { onUnmounted(() => {
// 清理主题观察器
if (themeObserver) {
themeObserver.disconnect()
themeObserver = null
}
// 取消待处理的 RAF // 取消待处理的 RAF
if (rafId !== null) { if (rafId !== null) {
cancelAnimationFrame(rafId) cancelAnimationFrame(rafId)

View File

@@ -1,4 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, onUnmounted, computed, watch } from 'vue' import { ref, onMounted, onUnmounted, computed, watch } from 'vue'
import { useI18n } from '../composables/useI18n' import { useI18n } from '../composables/useI18n'
import type { ToolbarConfig } from '../models/configs/ToolbarConfig' import type { ToolbarConfig } from '../models/configs/ToolbarConfig'
@@ -117,7 +117,7 @@ watch(
const newMode = newTheme === 'dark' const newMode = newTheme === 'dark'
if (isDarkMode.value !== newMode) { if (isDarkMode.value !== newMode) {
isDarkMode.value = newMode isDarkMode.value = newMode
document.documentElement.setAttribute('data-theme', newTheme) // 不再直接设置document.documentElement由GanttChart统一管理
} }
} }
}, },
@@ -304,7 +304,7 @@ const handleThemeToggle = () => {
// 立即应用主题变化 // 立即应用主题变化
isDarkMode.value = newTheme isDarkMode.value = newTheme
document.documentElement.setAttribute('data-theme', newTheme ? 'dark' : 'light') // 不再直接设置document.documentElement由GanttChart统一管理
// 立即触发主题变化事件 // 立即触发主题变化事件
if (props.onThemeChange && typeof props.onThemeChange === 'function') { if (props.onThemeChange && typeof props.onThemeChange === 'function') {
@@ -447,23 +447,12 @@ onMounted(() => {
const currentLocale = locale.value const currentLocale = locale.value
currentLanguage.value = currentLocale === 'zh-CN' ? 'zh' : 'en' currentLanguage.value = currentLocale === 'zh-CN' ? 'zh' : 'en'
// 初始化主题状态并应用到DOM // 不再直接设置document.documentElement由GanttChart统一管理
document.documentElement.setAttribute('data-theme', isDarkMode.value ? 'dark' : 'light')
// 添加点击外部关闭下拉菜单的监听 // 添加点击外部关闭下拉菜单的监听
document.addEventListener('click', handleClickOutside) document.addEventListener('click', handleClickOutside)
// 监听系统主题变化(仅在用户未手动设置时) // 不再监听系统主题变化由GanttChart统一管理
if (
window.matchMedia &&
typeof window !== 'undefined' &&
!localStorage.getItem(THEME_STORAGE_KEY)
) {
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
isDarkMode.value = e.matches
document.documentElement.setAttribute('data-theme', e.matches ? 'dark' : 'light')
})
}
}) })
onUnmounted(() => { onUnmounted(() => {
@@ -1058,34 +1047,34 @@ onUnmounted(() => {
} }
/* 暗黑模式样式 */ /* 暗黑模式样式 */
:global(html[data-theme='dark']) .toolbar-icon-btn:hover { :global(.gantt-root[data-theme='dark']) .toolbar-icon-btn:hover {
background: var(--gantt-bg-hover, rgba(255, 255, 255, 0.08)); background: var(--gantt-bg-hover, rgba(255, 255, 255, 0.08));
color: var(--gantt-primary, #66b1ff); color: var(--gantt-primary, #66b1ff);
} }
:global(html[data-theme='dark']) .toolbar-icon-btn:focus { :global(.gantt-root[data-theme='dark']) .toolbar-icon-btn:focus {
background: var(--gantt-bg-hover, rgba(255, 255, 255, 0.1)); background: var(--gantt-bg-hover, rgba(255, 255, 255, 0.1));
color: var(--gantt-primary, #66b1ff); color: var(--gantt-primary, #66b1ff);
} }
:global(html[data-theme='dark']) .toolbar-lang-btn:hover { :global(.gantt-root[data-theme='dark']) .toolbar-lang-btn:hover {
background: var(--gantt-bg-hover, rgba(255, 255, 255, 0.06)); background: var(--gantt-bg-hover, rgba(255, 255, 255, 0.06));
border-color: var(--gantt-primary, #66b1ff); border-color: var(--gantt-primary, #66b1ff);
color: var(--gantt-primary, #66b1ff); color: var(--gantt-primary, #66b1ff);
} }
:global(html[data-theme='dark']) .toolbar-lang-btn:focus { :global(.gantt-root[data-theme='dark']) .toolbar-lang-btn:focus {
background: var(--gantt-bg-hover, rgba(255, 255, 255, 0.08)); background: var(--gantt-bg-hover, rgba(255, 255, 255, 0.08));
border-color: var(--gantt-primary, #66b1ff); border-color: var(--gantt-primary, #66b1ff);
color: var(--gantt-primary, #66b1ff); color: var(--gantt-primary, #66b1ff);
box-shadow: 0 0 0 2px rgba(102, 177, 255, 0.4); box-shadow: 0 0 0 2px rgba(102, 177, 255, 0.4);
} }
:global(html[data-theme='dark']) .dialog-content { :global(.gantt-root[data-theme='dark']) .dialog-content {
background: var(--gantt-bg-secondary, #2c2c2c); background: var(--gantt-bg-secondary, #2c2c2c);
} }
:global(html[data-theme='dark']) .dialog-message { :global(.gantt-root[data-theme='dark']) .dialog-message {
color: var(--gantt-text-primary, #e5eaf3); color: var(--gantt-text-primary, #e5eaf3);
} }
@@ -1270,40 +1259,40 @@ onUnmounted(() => {
} }
/* 暗黑模式下的按钮组样式 */ /* 暗黑模式下的按钮组样式 */
:global(html[data-theme='dark']) .gantt-btn-group { :global(.gantt-root[data-theme='dark']) .gantt-btn-group {
box-shadow: box-shadow:
0 1px 3px 0 rgba(0, 0, 0, 0.3), 0 1px 3px 0 rgba(0, 0, 0, 0.3),
0 1px 2px -1px rgba(0, 0, 0, 0.3); 0 1px 2px -1px rgba(0, 0, 0, 0.3);
} }
:global(html[data-theme='dark']) .gantt-btn-group:hover, :global(.gantt-root[data-theme='dark']) .gantt-btn-group:hover,
:global(html[data-theme='dark']) .gantt-btn-group:focus-within { :global(.gantt-root[data-theme='dark']) .gantt-btn-group:focus-within {
box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.5); box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.5);
} }
:global(html[data-theme='dark']) .add-btn-group .gantt-btn-group-item { :global(.gantt-root[data-theme='dark']) .add-btn-group .gantt-btn-group-item {
background: #337ecc; background: #337ecc;
border-color: #337ecc; border-color: #337ecc;
color: #ffffff; color: #ffffff;
} }
:global(html[data-theme='dark']) .add-btn-group .gantt-btn-group-item:hover { :global(.gantt-root[data-theme='dark']) .add-btn-group .gantt-btn-group-item:hover {
background: #4d94d4; background: #4d94d4;
border-color: #4d94d4; border-color: #4d94d4;
} }
:global(html[data-theme='dark']) .add-btn-group .gantt-btn-group-item:focus { :global(.gantt-root[data-theme='dark']) .add-btn-group .gantt-btn-group-item:focus {
background: #2c5aa0; background: #2c5aa0;
border-color: #2c5aa0; border-color: #2c5aa0;
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.3); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.3);
} }
:global(html[data-theme='dark']) .add-btn-group .gantt-btn-group-item:active { :global(.gantt-root[data-theme='dark']) .add-btn-group .gantt-btn-group-item:active {
background: #1f4872; background: #1f4872;
border-color: #1f4872; border-color: #1f4872;
} }
:global(html[data-theme='dark']) .gantt-btn-group:not(.gantt-add-btn-group) .gantt-btn-group-item { :global(.gantt-root[data-theme='dark']) .gantt-btn-group:not(.gantt-add-btn-group) .gantt-btn-group-item {
background: #2c2c2c; background: #2c2c2c;
border-color: #4c4c4c; border-color: #4c4c4c;
color: #e5e5e5; color: #e5e5e5;
@@ -1396,41 +1385,41 @@ onUnmounted(() => {
} }
/* 暗黑模式下的分段控制器样式 */ /* 暗黑模式下的分段控制器样式 */
:global(html[data-theme='dark']) .segmented-control { :global(.gantt-root[data-theme='dark']) .segmented-control {
background: var(--gantt-bg-secondary, #4b4b4b); background: var(--gantt-bg-secondary, #4b4b4b);
border-color: var(--gantt-border-color, #808080); border-color: var(--gantt-border-color, #808080);
} }
:global(html[data-theme='dark']) .segmented-control:hover { :global(.gantt-root[data-theme='dark']) .segmented-control:hover {
border-color: var(--gantt-primary, #3399ff); border-color: var(--gantt-primary, #3399ff);
} }
:global(html[data-theme='dark']) .segmented-thumb { :global(.gantt-root[data-theme='dark']) .segmented-thumb {
background: var(--gantt-primary, #3399ff); background: var(--gantt-primary, #3399ff);
box-shadow: box-shadow:
0 1px 2px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.3),
0 1px 6px -1px rgba(0, 0, 0, 0.3); 0 1px 6px -1px rgba(0, 0, 0, 0.3);
} }
:global(html[data-theme='dark']) .segmented-item { :global(.gantt-root[data-theme='dark']) .segmented-item {
color: #ffffff !important; /* 强制使用纯白色,更加突出 */ color: #ffffff !important; /* 强制使用纯白色,更加突出 */
} }
/* 特别针对时间刻度分段控制器的暗黑模式样式 */ /* 特别针对时间刻度分段控制器的暗黑模式样式 */
:global(html[data-theme='dark']) .time-scale-segmented .segmented-item { :global(.gantt-root[data-theme='dark']) .time-scale-segmented .segmented-item {
color: #ffffff !important; /* 确保时间刻度按钮也使用纯白色 */ color: #ffffff !important; /* 确保时间刻度按钮也使用纯白色 */
} }
:global(html[data-theme='dark']) .segmented-item:hover:not(.active) { :global(.gantt-root[data-theme='dark']) .segmented-item:hover:not(.active) {
color: var(--gantt-primary, #3399ff); /* 使用主色调,更加鲜艳 */ color: var(--gantt-primary, #3399ff); /* 使用主色调,更加鲜艳 */
background: rgba(51, 153, 255, 0.12); /* 调整背景透明度,与主色调匹配 */ background: rgba(51, 153, 255, 0.12); /* 调整背景透明度,与主色调匹配 */
} }
:global(html[data-theme='dark']) .segmented-item:active:not(.active) { :global(.gantt-root[data-theme='dark']) .segmented-item:active:not(.active) {
background: rgba(51, 153, 255, 0.2); /* 调整背景透明度,与主色调匹配 */ background: rgba(51, 153, 255, 0.2); /* 调整背景透明度,与主色调匹配 */
} }
:global(html[data-theme='dark']) .segmented-item.active { :global(.gantt-root[data-theme='dark']) .segmented-item.active {
color: #ffffff; color: #ffffff;
} }
</style> </style>

View File

@@ -1,4 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, onUnmounted } from 'vue' import { computed, ref, onUnmounted } from 'vue'
interface Props { interface Props {
@@ -245,16 +245,16 @@ onUnmounted(() => {
} }
/* 暗色主题支持 */ /* 暗色主题支持 */
:global(html[data-theme='dark']) .link-anchor { :global(.gantt-root[data-theme='dark']) .link-anchor {
border-color: #1a1a1a; border-color: #1a1a1a;
} }
:global(html[data-theme='dark']) .link-anchor.valid-target, :global(.gantt-root[data-theme='dark']) .link-anchor.valid-target,
:global(html[data-theme='dark']) .link-anchor.invalid-target { :global(.gantt-root[data-theme='dark']) .link-anchor.invalid-target {
border-color: #1a1a1a; border-color: #1a1a1a;
} }
:global(html[data-theme='dark']) .anchor-tooltip { :global(.gantt-root[data-theme='dark']) .anchor-tooltip {
background: rgba(255, 255, 255, 0.9); background: rgba(255, 255, 255, 0.9);
color: #1a1a1a; color: #1a1a1a;
} }

View File

@@ -1,4 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, watch, computed } from 'vue' import { ref, reactive, watch, computed } from 'vue'
import { useI18n } from '../composables/useI18n' import { useI18n } from '../composables/useI18n'
import DatePicker from './DatePicker.vue' import DatePicker from './DatePicker.vue'
@@ -792,12 +792,12 @@ const t = (key: string) => {
} }
/* 暗黑模式下的确认弹窗 */ /* 暗黑模式下的确认弹窗 */
:global(html[data-theme='dark']) .milestone-confirm-dialog { :global(.gantt-root[data-theme='dark']) .milestone-confirm-dialog {
background: var(--gantt-bg-dark, #1d1e1f); background: var(--gantt-bg-dark, #1d1e1f);
border-color: var(--gantt-border-dark, #3c3e40); border-color: var(--gantt-border-dark, #3c3e40);
} }
:global(html[data-theme='dark']) .milestone-confirm-footer { :global(.gantt-root[data-theme='dark']) .milestone-confirm-footer {
background: var(--gantt-bg-darker, #141414); background: var(--gantt-bg-darker, #141414);
border-color: var(--gantt-border-dark, #3c3e40); border-color: var(--gantt-border-dark, #3c3e40);
} }

View File

@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, onUnmounted } from 'vue' import { computed, ref, onUnmounted } from 'vue'
import type { Milestone } from '../models/classes/Milestone' import type { Milestone } from '../models/classes/Milestone'
@@ -1067,23 +1067,23 @@ const calculateMilestonePositionFromTimelineData = (
} }
/* 暗黑模式下的适配 */ /* 暗黑模式下的适配 */
:global(html[data-theme='dark']) .milestone-label { :global(.gantt-root[data-theme='dark']) .milestone-label {
color: var(--gantt-text-white, #ffffff) !important; color: var(--gantt-text-white, #ffffff) !important;
} }
/* 暗黑模式下的粘性标签样式 */ /* 暗黑模式下的粘性标签样式 */
:global(html[data-theme='dark']) .milestone-label[style*='position: absolute'] { :global(.gantt-root[data-theme='dark']) .milestone-label[style*='position: absolute'] {
background: rgba(30, 30, 30, 0.9) !important; background: rgba(30, 30, 30, 0.9) !important;
border-color: rgba(246, 124, 124, 0.3) !important; border-color: rgba(246, 124, 124, 0.3) !important;
color: #ffffff !important; color: #ffffff !important;
} }
:global(html[data-theme='dark']) .milestone svg { :global(.gantt-root[data-theme='dark']) .milestone svg {
filter: drop-shadow(0 0 8px var(--gantt-danger, #f67c7c)); filter: drop-shadow(0 0 8px var(--gantt-danger, #f67c7c));
animation: milestone-glow-dark 2s ease-in-out infinite alternate; animation: milestone-glow-dark 2s ease-in-out infinite alternate;
} }
:global(html[data-theme='dark']) .milestone:hover svg { :global(.gantt-root[data-theme='dark']) .milestone:hover svg {
filter: drop-shadow(0 0 16px var(--gantt-danger, #f67c7c)) filter: drop-shadow(0 0 16px var(--gantt-danger, #f67c7c))
drop-shadow(0 0 24px rgba(246, 124, 124, 0.4)); drop-shadow(0 0 24px rgba(246, 124, 124, 0.4));
animation: milestone-glow-intense-dark 1.5s ease-in-out infinite alternate; animation: milestone-glow-intense-dark 1.5s ease-in-out infinite alternate;
@@ -1125,7 +1125,7 @@ const calculateMilestonePositionFromTimelineData = (
animation: none; animation: none;
} }
:global(html[data-theme='dark']) .milestone.dragging svg { :global(.gantt-root[data-theme='dark']) .milestone.dragging svg {
filter: drop-shadow(0 0 20px var(--gantt-danger, #f67c7c)) filter: drop-shadow(0 0 20px var(--gantt-danger, #f67c7c))
drop-shadow(0 0 32px rgba(246, 124, 124, 0.6)); drop-shadow(0 0 32px rgba(246, 124, 124, 0.6));
} }
@@ -1164,14 +1164,14 @@ const calculateMilestonePositionFromTimelineData = (
} }
/* 暗黑模式下的停靠状态样式 */ /* 暗黑模式下的停靠状态样式 */
:global(html[data-theme='dark']) .milestone-sticky-left svg, :global(.gantt-root[data-theme='dark']) .milestone-sticky-left svg,
:global(html[data-theme='dark']) .milestone-sticky-right svg { :global(.gantt-root[data-theme='dark']) .milestone-sticky-right svg {
animation: milestone-glow-sticky-dark 3s ease-in-out infinite alternate; animation: milestone-glow-sticky-dark 3s ease-in-out infinite alternate;
} }
/* 暗黑模式下半图标显示时取消发光效果 */ /* 暗黑模式下半图标显示时取消发光效果 */
:global(html[data-theme='dark']) .milestone-sticky-left svg[style*='clip-path'], :global(.gantt-root[data-theme='dark']) .milestone-sticky-left svg[style*='clip-path'],
:global(html[data-theme='dark']) .milestone-sticky-right svg[style*='clip-path'] { :global(.gantt-root[data-theme='dark']) .milestone-sticky-right svg[style*='clip-path'] {
animation: none; animation: none;
filter: none; filter: none;
} }
@@ -1259,7 +1259,7 @@ const calculateMilestonePositionFromTimelineData = (
} }
/* 暗黑模式下的Tooltip样式 */ /* 暗黑模式下的Tooltip样式 */
:global(html[data-theme='dark']) .milestone-tooltip { :global(.gantt-root[data-theme='dark']) .milestone-tooltip {
background: rgba(30, 30, 30, 0.95) !important; background: rgba(30, 30, 30, 0.95) !important;
color: #ffffff !important; color: #ffffff !important;
} }

View File

@@ -1,4 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue' import { ref, computed, watch } from 'vue'
import type { Task } from '../models/classes/Task' import type { Task } from '../models/classes/Task'
@@ -184,17 +184,17 @@ watch(
} }
/* 暗黑模式 */ /* 暗黑模式 */
:global(html[data-theme='dark']) .predecessor-tag { :global(.gantt-root[data-theme='dark']) .predecessor-tag {
background: var(--gantt-primary-dark, #337ecc); background: var(--gantt-primary-dark, #337ecc);
} }
:global(html[data-theme='dark']) .form-select { :global(.gantt-root[data-theme='dark']) .form-select {
background: var(--gantt-bg-primary, #2b2b2b); background: var(--gantt-bg-primary, #2b2b2b);
border-color: var(--gantt-border-medium, #4c4d4f); border-color: var(--gantt-border-medium, #4c4d4f);
color: var(--gantt-text-primary, #e5eaf3); color: var(--gantt-text-primary, #e5eaf3);
} }
:global(html[data-theme='dark']) .form-select:focus { :global(.gantt-root[data-theme='dark']) .form-select:focus {
border-color: var(--gantt-primary, #409eff); border-color: var(--gantt-primary, #409eff);
} }
</style> </style>

View File

@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, onUnmounted, onMounted, nextTick, watch, useSlots, inject, type ComputedRef } from 'vue' import { ref, computed, onUnmounted, onMounted, nextTick, watch, useSlots, inject, type ComputedRef } from 'vue'
import type { Task } from '../models/classes/Task' import type { Task } from '../models/classes/Task'
@@ -3406,7 +3406,7 @@ const handleAnchorDragEnd = (anchorEvent: { taskId: number; type: 'predecessor'
} }
/* 暗黑主题下的标题颜色 */ /* 暗黑主题下的标题颜色 */
:global(html[data-theme='dark']) .actual-task-name { :global(.gantt-root[data-theme='dark']) .actual-task-name {
color: #ffffff !important; color: #ffffff !important;
} }
@@ -3971,14 +3971,14 @@ const handleAnchorDragEnd = (anchorEvent: { taskId: number; type: 'predecessor'
} }
/* 暗色主题支持 */ /* 暗色主题支持 */
:global(html[data-theme='dark']) .task-bar { :global(.gantt-root[data-theme='dark']) .task-bar {
border-color: #111827 !important; border-color: #111827 !important;
box-shadow: box-shadow:
0 4px 12px rgba(0, 0, 0, 0.7), 0 4px 12px rgba(0, 0, 0, 0.7),
0 2px 4px rgba(0, 0, 0, 0.3) !important; 0 2px 4px rgba(0, 0, 0, 0.3) !important;
} }
:global(html[data-theme='dark']) .task-bar:hover { :global(.gantt-root[data-theme='dark']) .task-bar:hover {
box-shadow: box-shadow:
0 6px 20px rgba(0, 0, 0, 0.8), 0 6px 20px rgba(0, 0, 0, 0.8),
0 4px 8px rgba(0, 0, 0, 0.4) !important; 0 4px 8px rgba(0, 0, 0, 0.4) !important;
@@ -3986,58 +3986,58 @@ const handleAnchorDragEnd = (anchorEvent: { taskId: number; type: 'predecessor'
transition: all 0.2s ease; transition: all 0.2s ease;
} }
:global(html[data-theme='dark']) .task-bar:hover::after { :global(.gantt-root[data-theme='dark']) .task-bar:hover::after {
background: rgba(7, 10, 15, 0.98) !important; background: rgba(7, 10, 15, 0.98) !important;
color: #f9fafb !important; color: #f9fafb !important;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.6) !important; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.6) !important;
} }
:global(html[data-theme='dark']) .task-bar.normal { :global(.gantt-root[data-theme='dark']) .task-bar.normal {
background: linear-gradient(135deg, #1e40af, #1e3a8a) !important; background: linear-gradient(135deg, #1e40af, #1e3a8a) !important;
border-color: #1e3a8a !important; border-color: #1e3a8a !important;
} }
:global(html[data-theme='dark']) .task-bar.milestone { :global(.gantt-root[data-theme='dark']) .task-bar.milestone {
background: linear-gradient(135deg, #c2410c, #9a3412) !important; background: linear-gradient(135deg, #c2410c, #9a3412) !important;
border-color: #9a3412 !important; border-color: #9a3412 !important;
} }
:global(html[data-theme='dark']) .task-bar.completed { :global(.gantt-root[data-theme='dark']) .task-bar.completed {
background: linear-gradient(135deg, #14532d, #16a34a) !important; background: linear-gradient(135deg, #14532d, #16a34a) !important;
border-color: #14532d !important; border-color: #14532d !important;
} }
:global(html[data-theme='dark']) .task-bar.delayed { :global(.gantt-root[data-theme='dark']) .task-bar.delayed {
background: linear-gradient(135deg, #991b1b, #dc2626) !important; background: linear-gradient(135deg, #991b1b, #dc2626) !important;
border-color: #991b1b !important; border-color: #991b1b !important;
} }
:global(html[data-theme='dark']) .task-bar.parent { :global(.gantt-root[data-theme='dark']) .task-bar.parent {
background: linear-gradient(135deg, #581c87, #7c3aed) !important; background: linear-gradient(135deg, #581c87, #7c3aed) !important;
border-color: #581c87 !important; border-color: #581c87 !important;
} }
:global(html[data-theme='dark']) .task-content { :global(.gantt-root[data-theme='dark']) .task-content {
color: #ffffff !important; color: #ffffff !important;
} }
:global(html[data-theme='dark']) .task-name { :global(.gantt-root[data-theme='dark']) .task-name {
color: #ffffff !important; color: #ffffff !important;
} }
:global(html[data-theme='dark']) .progress-bar { :global(.gantt-root[data-theme='dark']) .progress-bar {
background: rgba(255, 255, 255, 0.2) !important; background: rgba(255, 255, 255, 0.2) !important;
} }
:global(html[data-theme='dark']) .progress-fill { :global(.gantt-root[data-theme='dark']) .progress-fill {
background: rgba(255, 255, 255, 0.8) !important; background: rgba(255, 255, 255, 0.8) !important;
} }
:global(html[data-theme='dark']) .resize-handle { :global(.gantt-root[data-theme='dark']) .resize-handle {
background: rgba(255, 255, 255, 0.1) !important; background: rgba(255, 255, 255, 0.1) !important;
} }
:global(html[data-theme='dark']) .resize-handle:hover { :global(.gantt-root[data-theme='dark']) .resize-handle:hover {
background: rgba(255, 255, 255, 0.3) !important; background: rgba(255, 255, 255, 0.3) !important;
} }
@@ -4099,42 +4099,42 @@ const handleAnchorDragEnd = (anchorEvent: { taskId: number; type: 'predecessor'
} }
/* 暗色主题下的短TaskBar溢出效果 */ /* 暗色主题下的短TaskBar溢出效果 */
:global(html[data-theme='dark']) .task-bar.overflow-effect .resize-handle { :global(.gantt-root[data-theme='dark']) .task-bar.overflow-effect .resize-handle {
background: rgba(255, 255, 255, 0.15); background: rgba(255, 255, 255, 0.15);
} }
:global(html[data-theme='dark']) .task-bar.overflow-effect .resize-handle:hover { :global(.gantt-root[data-theme='dark']) .task-bar.overflow-effect .resize-handle:hover {
background: rgba(255, 255, 255, 0.3); background: rgba(255, 255, 255, 0.3);
} }
/* 暗色主题下的进度百分比样式 */ /* 暗色主题下的进度百分比样式 */
:global(html[data-theme='dark']) .task-bar.overflow-effect .task-progress { :global(.gantt-root[data-theme='dark']) .task-bar.overflow-effect .task-progress {
background: rgba(0, 0, 0, 0.9); background: rgba(0, 0, 0, 0.9);
color: white; color: white;
} }
:global(html[data-theme='dark']) .task-bar.week-view { :global(.gantt-root[data-theme='dark']) .task-bar.week-view {
border-color: var(--gantt-border-light, #555555); border-color: var(--gantt-border-light, #555555);
} }
/* 暗色主题下的头像样式 */ /* 暗色主题下的头像样式 */
:global(html[data-theme='dark']) .task-avatar { :global(.gantt-root[data-theme='dark']) .task-avatar {
border-color: rgba(255, 255, 255, 0.3); border-color: rgba(255, 255, 255, 0.3);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
} }
/* 暗色主题下的默认头像 */ /* 暗色主题下的默认头像 */
:global(html[data-theme='dark']) .task-avatar.avatar-default { :global(.gantt-root[data-theme='dark']) .task-avatar.avatar-default {
background: var(--gantt-bg-tertiary, #4a5568); background: var(--gantt-bg-tertiary, #4a5568);
color: var(--gantt-text-tertiary, #718096); color: var(--gantt-text-tertiary, #718096);
} }
/* 暗色主题下的图标颜色 */ /* 暗色主题下的图标颜色 */
:global(html[data-theme='dark']) .task-avatar .avatar-icon { :global(.gantt-root[data-theme='dark']) .task-avatar .avatar-icon {
color: var(--gantt-text-tertiary, #718096); color: var(--gantt-text-tertiary, #718096);
} }
:global(html[data-theme='dark']) .task-avatar.avatar-outside { :global(.gantt-root[data-theme='dark']) .task-avatar.avatar-outside {
border-color: rgba(255, 255, 255, 0.4); border-color: rgba(255, 255, 255, 0.4);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.7); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.7);
} }

View File

@@ -1,4 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, nextTick, computed } from 'vue' import { ref, onMounted, onUnmounted, watch, nextTick, computed } from 'vue'
import { useI18n } from '../composables/useI18n' import { useI18n } from '../composables/useI18n'
import type { Task } from '../models/classes/Task' import type { Task } from '../models/classes/Task'
@@ -661,23 +661,23 @@ onUnmounted(() => {
} }
/* 暗色主题支持 */ /* 暗色主题支持 */
:global(html[data-theme='dark']) .task-context-menu { :global(.gantt-root[data-theme='dark']) .task-context-menu {
background-color: #2c2c2c; background-color: #2c2c2c;
border-color: #444444; border-color: #444444;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.35); box-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
} }
:global(html[data-theme='dark']) .menu-item { :global(.gantt-root[data-theme='dark']) .menu-item {
color: #e5e5e5; color: #e5e5e5;
} }
:global(html[data-theme='dark']) .menu-item:hover { :global(.gantt-root[data-theme='dark']) .menu-item:hover {
background-color: #3a3a3a; background-color: #3a3a3a;
color: #409eff; color: #409eff;
} }
/* 暗色主题下箭头颜色 */ /* 暗色主题下箭头颜色 */
:global(html[data-theme='dark']) .menu-arrow { :global(.gantt-root[data-theme='dark']) .menu-arrow {
border-bottom-color: #2c2c2c; /* 匹配暗色菜单背景色 */ border-bottom-color: #2c2c2c; /* 匹配暗色菜单背景色 */
filter: drop-shadow(0 -1px 2px rgba(0, 0, 0, 0.25)); filter: drop-shadow(0 -1px 2px rgba(0, 0, 0, 0.25));
} }
@@ -784,13 +784,13 @@ onUnmounted(() => {
} }
/* 暗色主题下的子菜单 */ /* 暗色主题下的子菜单 */
:global(html[data-theme='dark']) .submenu { :global(.gantt-root[data-theme='dark']) .submenu {
background-color: #2c2c2c; background-color: #2c2c2c;
border-color: #444444; border-color: #444444;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.35); box-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
} }
:global(html[data-theme='dark']) .submenu-item:hover { :global(.gantt-root[data-theme='dark']) .submenu-item:hover {
background-color: #3a1f1f; background-color: #3a1f1f;
color: #f56c6c; color: #f56c6c;
} }

View File

@@ -1,4 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, watch, computed, onMounted, onUnmounted, nextTick } from 'vue' import { ref, reactive, watch, computed, onMounted, onUnmounted, nextTick } from 'vue'
import { useI18n } from '../composables/useI18n' import { useI18n } from '../composables/useI18n'
import { useMessage } from '../composables/useMessage' import { useMessage } from '../composables/useMessage'
@@ -1467,29 +1467,29 @@ const taskStatus = computed(() => {
} }
/* 暗黑模式样式 */ /* 暗黑模式样式 */
:global(html[data-theme='dark']) .progress-input-group { :global(.gantt-root[data-theme='dark']) .progress-input-group {
border-color: var(--gantt-border-medium, #4c4d4f); border-color: var(--gantt-border-medium, #4c4d4f);
background: var(--gantt-bg-primary, #2b2b2b); background: var(--gantt-bg-primary, #2b2b2b);
} }
:global(html[data-theme='dark']) .progress-input-group:hover { :global(.gantt-root[data-theme='dark']) .progress-input-group:hover {
border-color: var(--gantt-primary, #409eff); border-color: var(--gantt-primary, #409eff);
} }
:global(html[data-theme='dark']) .progress-input-group:focus-within { :global(.gantt-root[data-theme='dark']) .progress-input-group:focus-within {
border-color: var(--gantt-primary, #409eff); border-color: var(--gantt-primary, #409eff);
} }
:global(html[data-theme='dark']) .progress-input { :global(.gantt-root[data-theme='dark']) .progress-input {
color: var(--gantt-text-primary, #e5eaf3); color: var(--gantt-text-primary, #e5eaf3);
background: transparent; background: transparent;
} }
:global(html[data-theme='dark']) .progress-input::placeholder { :global(.gantt-root[data-theme='dark']) .progress-input::placeholder {
color: var(--gantt-text-placeholder, #8b949e); color: var(--gantt-text-placeholder, #8b949e);
} }
:global(html[data-theme='dark']) .progress-unit { :global(.gantt-root[data-theme='dark']) .progress-unit {
color: var(--gantt-text-secondary, #a8a8a8); color: var(--gantt-text-secondary, #a8a8a8);
} }
@@ -1547,27 +1547,27 @@ const taskStatus = computed(() => {
} }
/* 暗黑模式样式优化 */ /* 暗黑模式样式优化 */
:global(html[data-theme='dark']) .drawer-overlay { :global(.gantt-root[data-theme='dark']) .drawer-overlay {
background: rgba(0, 0, 0, 0.7) !important; background: rgba(0, 0, 0, 0.7) !important;
} }
:global(html[data-theme='dark']) .drawer-container { :global(.gantt-root[data-theme='dark']) .drawer-container {
box-shadow: -4px 0 15px rgba(0, 0, 0, 0.4) !important; box-shadow: -4px 0 15px rgba(0, 0, 0, 0.4) !important;
} }
:global(html[data-theme='dark']) .drawer-close-btn:hover { :global(.gantt-root[data-theme='dark']) .drawer-close-btn:hover {
background: var(--gantt-bg-hover, rgba(255, 255, 255, 0.1)) !important; background: var(--gantt-bg-hover, rgba(255, 255, 255, 0.1)) !important;
border-radius: 4px; border-radius: 4px;
} }
:global(html[data-theme='dark']) .form-input:focus, :global(.gantt-root[data-theme='dark']) .form-input:focus,
:global(html[data-theme='dark']) .form-select:focus, :global(.gantt-root[data-theme='dark']) .form-select:focus,
:global(html[data-theme='dark']) .form-textarea:focus { :global(.gantt-root[data-theme='dark']) .form-textarea:focus {
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2) !important; box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2) !important;
} }
:global(html[data-theme='dark']) .form-input::placeholder, :global(.gantt-root[data-theme='dark']) .form-input::placeholder,
:global(html[data-theme='dark']) .form-textarea::placeholder { :global(.gantt-root[data-theme='dark']) .form-textarea::placeholder {
color: var(--gantt-text-muted, #9e9e9e) !important; color: var(--gantt-text-muted, #9e9e9e) !important;
} }
</style> </style>

View File

@@ -1,4 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, useSlots, toRef, inject, type ComputedRef } from 'vue' import { ref, computed, useSlots, toRef, inject, type ComputedRef } from 'vue'
import type { StyleValue } from 'vue' import type { StyleValue } from 'vue'
import { useI18n } from '../../../composables/useI18n' import { useI18n } from '../../../composables/useI18n'
@@ -636,20 +636,20 @@ const assigneeDisplayData = computed(() => {
border-left: 5px solid var(--gantt-danger, #f56c6c) !important; border-left: 5px solid var(--gantt-danger, #f56c6c) !important;
} }
:global(html[data-theme='dark']) .milestone-group-row { :global(.gantt-root[data-theme='dark']) .milestone-group-row {
border-left-color: var(--gantt-danger, #f67c7c); border-left-color: var(--gantt-danger, #f67c7c);
} }
/* 暗黑模式下的任务类型左边框颜色 */ /* 暗黑模式下的任务类型左边框颜色 */
:global(html[data-theme='dark']) .task-type-story { :global(.gantt-root[data-theme='dark']) .task-type-story {
border-left-color: var(--gantt-primary, #7db4f0); border-left-color: var(--gantt-primary, #7db4f0);
} }
:global(html[data-theme='dark']) .task-type-task { :global(.gantt-root[data-theme='dark']) .task-type-task {
border-left-color: var(--gantt-warning, #f0b83c); border-left-color: var(--gantt-warning, #f0b83c);
} }
:global(html[data-theme='dark']) .task-type-milestone { :global(.gantt-root[data-theme='dark']) .task-type-milestone {
border-left-color: var(--gantt-danger, #f67c7c); border-left-color: var(--gantt-danger, #f67c7c);
} }
@@ -775,44 +775,44 @@ const assigneeDisplayData = computed(() => {
} }
/* 暗黑模式适配 */ /* 暗黑模式适配 */
:global(html[data-theme='dark']) .milestone-row-icon { :global(.gantt-root[data-theme='dark']) .milestone-row-icon {
color: var(--gantt-danger, #f67c7c); color: var(--gantt-danger, #f67c7c);
} }
:global(html[data-theme='dark']) .milestone-empty-col { :global(.gantt-root[data-theme='dark']) .milestone-empty-col {
color: var(--gantt-text-disabled, #606266); color: var(--gantt-text-disabled, #606266);
/* 确保暗黑模式下边框颜色与普通数据行一致 */ /* 确保暗黑模式下边框颜色与普通数据行一致 */
border-right-color: var(--gantt-border-light) !important; border-right-color: var(--gantt-border-light) !important;
} }
/* 暗黑模式的悬停效果 */ /* 暗黑模式的悬停效果 */
:global(html[data-theme='dark']) .task-row:hover { :global(.gantt-root[data-theme='dark']) .task-row:hover {
box-shadow: box-shadow:
0 4px 12px rgba(255, 255, 255, 0.1), 0 4px 12px rgba(255, 255, 255, 0.1),
0 2px 8px rgba(0, 0, 0, 0.3); 0 2px 8px rgba(0, 0, 0, 0.3);
} }
:global(html[data-theme='dark']) .task-row.task-row-hovered { :global(.gantt-root[data-theme='dark']) .task-row.task-row-hovered {
background-color: var(--gantt-bg-hover) !important; background-color: var(--gantt-bg-hover) !important;
box-shadow: box-shadow:
0 4px 12px rgba(255, 255, 255, 0.1), 0 4px 12px rgba(255, 255, 255, 0.1),
0 2px 8px rgba(0, 0, 0, 0.3) !important; 0 2px 8px rgba(0, 0, 0, 0.3) !important;
} }
:global(html[data-theme='dark']) .task-row.parent-task:hover { :global(.gantt-root[data-theme='dark']) .task-row.parent-task:hover {
box-shadow: box-shadow:
0 6px 16px rgba(255, 255, 255, 0.15), 0 6px 16px rgba(255, 255, 255, 0.15),
0 2px 8px rgba(0, 0, 0, 0.4); 0 2px 8px rgba(0, 0, 0, 0.4);
} }
:global(html[data-theme='dark']) .task-row.parent-task.task-row-hovered { :global(.gantt-root[data-theme='dark']) .task-row.parent-task.task-row-hovered {
background: var(--gantt-bg-hover-parent) !important; background: var(--gantt-bg-hover-parent) !important;
box-shadow: box-shadow:
0 6px 16px rgba(255, 255, 255, 0.15), 0 6px 16px rgba(255, 255, 255, 0.15),
0 2px 8px rgba(0, 0, 0, 0.4) !important; 0 2px 8px rgba(0, 0, 0, 0.4) !important;
} }
:global(html[data-theme='dark']) .milestone-group-row:hover { :global(.gantt-root[data-theme='dark']) .milestone-group-row:hover {
box-shadow: box-shadow:
0 6px 16px rgba(246, 124, 124, 0.4), 0 6px 16px rgba(246, 124, 124, 0.4),
0 2px 8px rgba(255, 255, 255, 0.1); 0 2px 8px rgba(255, 255, 255, 0.1);
@@ -835,11 +835,11 @@ const assigneeDisplayData = computed(() => {
background-color: rgba(64, 158, 255, 0.05) !important; background-color: rgba(64, 158, 255, 0.05) !important;
} }
:global(html[data-theme='dark']) .task-row-drop-target.drop-after { :global(.gantt-root[data-theme='dark']) .task-row-drop-target.drop-after {
background-color: rgba(125, 180, 240, 0.1) !important; background-color: rgba(125, 180, 240, 0.1) !important;
} }
:global(html[data-theme='dark']) .task-row-drop-target.drop-child { :global(.gantt-root[data-theme='dark']) .task-row-drop-target.drop-child {
background-color: rgba(125, 180, 240, 0.1) !important; background-color: rgba(125, 180, 240, 0.1) !important;
} }

View File

@@ -1,4 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
interface Props { interface Props {
isMilestoneGroup: boolean isMilestoneGroup: boolean
isParentTask: boolean isParentTask: boolean
@@ -75,7 +75,7 @@ withDefaults(defineProps<Props>(), {
} }
/* 暗黑模式下的里程碑图标 */ /* 暗黑模式下的里程碑图标 */
:global(html[data-theme='dark']) .milestone-group-icon { :global(.gantt-root[data-theme='dark']) .milestone-group-icon {
color: var(--gantt-danger, #f67c7c); color: var(--gantt-danger, #f67c7c);
fill: var(--gantt-danger, #f67c7c); fill: var(--gantt-danger, #f67c7c);
} }

View File

@@ -1,4 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, onUnmounted, computed, watch, nextTick, shallowRef } from 'vue' import { ref, onMounted, onUnmounted, computed, watch, nextTick, shallowRef } from 'vue'
import TaskBar from './TaskBar.vue' import TaskBar from './TaskBar.vue'
import MilestonePoint from './MilestonePoint.vue' import MilestonePoint from './MilestonePoint.vue'
@@ -4784,11 +4784,11 @@ const handleAddSuccessor = (task: Task) => {
} }
/* 暗色主题下的旗帜样式 */ /* 暗色主题下的旗帜样式 */
:global(html[data-theme='dark']) .flag-pole { :global(.gantt-root[data-theme='dark']) .flag-pole {
background-color: var(--gantt-primary-light, #66b1ff); background-color: var(--gantt-primary-light, #66b1ff);
} }
:global(html[data-theme='dark']) .flag-content { :global(.gantt-root[data-theme='dark']) .flag-content {
background-color: var(--gantt-primary-light, #66b1ff); background-color: var(--gantt-primary-light, #66b1ff);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
} }
@@ -5024,72 +5024,72 @@ const handleAddSuccessor = (task: Task) => {
} }
/* 暗色主题支持 */ /* 暗色主题支持 */
:global(html[data-theme='dark']) .timeline { :global(.gantt-root[data-theme='dark']) .timeline {
background: var(--gantt-bg-primary, #3a3a3a) !important; background: var(--gantt-bg-primary, #3a3a3a) !important;
color: var(--gantt-text-primary, #e5e5e5) !important; color: var(--gantt-text-primary, #e5e5e5) !important;
} }
:global(html[data-theme='dark']) .timeline-header { :global(.gantt-root[data-theme='dark']) .timeline-header {
background: var(--gantt-bg-secondary, #1a1a1a) !important; background: var(--gantt-bg-secondary, #1a1a1a) !important;
} }
:global(html[data-theme='dark']) .timeline-header-row { :global(.gantt-root[data-theme='dark']) .timeline-header-row {
border-bottom-color: var(--gantt-border-medium, #333333) !important; border-bottom-color: var(--gantt-border-medium, #333333) !important;
} }
:global(html[data-theme='dark']) .timeline-month { :global(.gantt-root[data-theme='dark']) .timeline-month {
border-right-color: var(--gantt-border-medium, #333333) !important; border-right-color: var(--gantt-border-medium, #333333) !important;
} }
:global(html[data-theme='dark']) .year-month-label { :global(.gantt-root[data-theme='dark']) .year-month-label {
color: var(--gantt-text-header, #ffffff) !important; color: var(--gantt-text-header, #ffffff) !important;
} }
:global(html[data-theme='dark']) .timeline-day { :global(.gantt-root[data-theme='dark']) .timeline-day {
border-right-color: var(--gantt-border-light, #555555) !important; border-right-color: var(--gantt-border-light, #555555) !important;
} }
:global(html[data-theme='dark']) .timeline-day.today { :global(.gantt-root[data-theme='dark']) .timeline-day.today {
background: #1a365d !important; background: #1a365d !important;
color: #e3f2fd !important; color: #e3f2fd !important;
} }
:global(html[data-theme='dark']) .timeline-day.weekend { :global(.gantt-root[data-theme='dark']) .timeline-day.weekend {
background: var(--gantt-bg-secondary, #1a1a1a) !important; background: var(--gantt-bg-secondary, #1a1a1a) !important;
color: var(--gantt-text-muted, #b0b0b0) !important; color: var(--gantt-text-muted, #b0b0b0) !important;
} }
:global(html[data-theme='dark']) .day-label { :global(.gantt-root[data-theme='dark']) .day-label {
color: var(--gantt-text-header, #ffffff) !important; color: var(--gantt-text-header, #ffffff) !important;
} }
:global(html[data-theme='dark']) .timeline-body { :global(.gantt-root[data-theme='dark']) .timeline-body {
background: var(--gantt-bg-primary, #6b6b6b) !important; background: var(--gantt-bg-primary, #6b6b6b) !important;
} }
:global(html[data-theme='dark']) .timeline-body-content { :global(.gantt-root[data-theme='dark']) .timeline-body-content {
background: var(--gantt-bg-primary, #6b6b6b) !important; background: var(--gantt-bg-primary, #6b6b6b) !important;
} }
:global(html[data-theme='dark']) .day-columns { :global(.gantt-root[data-theme='dark']) .day-columns {
border-right-color: var(--gantt-border-light, #555555) !important; border-right-color: var(--gantt-border-light, #555555) !important;
} }
:global(html[data-theme='dark']) .month-day-columns { :global(.gantt-root[data-theme='dark']) .month-day-columns {
border-right-color: var(--gantt-border-light, #555555) !important; border-right-color: var(--gantt-border-light, #555555) !important;
} }
:global(html[data-theme='dark']) .day-column { :global(.gantt-root[data-theme='dark']) .day-column {
border-right-color: var(--gantt-border-light, #555555) !important; border-right-color: var(--gantt-border-light, #555555) !important;
/* 非周末列透明背景继承timeline-body的背景色 */ /* 非周末列透明背景继承timeline-body的背景色 */
} }
:global(html[data-theme='dark']) .day-column.today { :global(.gantt-root[data-theme='dark']) .day-column.today {
border-left-color: var(--gantt-primary, #409eff) !important; border-left-color: var(--gantt-primary, #409eff) !important;
background-color: var(--gantt-primary, #409eff) !important; background-color: var(--gantt-primary, #409eff) !important;
} }
:global(html[data-theme='dark']) .day-column.today::before { :global(.gantt-root[data-theme='dark']) .day-column.today::before {
background: linear-gradient( background: linear-gradient(
to bottom, to bottom,
rgba(64, 158, 255, 0.15) 0%, rgba(64, 158, 255, 0.15) 0%,
@@ -5098,17 +5098,17 @@ const handleAddSuccessor = (task: Task) => {
) !important; ) !important;
} }
:global(html[data-theme='dark']) .day-column.today.weekend { :global(.gantt-root[data-theme='dark']) .day-column.today.weekend {
background-color: var(--gantt-primary-color, #409eff) !important; background-color: var(--gantt-primary-color, #409eff) !important;
} }
/* 暗色主题下的今日定位高亮效果 */ /* 暗色主题下的今日定位高亮效果 */
:global(html[data-theme='dark']) .day-column.today-highlight { :global(.gantt-root[data-theme='dark']) .day-column.today-highlight {
background-color: var(--gantt-primary-color, #409eff) !important; background-color: var(--gantt-primary-color, #409eff) !important;
box-shadow: 0 0 8px rgba(64, 158, 255, 0.6) !important; box-shadow: 0 0 8px rgba(64, 158, 255, 0.6) !important;
} }
:global(html[data-theme='dark']) .day-column.today-highlight::before { :global(.gantt-root[data-theme='dark']) .day-column.today-highlight::before {
background: linear-gradient( background: linear-gradient(
to bottom, to bottom,
rgba(64, 158, 255, 0.4) 0%, rgba(64, 158, 255, 0.4) 0%,
@@ -5118,23 +5118,23 @@ const handleAddSuccessor = (task: Task) => {
} }
/* 暗黑模式下的任务行悬停效果 */ /* 暗黑模式下的任务行悬停效果 */
:global(html[data-theme='dark']) .timeline-body .task-row-hovered { :global(.gantt-root[data-theme='dark']) .timeline-body .task-row-hovered {
background-color: var(--gantt-bg-hover) !important; /* 与TaskList保持一致使用透明背景 */ background-color: var(--gantt-bg-hover) !important; /* 与TaskList保持一致使用透明背景 */
/* 降低层级,避免覆盖任务条等元素 */ /* 降低层级,避免覆盖任务条等元素 */
z-index: 11 !important; z-index: 11 !important;
} }
/* 确保暗黑模式下子元素能继续响应事件 */ /* 确保暗黑模式下子元素能继续响应事件 */
:global(html[data-theme='dark']) .timeline-body .task-row-hovered > * { :global(.gantt-root[data-theme='dark']) .timeline-body .task-row-hovered > * {
pointer-events: auto !important; pointer-events: auto !important;
} }
/* 暗黑模式下的非工作时间样式 */ /* 暗黑模式下的非工作时间样式 */
:global(html[data-theme='dark']) .timeline-hour-item.non-working-hour { :global(.gantt-root[data-theme='dark']) .timeline-hour-item.non-working-hour {
background-color: var(--gantt-bg-secondary, #1a1a1a) !important; background-color: var(--gantt-bg-secondary, #1a1a1a) !important;
} }
:global(html[data-theme='dark']) .timeline-hour-item.non-working-hour .hour-label { :global(.gantt-root[data-theme='dark']) .timeline-hour-item.non-working-hour .hour-label {
color: var(--gantt-text-muted, #b0b0b0) !important; color: var(--gantt-text-muted, #b0b0b0) !important;
} }
@@ -5300,98 +5300,98 @@ const handleAddSuccessor = (task: Task) => {
} }
/* 月度视图暗色主题样式 */ /* 月度视图暗色主题样式 */
:global(html[data-theme='dark']) .year-row { :global(.gantt-root[data-theme='dark']) .year-row {
background: var(--gantt-bg-secondary, #1a1a1a) !important; background: var(--gantt-bg-secondary, #1a1a1a) !important;
border-bottom-color: var(--gantt-border-medium, #333333) !important; border-bottom-color: var(--gantt-border-medium, #333333) !important;
} }
:global(html[data-theme='dark']) .timeline-year { :global(.gantt-root[data-theme='dark']) .timeline-year {
border-right-color: var(--gantt-border-medium, #333333) !important; border-right-color: var(--gantt-border-medium, #333333) !important;
} }
:global(html[data-theme='dark']) .year-label { :global(.gantt-root[data-theme='dark']) .year-label {
color: var(--gantt-text-header, #ffffff) !important; color: var(--gantt-text-header, #ffffff) !important;
} }
:global(html[data-theme='dark']) .months-row { :global(.gantt-root[data-theme='dark']) .months-row {
background: var(--gantt-bg-secondary, #1a1a1a) !important; background: var(--gantt-bg-secondary, #1a1a1a) !important;
border-bottom-color: var(--gantt-border-medium, #333333) !important; border-bottom-color: var(--gantt-border-medium, #333333) !important;
} }
:global(html[data-theme='dark']) .timeline-month-item { :global(.gantt-root[data-theme='dark']) .timeline-month-item {
border-right-color: var(--gantt-border-light, #555555) !important; border-right-color: var(--gantt-border-light, #555555) !important;
border-bottom-color: var(--gantt-border-light, #555555) !important; border-bottom-color: var(--gantt-border-light, #555555) !important;
} }
:global(html[data-theme='dark']) .timeline-month-item.today { :global(.gantt-root[data-theme='dark']) .timeline-month-item.today {
background-color: var(--gantt-primary); background-color: var(--gantt-primary);
border-left-color: var(--gantt-primary, #409eff) !important; border-left-color: var(--gantt-primary, #409eff) !important;
} }
:global(html[data-theme='dark']) .month-label { :global(.gantt-root[data-theme='dark']) .month-label {
color: var(--gantt-text-header, #ffffff) !important; color: var(--gantt-text-header, #ffffff) !important;
} }
/* 季度视图暗色主题样式 */ /* 季度视图暗色主题样式 */
:global(html[data-theme='dark']) .quarters-row { :global(.gantt-root[data-theme='dark']) .quarters-row {
background: var(--gantt-bg-secondary, #1a1a1a) !important; background: var(--gantt-bg-secondary, #1a1a1a) !important;
border-bottom-color: var(--gantt-border-medium, #333333) !important; border-bottom-color: var(--gantt-border-medium, #333333) !important;
} }
:global(html[data-theme='dark']) .timeline-quarter-item { :global(.gantt-root[data-theme='dark']) .timeline-quarter-item {
border-right-color: var(--gantt-border-light, #555555) !important; border-right-color: var(--gantt-border-light, #555555) !important;
border-bottom-color: var(--gantt-border-light, #555555) !important; border-bottom-color: var(--gantt-border-light, #555555) !important;
} }
:global(html[data-theme='dark']) .timeline-quarter-item.today { :global(.gantt-root[data-theme='dark']) .timeline-quarter-item.today {
background-color: var(--gantt-primary); background-color: var(--gantt-primary);
border-left-color: var(--gantt-primary, #409eff) !important; border-left-color: var(--gantt-primary, #409eff) !important;
} }
:global(html[data-theme='dark']) .quarter-label { :global(.gantt-root[data-theme='dark']) .quarter-label {
color: var(--gantt-text-header, #ffffff) !important; color: var(--gantt-text-header, #ffffff) !important;
} }
:global(html[data-theme='dark']) .quarter-column { :global(.gantt-root[data-theme='dark']) .quarter-column {
border-right-color: var(--gantt-border-light, #555555) !important; border-right-color: var(--gantt-border-light, #555555) !important;
background-color: var(--gantt-bg-primary, #6b6b6b) !important; background-color: var(--gantt-bg-primary, #6b6b6b) !important;
} }
:global(html[data-theme='dark']) .quarter-column.today { :global(.gantt-root[data-theme='dark']) .quarter-column.today {
background-color: var(--gantt-primary, #409eff) !important; background-color: var(--gantt-primary, #409eff) !important;
} }
:global(html[data-theme='dark']) .month-column { :global(.gantt-root[data-theme='dark']) .month-column {
border-right-color: var(--gantt-border-light, #555555) !important; border-right-color: var(--gantt-border-light, #555555) !important;
} }
:global(html[data-theme='dark']) .month-column.today { :global(.gantt-root[data-theme='dark']) .month-column.today {
background-color: var(--gantt-primary-color, #409eff); background-color: var(--gantt-primary-color, #409eff);
border-left-color: var(--gantt-primary-color, #409eff) !important; border-left-color: var(--gantt-primary-color, #409eff) !important;
} }
/* 年度视图暗色主题样式 */ /* 年度视图暗色主题样式 */
:global(html[data-theme='dark']) .half-years-row { :global(.gantt-root[data-theme='dark']) .half-years-row {
background: var(--gantt-bg-secondary, #1a1a1a) !important; background: var(--gantt-bg-secondary, #1a1a1a) !important;
border-bottom-color: var(--gantt-border-medium, #333333) !important; border-bottom-color: var(--gantt-border-medium, #333333) !important;
} }
:global(html[data-theme='dark']) .timeline-half-year-item { :global(.gantt-root[data-theme='dark']) .timeline-half-year-item {
border-right-color: var(--gantt-border-light, #555555) !important; border-right-color: var(--gantt-border-light, #555555) !important;
border-bottom-color: var(--gantt-border-light, #555555) !important; border-bottom-color: var(--gantt-border-light, #555555) !important;
} }
:global(html[data-theme='dark']) .half-year-label { :global(.gantt-root[data-theme='dark']) .half-year-label {
color: var(--gantt-text-header, #ffffff) !important; color: var(--gantt-text-header, #ffffff) !important;
} }
/* 年度视图背景列暗色主题样式 */ /* 年度视图背景列暗色主题样式 */
:global(html[data-theme='dark']) .half-year-column { :global(.gantt-root[data-theme='dark']) .half-year-column {
border-right-color: var(--gantt-border-light, #555555) !important; border-right-color: var(--gantt-border-light, #555555) !important;
background-color: var(--gantt-bg-primary, #6b6b6b) !important; background-color: var(--gantt-bg-primary, #6b6b6b) !important;
} }
:global(html[data-theme='dark']) .half-year-column:hover { :global(.gantt-root[data-theme='dark']) .half-year-column:hover {
background-color: var(--gantt-bg-hover, rgba(64, 158, 255, 0.1)) !important; background-color: var(--gantt-bg-hover, rgba(64, 158, 255, 0.1)) !important;
} }
@@ -5407,7 +5407,7 @@ const handleAddSuccessor = (task: Task) => {
} }
/* 暗黑模式下的年度视图今日标记线 */ /* 暗黑模式下的年度视图今日标记线 */
:global(html[data-theme='dark']) .today-line-year-view { :global(.gantt-root[data-theme='dark']) .today-line-year-view {
background-color: var(--gantt-primary, #66b1ff); background-color: var(--gantt-primary, #66b1ff);
box-shadow: 0 0 4px rgba(102, 177, 255, 0.4); box-shadow: 0 0 4px rgba(102, 177, 255, 0.4);
} }
@@ -5569,65 +5569,65 @@ const handleAddSuccessor = (task: Task) => {
} }
/* 小时视图暗色主题样式 */ /* 小时视图暗色主题样式 */
:global(html[data-theme='dark']) .date-row { :global(.gantt-root[data-theme='dark']) .date-row {
background: var(--gantt-bg-secondary, #1a1a1a) !important; background: var(--gantt-bg-secondary, #1a1a1a) !important;
border-bottom-color: var(--gantt-border-medium, #333333) !important; border-bottom-color: var(--gantt-border-medium, #333333) !important;
} }
:global(html[data-theme='dark']) .timeline-day-item { :global(.gantt-root[data-theme='dark']) .timeline-day-item {
border-right-color: var(--gantt-border-medium, #333333) !important; border-right-color: var(--gantt-border-medium, #333333) !important;
} }
:global(html[data-theme='dark']) .date-label { :global(.gantt-root[data-theme='dark']) .date-label {
color: var(--gantt-text-header, #ffffff) !important; color: var(--gantt-text-header, #ffffff) !important;
} }
:global(html[data-theme='dark']) .hours-row { :global(.gantt-root[data-theme='dark']) .hours-row {
background: var(--gantt-bg-secondary, #1a1a1a) !important; background: var(--gantt-bg-secondary, #1a1a1a) !important;
border-bottom-color: var(--gantt-border-medium, #333333) !important; border-bottom-color: var(--gantt-border-medium, #333333) !important;
} }
:global(html[data-theme='dark']) .timeline-hour-item { :global(.gantt-root[data-theme='dark']) .timeline-hour-item {
border-right-color: var(--gantt-border-light, #555555) !important; border-right-color: var(--gantt-border-light, #555555) !important;
border-bottom-color: var(--gantt-border-light, #555555) !important; border-bottom-color: var(--gantt-border-light, #555555) !important;
} }
:global(html[data-theme='dark']) .timeline-hour-item.today { :global(.gantt-root[data-theme='dark']) .timeline-hour-item.today {
background-color: var(--gantt-primary, #1a365d) !important; background-color: var(--gantt-primary, #1a365d) !important;
color: var(--gantt-text-white, #e3f2fd) !important; color: var(--gantt-text-white, #e3f2fd) !important;
} }
:global(html[data-theme='dark']) .hour-label { :global(.gantt-root[data-theme='dark']) .hour-label {
color: var(--gantt-text-primary, #e5e5e5) !important; color: var(--gantt-text-primary, #e5e5e5) !important;
} }
:global(html[data-theme='dark']) .timeline-hour-item.today .hour-label { :global(.gantt-root[data-theme='dark']) .timeline-hour-item.today .hour-label {
color: var(--gantt-text-white, #e3f2fd) !important; color: var(--gantt-text-white, #e3f2fd) !important;
} }
:global(html[data-theme='dark']) .hour-column { :global(.gantt-root[data-theme='dark']) .hour-column {
border-right-color: var(--gantt-border-light, #555555) !important; border-right-color: var(--gantt-border-light, #555555) !important;
} }
:global(html[data-theme='dark']) .hour-column.weekend { :global(.gantt-root[data-theme='dark']) .hour-column.weekend {
background-color: var(--gantt-bg-secondary, #1a1a1a) !important; background-color: var(--gantt-bg-secondary, #1a1a1a) !important;
} }
:global(html[data-theme='dark']) .hour-column.rest-hour { :global(.gantt-root[data-theme='dark']) .hour-column.rest-hour {
background-color: var(--gantt-bg-secondary, #1a1a1a) !important; background-color: var(--gantt-bg-secondary, #1a1a1a) !important;
} }
:global(html[data-theme='dark']) .hour-column.working-hour { :global(.gantt-root[data-theme='dark']) .hour-column.working-hour {
background-color: var(--gantt-bg-primary, #6b6b6b) !important; background-color: var(--gantt-bg-primary, #6b6b6b) !important;
} }
:global(html[data-theme='dark']) .hour-column.today { :global(.gantt-root[data-theme='dark']) .hour-column.today {
background-color: var(--gantt-primary-color, #409eff) !important; background-color: var(--gantt-primary-color, #409eff) !important;
border-left-color: var(--gantt-primary-color, #409eff) !important; border-left-color: var(--gantt-primary-color, #409eff) !important;
} }
/* 暗色主题15分钟刻度线样式 */ /* 暗色主题15分钟刻度线样式 */
:global(html[data-theme='dark']) .quarter-line { :global(.gantt-root[data-theme='dark']) .quarter-line {
background-color: var(--gantt-border-light, #555555) !important; background-color: var(--gantt-border-light, #555555) !important;
} }
</style> </style>

View File

@@ -36,13 +36,13 @@
} }
/* 暗黑主题下 .gantt-btn-default 全局样式 */ /* 暗黑主题下 .gantt-btn-default 全局样式 */
:global(html[data-theme='dark']) .gantt-btn-default { :global(.gantt-root[data-theme='dark']) .gantt-btn-default {
background: var(--gantt-bg-tertiary, #454545) !important; background: var(--gantt-bg-tertiary, #454545) !important;
border-color: var(--gantt-border-color, #dcdfe6) !important; border-color: var(--gantt-border-color, #dcdfe6) !important;
color: var(--gantt-text-white, #ffffff) !important; color: var(--gantt-text-white, #ffffff) !important;
} }
:global(html[data-theme='dark']) .gantt-btn-default:hover:not(:disabled) { :global(.gantt-root[data-theme='dark']) .gantt-btn-default:hover:not(:disabled) {
background: var(--gantt-bg-hover, rgba(255, 255, 255, 0.1)) !important; background: var(--gantt-bg-hover, rgba(255, 255, 255, 0.1)) !important;
border-color: var(--gantt-primary, #409eff) !important; border-color: var(--gantt-primary, #409eff) !important;
color: var(--gantt-primary, #409eff) !important; color: var(--gantt-primary, #409eff) !important;
@@ -82,23 +82,17 @@
} }
/* 黑暗模式全局样式 */ /* 黑暗模式全局样式 */
html[data-theme='dark'] { .gantt-root[data-theme='dark'] {
background: #1e1e1e !important; background: #1e1e1e;
color-scheme: dark !important; color-scheme: dark;
} }
html[data-theme='dark'] body { /* 移除body样式因为不再全局污染 */
background: #1e1e1e !important;
color: #e5e5e5 !important;
}
/* 明亮模式全局样式 */ /* 明亮模式全局样式 */
html[data-theme='light'] { .gantt-root[data-theme='light'] {
background: #ffffff !important; background: #ffffff;
color-scheme: light !important; color-scheme: light;
} }
html[data-theme='light'] body { /* 移除body样式因为不再全局污染 */
background: #ffffff !important;
color: #333333 !important;
}

View File

@@ -38,7 +38,7 @@
} }
/* 暗黑主题 */ /* 暗黑主题 */
html[data-theme='dark'] { .gantt-root[data-theme='dark'] {
/* 背景色 - 大幅提升亮度,接近中性灰 */ /* 背景色 - 大幅提升亮度,接近中性灰 */
--gantt-bg-primary: #6b6b6b; /* Body主体 - 明显更亮,接近中性灰 */ --gantt-bg-primary: #6b6b6b; /* Body主体 - 明显更亮,接近中性灰 */
--gantt-bg-secondary: #4b4b4b; /* Header背景 - 中等亮度,保持层次 */ --gantt-bg-secondary: #4b4b4b; /* Header背景 - 中等亮度,保持层次 */