diff --git a/.gitignore b/.gitignore
index 3488237..f4a55f8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,8 @@ pnpm-debug.log*
lerna-debug.log*
node_modules
+dist
+dist-ssr
*.local
# Editor directories and files
@@ -36,4 +38,3 @@ Desktop.ini
yarn.lock
.ai/
-dist/
diff --git a/demo/App.vue b/demo/App.vue
index 5c36825..5e55512 100644
--- a/demo/App.vue
+++ b/demo/App.vue
@@ -2211,7 +2211,6 @@ const handleCustomMenuAction = (action: string, task: Task) => {
:view-mode="viewMode"
:resource-list-config="resourceListConfig"
:locale="controlMode === 'props' ? propsLocale : undefined"
- :theme="controlMode === 'props' ? propsTheme : undefined"
:time-scale="controlMode === 'props' ? propsTimeScale : undefined"
:fullscreen="controlMode === 'props' ? propsFullscreen : undefined"
:expand-all="controlMode === 'props' ? propsExpandAll : undefined"
diff --git a/demo/version-history.json b/demo/version-history.json
index 6d36d38..f1c06f7 100644
--- a/demo/version-history.json
+++ b/demo/version-history.json
@@ -492,5 +492,19 @@
"🎉 Optimized: The assignee and avatar properties of the Task object now accept arrays to mark multiple assignees",
"Special thanks to yunlbs/fhjfhj/jakepan@gitee for their use and suggestions"
]
+ },
+ {
+ "version": "1.8.1",
+ "date": "2026-02-05",
+ "notes": [
+ "🎉 优化:重构组件,Theme作用域从全局调整至局部.gantt-root",
+ "🎉 优化:重构组件,Theme自动跟随系统设置",
+ "🎉 优化:重构组件,完美支持Nuxt3、TailwindCSS等框架",
+ "特别感谢andrijor@gmail.com的专业反馈",
+ "🎉 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",
+ "Special thanks to andrijor@gmail.com for their professional feedback"
+ ]
}
]
diff --git a/package.json b/package.json
index e95c571..2cf9f13 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "jordium-gantt-vue3",
- "version": "1.9.0",
+ "version": "1.8.1",
"type": "module",
"main": "npm-package/dist/jordium-gantt-vue3.cjs.js",
"module": "npm-package/dist/jordium-gantt-vue3.es.js",
diff --git a/src/components/ConfirmTimerDialog.vue b/src/components/ConfirmTimerDialog.vue
index 8f3a64e..df19e08 100644
--- a/src/components/ConfirmTimerDialog.vue
+++ b/src/components/ConfirmTimerDialog.vue
@@ -1,4 +1,4 @@
-
@@ -330,7 +289,6 @@ const assigneeDisplayData = computed(() => {
:data-task-id="props.task.id"
:class="{
'task-row-hovered': isHovered,
- 'task-type-resource': isResourceRow, /* v1.9.0 资源视图始终显示左边框 */
'parent-task': isParentTask,
'milestone-group-row': isMilestoneGroup,
'task-type-story': isStoryTask,
@@ -338,7 +296,7 @@ const assigneeDisplayData = computed(() => {
'task-type-milestone': isMilestoneTask,
[customRowClass]: customRowClass,
}"
- :style="[customRowStyle, customBorderStyle, { height: `${rowHeight}px` }]"
+ :style="[customRowStyle, customBorderStyle]"
@click="handleRowClick"
@dblclick="handleTaskRowDoubleClick"
@mousedown="handleMouseDown"
@@ -400,40 +358,11 @@ const assigneeDisplayData = computed(() => {
-
-
-
-
-
-
![]()
-
-
{{ (props.task as any).name || '-' }}
-
-
-
{
{{ column.formatter(props.task, column) }}
-
-
- {{ (props.task as any)[column.key] || '-' }}
-
-
-
+
{{ formatPredecessorDisplay(props.task.predecessor) }}
@@ -610,26 +534,30 @@ const assigneeDisplayData = computed(() => {
.task-row {
display: flex;
border-bottom: 1px solid var(--gantt-border-light);
- height: 51px; /* v1.9.1 任务视图51px(包含border-bottom 1px),资源视图动态高度(第一行56px,后续行46px) */
+ height: 51px; /* 修改为51px,与Timeline中的task-row高度保持一致,包含border-bottom 1px */
box-sizing: border-box; /* 确保border包含在高度计算中 */
background: var(--gantt-bg-primary);
align-items: center;
color: var(--gantt-text-secondary);
cursor: pointer;
- transition: background-color 0.15s ease, box-shadow 0.15s ease;
+ transition: all 0.3s ease;
+ transform: scale(1);
+ transform-origin: 5px center; /* 从左侧偏右5px的位置作为放大中心 */
z-index: 1;
position: relative;
}
.task-row:hover {
background-color: var(--gantt-bg-hover);
- box-shadow: 0 1px 3px 0 rgba(60, 64, 67, 0.3), 0 4px 8px 3px rgba(60, 64, 67, 0.15);
+ transform: scale(1.02);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
z-index: 10;
}
.task-row-hovered {
background-color: var(--gantt-bg-hover) !important;
- box-shadow: 0 1px 3px 0 rgba(60, 64, 67, 0.3), 0 4px 8px 3px rgba(60, 64, 67, 0.15) !important;
+ transform: scale(1.02) !important;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;
z-index: 10 !important;
}
@@ -640,13 +568,15 @@ const assigneeDisplayData = computed(() => {
.task-row.parent-task:hover {
background: var(--gantt-bg-hover-parent, var(--gantt-bg-hover));
- box-shadow: 0 1px 3px 0 rgba(60, 64, 67, 0.3), 0 4px 8px 3px rgba(60, 64, 67, 0.15);
+ transform: scale(1.02);
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
z-index: 10;
}
.task-row.parent-task.task-row-hovered {
background: var(--gantt-bg-hover-parent, var(--gantt-bg-hover)) !important;
- box-shadow: 0 1px 3px 0 rgba(60, 64, 67, 0.3), 0 4px 8px 3px rgba(60, 64, 67, 0.15) !important;
+ transform: scale(1.02) !important;
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2) !important;
z-index: 10 !important;
}
@@ -656,9 +586,12 @@ const assigneeDisplayData = computed(() => {
background: linear-gradient(90deg, var(--gantt-bg-tertiary) 0%, var(--gantt-bg-primary) 100%);
}
-.mbox-shadow: 0 1px 3px 0 rgba(60, 64, 67, 0.3), 0 4px 8px 3px rgba(60, 64, 67, 0.15);
- ilestone-group-row:hover {
+.milestone-group-row:hover {
background: linear-gradient(90deg, var(--gantt-bg-hover-parent) 0%, var(--gantt-bg-hover) 100%);
+ transform: scale(1.02);
+ box-shadow:
+ 0 6px 16px rgba(245, 108, 108, 0.3),
+ 0 2px 8px rgba(0, 0, 0, 0.1);
z-index: 10;
border-left-color: var(--gantt-danger, #f56c6c);
border-left-width: 4px; /* 悬停时边框稍微加粗 */
@@ -677,66 +610,49 @@ const assigneeDisplayData = computed(() => {
border-left: 3px solid var(--gantt-danger, #f56c6c);
}
-/* v1.9.0 资源类型左边框颜色 */
-.task-type-resource {
- border-left: 3px solid var(--gantt-success, #67c23a);
-}
-
-/* 任务类型悬停时保持左边框,无需加粗 */
+/* 任务类型悬停时保持并增强左边框 */
.task-type-story:hover {
- border-left: 3px solid var(--gantt-primary, #409eff);
+ border-left: 5px solid var(--gantt-primary, #409eff);
}
.task-type-task:hover {
- border-left: 3px solid var(--gantt-warning, #e6a23c);
+ border-left: 5px solid var(--gantt-warning, #e6a23c);
}
.task-type-milestone:hover {
- border-left: 3px solid var(--gantt-danger, #f56c6c);
-}
-
-.task-type-resource:hover {
- border-left: 3px solid var(--gantt-success, #67c23a);
+ border-left: 5px solid var(--gantt-danger, #f56c6c);
}
/* 悬停状态下的左边框保持 */
.task-row-hovered.task-type-story {
- border-left: 3px solid var(--gantt-primary, #409eff) !important;
+ border-left: 5px solid var(--gantt-primary, #409eff) !important;
}
.task-row-hovered.task-type-task {
- border-left: 3px solid var(--gantt-warning, #e6a23c) !important;
+ border-left: 5px solid var(--gantt-warning, #e6a23c) !important;
}
.task-row-hovered.task-type-milestone {
- border-left: 3px solid var(--gantt-danger, #f56c6c) !important;
+ border-left: 5px solid var(--gantt-danger, #f56c6c) !important;
}
-.task-row-hovered.task-type-resource {
- border-left: 3px solid var(--gantt-success, #67c23a) !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);
}
/* 暗黑模式下的任务类型左边框颜色 */
-:global(html[data-theme='dark']) .task-type-story {
+:global(.gantt-root[data-theme='dark']) .task-type-story {
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);
}
-:global(html[data-theme='dark']) .task-type-milestone {
+:global(.gantt-root[data-theme='dark']) .task-type-milestone {
border-left-color: var(--gantt-danger, #f67c7c);
}
-:global(html[data-theme='dark']) .task-type-resource {
- border-left-color: var(--gantt-success, #85ce61);
-}
-
.collapse-btn:hover {
background-color: var(--gantt-primary-light);
}
@@ -859,37 +775,47 @@ 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);
}
-:global(html[data-theme='dark']) .milestone-empty-col {
+:global(.gantt-root[data-theme='dark']) .milestone-empty-col {
color: var(--gantt-text-disabled, #606266);
/* 确保暗黑模式下边框颜色与普通数据行一致 */
border-right-color: var(--gantt-border-light) !important;
}
/* 暗黑模式的悬停效果 */
-:global(html[data-theme='dark']) .task-row:hover {
- box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.3), 0 2px 6px 2px rgba(0, 0, 0, 0.15);
+:global(.gantt-root[data-theme='dark']) .task-row:hover {
+ box-shadow:
+ 0 4px 12px rgba(255, 255, 255, 0.1),
+ 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;
- box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.3), 0 2px 6px 2px rgba(0, 0, 0, 0.15) !important;
+ box-shadow:
+ 0 4px 12px rgba(255, 255, 255, 0.1),
+ 0 2px 8px rgba(0, 0, 0, 0.3) !important;
}
-:global(html[data-theme='dark']) .task-row.parent-task:hover {
- box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.3), 0 2px 6px 2px rgba(0, 0, 0, 0.15);
+:global(.gantt-root[data-theme='dark']) .task-row.parent-task:hover {
+ box-shadow:
+ 0 6px 16px rgba(255, 255, 255, 0.15),
+ 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;
- box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.3), 0 2px 6px 2px rgba(0, 0, 0, 0.15) !important;
+ box-shadow:
+ 0 6px 16px rgba(255, 255, 255, 0.15),
+ 0 2px 8px rgba(0, 0, 0, 0.4) !important;
}
-:global(html[data-theme='dark']) .milestone-group-row:hover {
- box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.3), 0 2px 6px 2px rgba(0, 0, 0, 0.15);
+:global(.gantt-root[data-theme='dark']) .milestone-group-row:hover {
+ box-shadow:
+ 0 6px 16px rgba(246, 124, 124, 0.4),
+ 0 2px 8px rgba(255, 255, 255, 0.1);
}
/* TaskRow拖拽样式 */
@@ -909,57 +835,11 @@ const assigneeDisplayData = computed(() => {
background-color: rgba(64, 158, 255, 0.05) !important;
}
-/* v1.9.0 资源视图行样式 */
-.resource-row-name {
- display: flex;
- align-items: center;
- gap: 8px;
- font-weight: 500;
- color: var(--gantt-text-primary);
-}
-
-/* v1.9.0 资源超载警示图标 */
-.resource-warning-icon {
- width: 18px;
- height: 18px;
- flex-shrink: 0;
- animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
-}
-
-@keyframes pulse {
- 0%, 100% {
- opacity: 1;
- }
- 50% {
- opacity: 0.5;
- }
-}
-
-.resource-avatar {
- width: 28px;
- height: 28px;
- border-radius: 50%;
- overflow: hidden;
- flex-shrink: 0;
-}
-
-.resource-avatar img {
- width: 100%;
- height: 100%;
- object-fit: cover;
-}
-
-.resource-name-text {
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-: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;
}
-: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;
}
diff --git a/src/components/TaskList/taskRow/TaskRowIcon.vue b/src/components/TaskList/taskRow/TaskRowIcon.vue
index c888282..e8ebda8 100644
--- a/src/components/TaskList/taskRow/TaskRowIcon.vue
+++ b/src/components/TaskList/taskRow/TaskRowIcon.vue
@@ -1,4 +1,4 @@
-