diff --git a/apps/web-antd/package.json b/apps/web-antd/package.json index 2705dc2d..6a0247de 100644 --- a/apps/web-antd/package.json +++ b/apps/web-antd/package.json @@ -42,7 +42,7 @@ "@vben/types": "workspace:*", "@vben/utils": "workspace:*", "@vueuse/core": "^11.0.3", - "ant-design-vue": "^4.2.3", + "ant-design-vue": "^4.2.4", "cropperjs": "^1.6.2", "crypto-js": "^4.2.0", "dayjs": "^1.11.13", @@ -52,7 +52,7 @@ "pinia": "2.2.2", "tinymce": "^7.3.0", "vue": "^3.5.4", - "vue-router": "^4.4.4" + "vue-router": "^4.4.5" }, "devDependencies": { "@types/crypto-js": "^4.2.2", diff --git a/apps/web-ele/package.json b/apps/web-ele/package.json index ff2af4ab..7ec1bdaf 100644 --- a/apps/web-ele/package.json +++ b/apps/web-ele/package.json @@ -42,10 +42,10 @@ "@vben/utils": "workspace:*", "@vueuse/core": "^11.0.3", "dayjs": "^1.11.13", - "element-plus": "^2.8.2", + "element-plus": "^2.8.3", "pinia": "2.2.2", "vue": "^3.5.4", - "vue-router": "^4.4.4" + "vue-router": "^4.4.5" }, "devDependencies": { "unplugin-element-plus": "^0.8.0" diff --git a/apps/web-naive/package.json b/apps/web-naive/package.json index 22f105b1..f4522685 100644 --- a/apps/web-naive/package.json +++ b/apps/web-naive/package.json @@ -44,6 +44,6 @@ "naive-ui": "^2.39.0", "pinia": "2.2.2", "vue": "^3.5.4", - "vue-router": "^4.4.4" + "vue-router": "^4.4.5" } } diff --git a/cspell.json b/cspell.json index 1024d56a..d3ffbc57 100644 --- a/cspell.json +++ b/cspell.json @@ -51,7 +51,13 @@ "vitepress", "vnode", "vueuse", - "yxxx" + "yxxx", + "echarts", + "sortablejs", + "etag", + "naiveui", + "uicons", + "iconoir" ], "ignorePaths": [ "**/node_modules/**", diff --git a/internal/lint-configs/commitlint-config/package.json b/internal/lint-configs/commitlint-config/package.json index 6e93ce9f..7bff5f47 100644 --- a/internal/lint-configs/commitlint-config/package.json +++ b/internal/lint-configs/commitlint-config/package.json @@ -23,8 +23,8 @@ } }, "dependencies": { - "@commitlint/cli": "^19.4.1", - "@commitlint/config-conventional": "^19.4.1", + "@commitlint/cli": "^19.5.0", + "@commitlint/config-conventional": "^19.5.0", "@vben/node-utils": "workspace:*", "commitlint-plugin-function-rules": "^4.0.0", "cz-git": "^1.9.4", diff --git a/internal/lint-configs/eslint-config/package.json b/internal/lint-configs/eslint-config/package.json index 069f6844..c49d12ec 100644 --- a/internal/lint-configs/eslint-config/package.json +++ b/internal/lint-configs/eslint-config/package.json @@ -27,8 +27,8 @@ } }, "dependencies": { - "eslint-config-turbo": "^2.1.1", - "eslint-plugin-command": "^0.2.4", + "eslint-config-turbo": "^2.1.2", + "eslint-plugin-command": "^0.2.5", "eslint-plugin-import-x": "^4.2.1" }, "devDependencies": { @@ -39,7 +39,7 @@ "eslint": "^9.10.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-jsdoc": "^50.2.2", + "eslint-plugin-jsdoc": "^50.2.3", "eslint-plugin-jsonc": "^2.16.0", "eslint-plugin-n": "^17.10.2", "eslint-plugin-no-only-tests": "^3.3.0", @@ -47,7 +47,7 @@ "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-regexp": "^2.6.0", "eslint-plugin-unicorn": "^55.0.0", - "eslint-plugin-unused-imports": "^4.1.3", + "eslint-plugin-unused-imports": "^4.1.4", "eslint-plugin-vitest": "^0.5.4", "eslint-plugin-vue": "^9.28.0", "globals": "^15.9.0", diff --git a/internal/tailwind-config/package.json b/internal/tailwind-config/package.json index 85f22d84..d8c03606 100644 --- a/internal/tailwind-config/package.json +++ b/internal/tailwind-config/package.json @@ -46,7 +46,7 @@ "tailwindcss": "^3.4.3" }, "dependencies": { - "@iconify/json": "^2.2.246", + "@iconify/json": "^2.2.247", "@iconify/tailwind": "^1.1.3", "@tailwindcss/nesting": "0.0.0-insiders.565cd3e", "@tailwindcss/typography": "^0.5.15", diff --git a/internal/tsconfig/package.json b/internal/tsconfig/package.json index 84a4c849..c84819c9 100644 --- a/internal/tsconfig/package.json +++ b/internal/tsconfig/package.json @@ -20,6 +20,6 @@ ], "dependencies": { "@vben/types": "workspace:*", - "vite": "^5.4.3" + "vite": "^5.4.5" } } diff --git a/internal/vite-config/package.json b/internal/vite-config/package.json index 53399a10..9c32759f 100644 --- a/internal/vite-config/package.json +++ b/internal/vite-config/package.json @@ -27,7 +27,7 @@ } }, "dependencies": { - "@intlify/unplugin-vue-i18n": "^4.0.0", + "@intlify/unplugin-vue-i18n": "^5.0.0", "@jspm/generator": "^2.3.0", "archiver": "^7.0.1", "cheerio": "1.0.0", @@ -37,7 +37,7 @@ "resolve.exports": "^2.0.2", "vite-plugin-lib-inject-css": "^2.1.1", "vite-plugin-pwa": "^0.20.5", - "vite-plugin-vue-devtools": "^7.4.4" + "vite-plugin-vue-devtools": "^7.4.5" }, "devDependencies": { "@types/archiver": "^6.0.2", @@ -50,7 +50,7 @@ "rollup": "^4.21.3", "rollup-plugin-visualizer": "^5.12.0", "sass": "^1.78.0", - "vite": "^5.4.3", + "vite": "^5.4.5", "vite-plugin-compression": "^0.5.1", "vite-plugin-dts": "4.2.1", "vite-plugin-html": "^3.2.2" diff --git a/package.json b/package.json index 44009ddd..ae115ff4 100644 --- a/package.json +++ b/package.json @@ -86,10 +86,10 @@ "lint-staged": "^15.2.10", "rimraf": "^6.0.1", "tailwindcss": "^3.4.11", - "turbo": "^2.1.1", + "turbo": "^2.1.2", "typescript": "^5.6.2", "unbuild": "^2.0.0", - "vite": "^5.4.3", + "vite": "^5.4.5", "vitest": "^2.1.0", "vue": "^3.5.4", "vue-tsc": "^2.1.6" diff --git a/packages/@core/base/design/src/css/global.css b/packages/@core/base/design/src/css/global.css index f9810e72..3c184109 100644 --- a/packages/@core/base/design/src/css/global.css +++ b/packages/@core/base/design/src/css/global.css @@ -37,10 +37,10 @@ } body { - @apply !pointer-events-auto; - min-height: 100vh; + /* pointer-events: auto !important; */ + /* overflow: overlay; */ /* -webkit-font-smoothing: antialiased; */ diff --git a/packages/@core/base/shared/src/utils/dom.ts b/packages/@core/base/shared/src/utils/dom.ts index 79640d60..16d6ddef 100644 --- a/packages/@core/base/shared/src/utils/dom.ts +++ b/packages/@core/base/shared/src/utils/dom.ts @@ -50,3 +50,22 @@ export function getElementVisibleRect( width: Math.max(0, right - left), }; } + +export function getScrollbarWidth() { + const scrollDiv = document.createElement('div'); + + scrollDiv.style.visibility = 'hidden'; + scrollDiv.style.overflow = 'scroll'; + scrollDiv.style.position = 'absolute'; + scrollDiv.style.top = '-9999px'; + + document.body.append(scrollDiv); + + const innerDiv = document.createElement('div'); + scrollDiv.append(innerDiv); + + const scrollbarWidth = scrollDiv.offsetWidth - innerDiv.offsetWidth; + + scrollDiv.remove(); + return scrollbarWidth; +} diff --git a/packages/@core/base/typings/package.json b/packages/@core/base/typings/package.json index d35f73b6..02b072d2 100644 --- a/packages/@core/base/typings/package.json +++ b/packages/@core/base/typings/package.json @@ -39,6 +39,6 @@ }, "dependencies": { "vue": "^3.5.4", - "vue-router": "^4.4.4" + "vue-router": "^4.4.5" } } diff --git a/packages/@core/composables/src/index.ts b/packages/@core/composables/src/index.ts index 31a7feab..abfd9501 100644 --- a/packages/@core/composables/src/index.ts +++ b/packages/@core/composables/src/index.ts @@ -2,6 +2,7 @@ export * from './use-content-style'; export * from './use-is-mobile'; export * from './use-namespace'; export * from './use-priority-value'; +export * from './use-scroll-lock'; export * from './use-simple-locale'; export * from './use-sortable'; export { diff --git a/packages/@core/composables/src/use-scroll-lock.ts b/packages/@core/composables/src/use-scroll-lock.ts new file mode 100644 index 00000000..b3f40d6b --- /dev/null +++ b/packages/@core/composables/src/use-scroll-lock.ts @@ -0,0 +1,48 @@ +import { getScrollbarWidth } from '@vben-core/shared/utils'; + +import { + useScrollLock as _useScrollLock, + tryOnBeforeMount, + tryOnBeforeUnmount, +} from '@vueuse/core'; + +export const SCROLL_FIXED_CLASS = `_scroll__fixed_`; + +export function useScrollLock() { + const isLocked = _useScrollLock(document.body); + const scrollbarWidth = getScrollbarWidth(); + + tryOnBeforeMount(() => { + document.body.style.paddingRight = `${scrollbarWidth}px`; + + const layoutFixedNodes = document.querySelectorAll( + `.${SCROLL_FIXED_CLASS}`, + ); + const nodes = [...layoutFixedNodes]; + if (nodes.length > 0) { + nodes.forEach((node) => { + node.dataset.transition = node.style.transition; + node.style.transition = 'none'; + node.style.paddingRight = `${scrollbarWidth}px`; + }); + } + isLocked.value = true; + }); + + tryOnBeforeUnmount(() => { + isLocked.value = false; + const layoutFixedNodes = document.querySelectorAll( + `.${SCROLL_FIXED_CLASS}`, + ); + const nodes = [...layoutFixedNodes]; + if (nodes.length > 0) { + nodes.forEach((node) => { + node.style.paddingRight = ''; + requestAnimationFrame(() => { + node.style.transition = node.dataset.transition || ''; + }); + }); + } + document.body.style.paddingRight = ''; + }); +} diff --git a/packages/@core/ui-kit/layout-ui/src/vben-layout.vue b/packages/@core/ui-kit/layout-ui/src/vben-layout.vue index 67c7278a..09350775 100644 --- a/packages/@core/ui-kit/layout-ui/src/vben-layout.vue +++ b/packages/@core/ui-kit/layout-ui/src/vben-layout.vue @@ -4,6 +4,7 @@ import type { VbenLayoutProps } from './vben-layout'; import type { CSSProperties } from 'vue'; import { computed, ref, watch } from 'vue'; +import { SCROLL_FIXED_CLASS } from '@vben-core/composables'; import { Menu } from '@vben-core/icons'; import { VbenIconButton } from '@vben-core/shadcn-ui'; @@ -478,9 +479,12 @@ function handleHeaderToggle() { class="flex flex-1 flex-col overflow-hidden transition-all duration-300 ease-in" >
diff --git a/packages/@core/ui-kit/popup-ui/src/drawer/drawer-api.ts b/packages/@core/ui-kit/popup-ui/src/drawer/drawer-api.ts index 499d1318..f859350f 100644 --- a/packages/@core/ui-kit/popup-ui/src/drawer/drawer-api.ts +++ b/packages/@core/ui-kit/popup-ui/src/drawer/drawer-api.ts @@ -39,6 +39,7 @@ export class DrawerApi { isOpen: false, loading: false, modal: true, + openAutoFocus: false, showCancelButton: true, showConfirmButton: true, title: '', diff --git a/packages/@core/ui-kit/popup-ui/src/drawer/drawer.ts b/packages/@core/ui-kit/popup-ui/src/drawer/drawer.ts index c3db0606..df179830 100644 --- a/packages/@core/ui-kit/popup-ui/src/drawer/drawer.ts +++ b/packages/@core/ui-kit/popup-ui/src/drawer/drawer.ts @@ -52,6 +52,10 @@ export interface DrawerProps { * @default true */ modal?: boolean; + /** + * 是否自动聚焦 + */ + openAutoFocus?: boolean; /** * 是否显示取消按钮 * @default true diff --git a/packages/@core/ui-kit/popup-ui/src/drawer/drawer.vue b/packages/@core/ui-kit/popup-ui/src/drawer/drawer.vue index 4c441d98..025ca742 100644 --- a/packages/@core/ui-kit/popup-ui/src/drawer/drawer.vue +++ b/packages/@core/ui-kit/popup-ui/src/drawer/drawer.vue @@ -51,6 +51,7 @@ const { footer: showFooter, loading: showLoading, modal, + openAutoFocus, showCancelButton, showConfirmButton, title, @@ -87,10 +88,21 @@ function pointerDownOutside(e: Event) { e.preventDefault(); } } + +function handerOpenAutoFocus(e: Event) { + if (!openAutoFocus.value) { + e?.preventDefault(); + } +} + +function handleFocusOutside(e: Event) { + e.preventDefault(); + e.stopPropagation(); +}