|
1 | 1 | <script lang="ts" setup> |
2 | 2 | import { onClickOutside } from '@vueuse/core' |
3 | 3 |
|
4 | | -import { capitalize, toUpperCase } from '../../utils/common' |
| 4 | +import { capitalize, toUpperCase } from '~/utils/common' |
| 5 | +
|
5 | 6 | import { JeLine } from '../Frame' |
6 | 7 | import { JeGroup } from '../Group' |
7 | 8 | import { JePopup } from '../Popup' |
@@ -65,6 +66,10 @@ function setHoveredOption(index: string | number | null) { |
65 | 66 | * @param option - 被点击的菜单项 |
66 | 67 | */ |
67 | 68 | function handleOptionClick(option: JeMenuOptionProps) { |
| 69 | + // 禁用状态不响应点击 |
| 70 | + if (option.disabled) |
| 71 | + return |
| 72 | +
|
68 | 73 | if (option.onClick) { |
69 | 74 | option.onClick() // 调用选项的 onClick 回调函数 |
70 | 75 | } |
@@ -137,11 +142,17 @@ function checkMenuPosition() { |
137 | 142 | <li |
138 | 143 | v-else |
139 | 144 | class="je-menu__option-item" |
140 | | - :class="{ hovered: option.childMenu && hoveredOptionIndex === index }" |
141 | | - :tabindex="0" |
| 145 | + :class="{ |
| 146 | + hovered: option.childMenu && hoveredOptionIndex === index && !option.disabled, |
| 147 | + disabled: option.disabled, |
| 148 | + }" |
| 149 | + :tabindex="option.disabled ? -1 : 0" |
| 150 | + role="menuitem" |
| 151 | + :aria-disabled="option.disabled || undefined" |
142 | 152 | @click="handleOptionClick(option)" |
143 | 153 | @keydown.enter="handleOptionClick(option)" |
144 | | - @mouseenter="setHoveredOption(index)" |
| 154 | + @mouseenter="!option.disabled && setHoveredOption(index)" |
| 155 | + @mouseleave="setHoveredOption(null)" |
145 | 156 | > |
146 | 157 | <div class="je-menu__option-item-left"> |
147 | 158 | <!-- Option Icon --> |
@@ -198,7 +209,7 @@ function checkMenuPosition() { |
198 | 209 |
|
199 | 210 | <!-- 子菜单递归渲染 --> |
200 | 211 | <div |
201 | | - v-if="option.childMenu && hoveredOptionIndex === index" |
| 212 | + v-if="option.childMenu && !option.disabled && hoveredOptionIndex === index" |
202 | 213 | class="je-menu__child-menu-wrapper" |
203 | 214 | :style="{ left: childMenuPosition === 'right' ? '100%' : 'auto', right: childMenuPosition === 'left' ? '100%' : 'auto' }" |
204 | 215 | > |
@@ -234,11 +245,17 @@ function checkMenuPosition() { |
234 | 245 | <li |
235 | 246 | v-else |
236 | 247 | class="je-menu__option-item" |
237 | | - :class="{ hovered: groupOption.childMenu && hoveredOptionIndex === `${index}-${groupIndex}` }" |
238 | | - :tabindex="0" |
| 248 | + :class="{ |
| 249 | + hovered: groupOption.childMenu && hoveredOptionIndex === `${index}-${groupIndex}` && !groupOption.disabled, |
| 250 | + disabled: groupOption.disabled, |
| 251 | + }" |
| 252 | + :tabindex="groupOption.disabled ? -1 : 0" |
| 253 | + role="menuitem" |
| 254 | + :aria-disabled="groupOption.disabled || undefined" |
239 | 255 | @click="handleOptionClick(groupOption)" |
240 | 256 | @keydown.enter="handleOptionClick(groupOption)" |
241 | | - @mouseenter="setHoveredOption(`${index}-${groupIndex}`)" |
| 257 | + @mouseenter="!groupOption.disabled && setHoveredOption(`${index}-${groupIndex}`)" |
| 258 | + @mouseleave="setHoveredOption(null)" |
242 | 259 | > |
243 | 260 | <div class="je-menu__option-item-left"> |
244 | 261 | <!-- Option Icon --> |
@@ -295,7 +312,7 @@ function checkMenuPosition() { |
295 | 312 |
|
296 | 313 | <!-- 子菜单递归渲染 --> |
297 | 314 | <div |
298 | | - v-if="groupOption.childMenu && hoveredOptionIndex === `${index}-${groupIndex}`" |
| 315 | + v-if="groupOption.childMenu && !groupOption.disabled && hoveredOptionIndex === `${index}-${groupIndex}`" |
299 | 316 | class="je-menu__child-menu-wrapper" |
300 | 317 | :style="{ left: childMenuPosition === 'right' ? '100%' : 'auto', right: childMenuPosition === 'left' ? '100%' : 'auto' }" |
301 | 318 | > |
@@ -345,6 +362,24 @@ function checkMenuPosition() { |
345 | 362 | &:hover { |
346 | 363 | @apply light:bg-$blue-11 dark:bg-$blue-2; |
347 | 364 | } |
| 365 | +
|
| 366 | + &.disabled { |
| 367 | + @apply opacity-60 cursor-not-allowed; |
| 368 | + /* 禁用时禁用悬停高亮 */ |
| 369 | + &:hover { |
| 370 | + @apply bg-transparent light:bg-transparent dark:bg-transparent; |
| 371 | + } |
| 372 | +
|
| 373 | + .je-menu__option-label:not(.custom-color), |
| 374 | + .je-menu__option-description, |
| 375 | + .je-menu__option-shortcut { |
| 376 | + @apply light:color-$gray-6 dark:color-$gray-8; |
| 377 | + } |
| 378 | +
|
| 379 | + .je-menu__icon-drop-down { |
| 380 | + @apply opacity-60; |
| 381 | + } |
| 382 | + } |
348 | 383 | } |
349 | 384 |
|
350 | 385 | .je-menu__option-item-left, |
@@ -385,11 +420,11 @@ function checkMenuPosition() { |
385 | 420 | } |
386 | 421 |
|
387 | 422 | .je-menu__option-line { |
388 | | - JeLine { |
| 423 | + :deep(.je-line) { |
389 | 424 | @apply my-1px; |
390 | 425 | } |
391 | 426 |
|
392 | | - &.je-menu__option-group JeLine { |
| 427 | + &.je-menu__option-group :deep(.je-line) { |
393 | 428 | @apply ml-6px; |
394 | 429 | } |
395 | 430 | } |
|
0 commit comments