+
diff --git a/docs/.vitepress/config/plugins/demo-preview.ts b/docs/.vitepress/config/plugins/demo-preview.ts
index 03b1698ca..ba3863b0b 100644
--- a/docs/.vitepress/config/plugins/demo-preview.ts
+++ b/docs/.vitepress/config/plugins/demo-preview.ts
@@ -84,7 +84,7 @@ export const demoPreviewPlugin = (md: MarkdownRenderer) => {
return '';
}
const firstString = 'index.vue';
- childFiles = childFiles.sort((a, b) => {
+ childFiles = childFiles.toSorted((a, b) => {
if (a === firstString) return -1;
if (b === firstString) return 1;
return a.localeCompare(b, 'en', { sensitivity: 'base' });
diff --git a/docs/src/components/common-ui/vben-form.md b/docs/src/components/common-ui/vben-form.md
index 48772bfac..30cbec448 100644
--- a/docs/src/components/common-ui/vben-form.md
+++ b/docs/src/components/common-ui/vben-form.md
@@ -335,6 +335,7 @@ useVbenForm 返回的第二个参数,是一个对象,包含了一些表单
| handleReset | 表单重置回调 | `(values: Record
,) => Promise \| void` | - |
| handleSubmit | 表单提交回调 | `(values: Record,) => Promise \| void` | - |
| handleValuesChange | 表单值变化回调 | `(values: Record, fieldsChanged: string[]) => void` | - |
+| handleCollapsedChange | 表单收起展开状态变化回调 | `(collapsed: boolean) => void` | - |
| actionButtonsReverse | 调换操作按钮位置 | `boolean` | `false` |
| resetButtonOptions | 重置按钮组件参数 | `ActionButtonOptions` | - |
| submitButtonOptions | 提交按钮组件参数 | `ActionButtonOptions` | - |
diff --git a/docs/src/demos/vben-drawer/auto-height/drawer.vue b/docs/src/demos/vben-drawer/auto-height/drawer.vue
index 9ab433ccb..1b09723c2 100644
--- a/docs/src/demos/vben-drawer/auto-height/drawer.vue
+++ b/docs/src/demos/vben-drawer/auto-height/drawer.vue
@@ -32,7 +32,7 @@ function handleUpdate(len: number) {
{{ item }}
diff --git a/docs/src/demos/vben-modal/auto-height/modal.vue b/docs/src/demos/vben-modal/auto-height/modal.vue
index 8757d5ef0..e270df1ae 100644
--- a/docs/src/demos/vben-modal/auto-height/modal.vue
+++ b/docs/src/demos/vben-modal/auto-height/modal.vue
@@ -32,7 +32,7 @@ function handleUpdate(len: number) {
{{ item }}
diff --git a/internal/lint-configs/commitlint-config/index.mjs b/internal/lint-configs/commitlint-config/index.mjs
index 3d854399f..36c3b09ac 100644
--- a/internal/lint-configs/commitlint-config/index.mjs
+++ b/internal/lint-configs/commitlint-config/index.mjs
@@ -21,7 +21,7 @@ const scopeComplete = execSync('git status --porcelain || true')
.trim()
.split('\n')
.find((r) => ~r.indexOf('M src'))
- ?.replace(/(\/)/g, '%%')
+ ?.replaceAll(/(\/)/g, '%%')
?.match(/src%%((\w|-)*)/)?.[1]
?.replace(/s$/, '');
diff --git a/internal/lint-configs/eslint-config/src/configs/command.ts b/internal/lint-configs/eslint-config/src/configs/command.ts
index 67651b233..d0c902de2 100644
--- a/internal/lint-configs/eslint-config/src/configs/command.ts
+++ b/internal/lint-configs/eslint-config/src/configs/command.ts
@@ -3,7 +3,6 @@ import createCommand from 'eslint-plugin-command/config';
export async function command() {
return [
{
- // @ts-expect-error - no types
...createCommand(),
},
];
diff --git a/internal/lint-configs/eslint-config/src/configs/node.ts b/internal/lint-configs/eslint-config/src/configs/node.ts
index fa960d85e..f8f266436 100644
--- a/internal/lint-configs/eslint-config/src/configs/node.ts
+++ b/internal/lint-configs/eslint-config/src/configs/node.ts
@@ -35,7 +35,7 @@ export async function node(): Promise {
'error',
{
ignores: [],
- version: '>=18.0.0',
+ version: '>=20.12.0',
},
],
'n/prefer-global/buffer': ['error', 'never'],
diff --git a/internal/lint-configs/eslint-config/src/configs/perfectionist.ts b/internal/lint-configs/eslint-config/src/configs/perfectionist.ts
index 136bfa332..4a7d12fe9 100644
--- a/internal/lint-configs/eslint-config/src/configs/perfectionist.ts
+++ b/internal/lint-configs/eslint-config/src/configs/perfectionist.ts
@@ -4,7 +4,6 @@ import { interopDefault } from '../util';
export async function perfectionist(): Promise {
const perfectionistPlugin = await interopDefault(
- // @ts-expect-error - no types
import('eslint-plugin-perfectionist'),
);
diff --git a/internal/lint-configs/eslint-config/src/configs/turbo.ts b/internal/lint-configs/eslint-config/src/configs/turbo.ts
index 9f6bf75be..bcc27eb69 100644
--- a/internal/lint-configs/eslint-config/src/configs/turbo.ts
+++ b/internal/lint-configs/eslint-config/src/configs/turbo.ts
@@ -4,7 +4,6 @@ import { interopDefault } from '../util';
export async function turbo(): Promise {
const [pluginTurbo] = await Promise.all([
- // @ts-expect-error - no types
interopDefault(import('eslint-config-turbo')),
] as const);
diff --git a/internal/lint-configs/eslint-config/src/configs/typescript.ts b/internal/lint-configs/eslint-config/src/configs/typescript.ts
index cff9aa4bc..2f6f97650 100644
--- a/internal/lint-configs/eslint-config/src/configs/typescript.ts
+++ b/internal/lint-configs/eslint-config/src/configs/typescript.ts
@@ -5,7 +5,6 @@ import { interopDefault } from '../util';
export async function typescript(): Promise {
const [pluginTs, parserTs] = await Promise.all([
interopDefault(import('@typescript-eslint/eslint-plugin')),
- // @ts-expect-error missing types
interopDefault(import('@typescript-eslint/parser')),
] as const);
@@ -27,11 +26,11 @@ export async function typescript(): Promise {
},
},
plugins: {
- '@typescript-eslint': pluginTs,
+ '@typescript-eslint': pluginTs as any,
},
rules: {
- ...pluginTs.configs['eslint-recommended'].overrides?.[0].rules,
- ...pluginTs.configs.strict.rules,
+ ...pluginTs.configs['eslint-recommended']?.overrides?.[0]?.rules,
+ ...pluginTs.configs.strict?.rules,
'@typescript-eslint/ban-ts-comment': [
'error',
{
diff --git a/internal/lint-configs/eslint-config/src/configs/vue.ts b/internal/lint-configs/eslint-config/src/configs/vue.ts
index a64c55aff..5db72992d 100644
--- a/internal/lint-configs/eslint-config/src/configs/vue.ts
+++ b/internal/lint-configs/eslint-config/src/configs/vue.ts
@@ -6,7 +6,6 @@ export async function vue(): Promise {
const [pluginVue, parserVue, parserTs] = await Promise.all([
interopDefault(import('eslint-plugin-vue')),
interopDefault(import('vue-eslint-parser')),
- // @ts-expect-error missing types
interopDefault(import('@typescript-eslint/parser')),
] as const);
diff --git a/internal/lint-configs/eslint-config/tsconfig.json b/internal/lint-configs/eslint-config/tsconfig.json
index b2ec3b61e..dbd3bcc8d 100644
--- a/internal/lint-configs/eslint-config/tsconfig.json
+++ b/internal/lint-configs/eslint-config/tsconfig.json
@@ -1,6 +1,9 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@vben/tsconfig/node.json",
+ "compilerOptions": {
+ "moduleResolution": "bundler"
+ },
"include": ["src"],
"exclude": ["node_modules"]
}
diff --git a/internal/tailwind-config/package.json b/internal/tailwind-config/package.json
index 07b26be4f..269558cdd 100644
--- a/internal/tailwind-config/package.json
+++ b/internal/tailwind-config/package.json
@@ -53,6 +53,7 @@
"@tailwindcss/typography": "catalog:",
"autoprefixer": "catalog:",
"cssnano": "catalog:",
+ "jiti": "catalog:",
"postcss": "catalog:",
"postcss-antd-fixes": "catalog:",
"postcss-import": "catalog:",
diff --git a/internal/vite-config/src/config/application.ts b/internal/vite-config/src/config/application.ts
index 8b3a4fcc6..298cea070 100644
--- a/internal/vite-config/src/config/application.ts
+++ b/internal/vite-config/src/config/application.ts
@@ -114,7 +114,7 @@ function createCssOptions(injectGlobalScss = true): CSSOptions {
}
return content;
},
- api: 'modern',
+ // api: 'modern',
importers: [new NodePackageImporter()],
},
}
diff --git a/package.json b/package.json
index 8229c713f..cb63ee096 100644
--- a/package.json
+++ b/package.json
@@ -98,7 +98,7 @@
"node": ">=20.12.0",
"pnpm": ">=10.14.0"
},
- "packageManager": "pnpm@10.14.0",
+ "packageManager": "pnpm@10.22.0",
"pnpm": {
"peerDependencyRules": {
"allowedVersions": {
@@ -110,6 +110,7 @@
"@ctrl/tinycolor": "catalog:",
"clsx": "catalog:",
"esbuild": "0.25.3",
+ "jiti": "catalog:",
"pinia": "catalog:",
"vue": "catalog:"
},
diff --git a/packages/@core/base/design/src/design-tokens/index.ts b/packages/@core/base/design/src/design-tokens/index.ts
index 2d031d81f..4bf1467d3 100644
--- a/packages/@core/base/design/src/design-tokens/index.ts
+++ b/packages/@core/base/design/src/design-tokens/index.ts
@@ -1,4 +1,2 @@
import './default.css';
import './dark.css';
-
-export {};
diff --git a/packages/@core/base/design/src/index.ts b/packages/@core/base/design/src/index.ts
index d7c05340c..952caef7a 100644
--- a/packages/@core/base/design/src/index.ts
+++ b/packages/@core/base/design/src/index.ts
@@ -4,5 +4,3 @@ import './css/global.css';
import './css/transition.css';
import './css/nprogress.css';
import './css/ui.css';
-
-export {};
diff --git a/packages/@core/base/shared/package.json b/packages/@core/base/shared/package.json
index 495de4519..4a1c77dc4 100644
--- a/packages/@core/base/shared/package.json
+++ b/packages/@core/base/shared/package.json
@@ -86,11 +86,9 @@
"crypto-js": "catalog:",
"dayjs": "catalog:",
"defu": "catalog:",
+ "es-toolkit": "catalog:",
"jsencrypt": "catalog:",
"lodash.clonedeep": "catalog:",
- "lodash.get": "catalog:",
- "lodash.isequal": "catalog:",
- "lodash.set": "catalog:",
"nprogress": "catalog:",
"tailwind-merge": "catalog:",
"theme-colors": "catalog:"
diff --git a/packages/@core/base/shared/src/utils/index.ts b/packages/@core/base/shared/src/utils/index.ts
index 2a545447d..60554745b 100644
--- a/packages/@core/base/shared/src/utils/index.ts
+++ b/packages/@core/base/shared/src/utils/index.ts
@@ -20,7 +20,6 @@ export * from './upload';
export * from './util';
export * from './uuid'; // add by 芋艿:从 vben2.0 复制
export * from './window';
+export { get, isEqual, set } from 'es-toolkit/compat';
+// export { cloneDeep } from 'es-toolkit/object';
export { default as cloneDeep } from 'lodash.clonedeep';
-export { default as get } from 'lodash.get';
-export { default as isEqual } from 'lodash.isequal';
-export { default as set } from 'lodash.set';
diff --git a/packages/@core/preferences/src/preferences.ts b/packages/@core/preferences/src/preferences.ts
index 23c5f8bef..9ac8fb054 100644
--- a/packages/@core/preferences/src/preferences.ts
+++ b/packages/@core/preferences/src/preferences.ts
@@ -221,12 +221,8 @@ class PreferenceManager {
const dom = document.documentElement;
const COLOR_WEAK = 'invert-mode';
const COLOR_GRAY = 'grayscale-mode';
- colorWeakMode
- ? dom.classList.add(COLOR_WEAK)
- : dom.classList.remove(COLOR_WEAK);
- colorGrayMode
- ? dom.classList.add(COLOR_GRAY)
- : dom.classList.remove(COLOR_GRAY);
+ dom.classList.toggle(COLOR_WEAK, colorWeakMode);
+ dom.classList.toggle(COLOR_GRAY, colorGrayMode);
}
}
}
diff --git a/packages/@core/ui-kit/form-ui/src/components/form-actions.vue b/packages/@core/ui-kit/form-ui/src/components/form-actions.vue
index 42101c124..36b1caa0c 100644
--- a/packages/@core/ui-kit/form-ui/src/components/form-actions.vue
+++ b/packages/@core/ui-kit/form-ui/src/components/form-actions.vue
@@ -47,7 +47,7 @@ async function handleSubmit(e: Event) {
return;
}
- const values = toRaw(await props.formApi.getValues());
+ const values = toRaw(await props.formApi.getValues()) ?? {};
await props.handleSubmit?.(values);
}
@@ -56,7 +56,7 @@ async function handleReset(e: Event) {
e?.stopPropagation();
const props = unref(rootProps);
- const values = toRaw(await props.formApi?.getValues());
+ const values = toRaw(await props.formApi?.getValues()) ?? {};
if (isFunction(props.handleReset)) {
await props.handleReset?.(values);
diff --git a/packages/@core/ui-kit/form-ui/src/form-api.ts b/packages/@core/ui-kit/form-ui/src/form-api.ts
index f7f01be8f..40b9bd46e 100644
--- a/packages/@core/ui-kit/form-ui/src/form-api.ts
+++ b/packages/@core/ui-kit/form-ui/src/form-api.ts
@@ -36,6 +36,7 @@ function getDefaultState(): VbenFormProps {
handleReset: undefined,
handleSubmit: undefined,
handleValuesChange: undefined,
+ handleCollapsedChange: undefined,
layout: 'horizontal',
resetButtonOptions: {},
schema: [],
diff --git a/packages/@core/ui-kit/form-ui/src/form-render/form-field.vue b/packages/@core/ui-kit/form-ui/src/form-render/form-field.vue
index b308b251e..94d6f3331 100644
--- a/packages/@core/ui-kit/form-ui/src/form-render/form-field.vue
+++ b/packages/@core/ui-kit/form-ui/src/form-render/form-field.vue
@@ -341,7 +341,7 @@ onUnmounted(() => {
:is="FieldComponent"
ref="fieldComponentRef"
:class="{
- 'border-destructive focus:border-destructive hover:border-destructive/80 focus:shadow-[0_0_0_2px_rgba(255,38,5,0.06)]':
+ 'border-destructive hover:border-destructive/80 focus:border-destructive focus:shadow-[0_0_0_2px_rgba(255,38,5,0.06)]':
isInValid,
}"
v-bind="createComponentProps(slotProps)"
@@ -369,7 +369,7 @@ onUnmounted(() => {
diff --git a/packages/@core/ui-kit/form-ui/src/form-render/form-label.vue b/packages/@core/ui-kit/form-ui/src/form-render/form-label.vue
index 9af4c133d..44d002d9b 100644
--- a/packages/@core/ui-kit/form-ui/src/form-render/form-label.vue
+++ b/packages/@core/ui-kit/form-ui/src/form-render/form-label.vue
@@ -21,7 +21,7 @@ const props = defineProps();
- *
+ *
diff --git a/packages/@core/ui-kit/form-ui/src/types.ts b/packages/@core/ui-kit/form-ui/src/types.ts
index fd80c9e72..8cfcaa4bb 100644
--- a/packages/@core/ui-kit/form-ui/src/types.ts
+++ b/packages/@core/ui-kit/form-ui/src/types.ts
@@ -381,6 +381,10 @@ export interface VbenFormProps<
* 表单字段映射
*/
fieldMappingTime?: FieldMappingTime;
+ /**
+ * 表单收起展开状态变化回调
+ */
+ handleCollapsedChange?: (collapsed: boolean) => void;
/**
* 表单重置回调
*/
diff --git a/packages/@core/ui-kit/form-ui/src/use-form-context.ts b/packages/@core/ui-kit/form-ui/src/use-form-context.ts
index 4ef182edf..e95c87b96 100644
--- a/packages/@core/ui-kit/form-ui/src/use-form-context.ts
+++ b/packages/@core/ui-kit/form-ui/src/use-form-context.ts
@@ -13,7 +13,7 @@ import { useForm } from 'vee-validate';
import { object, ZodIntersection, ZodNumber, ZodObject, ZodString } from 'zod';
import { getDefaultsForSchema } from 'zod-defaults';
-type ExtendFormProps = VbenFormProps & { formApi: ExtendedFormApi };
+type ExtendFormProps = VbenFormProps & { formApi?: ExtendedFormApi };
export const [injectFormProps, provideFormProps] =
createContext<[ComputedRef | ExtendFormProps, FormActions]>(
diff --git a/packages/@core/ui-kit/form-ui/src/vben-form.vue b/packages/@core/ui-kit/form-ui/src/vben-form.vue
index 260e75cdb..f3ba37f07 100644
--- a/packages/@core/ui-kit/form-ui/src/vben-form.vue
+++ b/packages/@core/ui-kit/form-ui/src/vben-form.vue
@@ -40,7 +40,9 @@ const { delegatedSlots, form } = useFormInitial(props);
provideFormProps([props, form]);
const handleUpdateCollapsed = (value: boolean) => {
- currentCollapsed.value = !!value;
+ currentCollapsed.value = value;
+ // 触发收起展开状态变化回调
+ props.handleCollapsedChange?.(value);
};
watchEffect(() => {
diff --git a/packages/@core/ui-kit/form-ui/src/vben-use-form.vue b/packages/@core/ui-kit/form-ui/src/vben-use-form.vue
index 3e7b00b6c..e93867257 100644
--- a/packages/@core/ui-kit/form-ui/src/vben-use-form.vue
+++ b/packages/@core/ui-kit/form-ui/src/vben-use-form.vue
@@ -25,7 +25,7 @@ import {
} from './use-form-context';
// 通过 extends 会导致热更新卡死,所以重复写了一遍
interface Props extends VbenFormProps {
- formApi: ExtendedFormApi;
+ formApi?: ExtendedFormApi;
}
const props = defineProps();
@@ -44,11 +44,13 @@ provideComponentRefMap(componentRefMap);
props.formApi?.mount?.(form, componentRefMap);
const handleUpdateCollapsed = (value: boolean) => {
- props.formApi?.setState({ collapsed: !!value });
+ props.formApi?.setState({ collapsed: value });
+ // 触发收起展开状态变化回调
+ forward.value.handleCollapsedChange?.(value);
};
function handleKeyDownEnter(event: KeyboardEvent) {
- if (!state.value.submitOnEnter || !forward.value.formApi?.isMounted) {
+ if (!state?.value.submitOnEnter || !forward.value.formApi?.isMounted) {
return;
}
// 如果是 textarea 不阻止默认行为,否则会导致无法换行。
@@ -58,11 +60,11 @@ function handleKeyDownEnter(event: KeyboardEvent) {
}
event.preventDefault();
- forward.value.formApi.validateAndSubmitForm();
+ forward.value.formApi?.validateAndSubmitForm();
}
const handleValuesChangeDebounced = useDebounceFn(async () => {
- state.value.submitOnChange && forward.value.formApi?.validateAndSubmitForm();
+ state?.value.submitOnChange && forward.value.formApi?.validateAndSubmitForm();
}, 300);
const valuesCache: Recordable = {};
@@ -74,7 +76,7 @@ onMounted(async () => {
() => form.values,
async (newVal) => {
if (forward.value.handleValuesChange) {
- const fields = state.value.schema?.map((item) => {
+ const fields = state?.value.schema?.map((item) => {
return item.fieldName;
});
@@ -91,8 +93,9 @@ onMounted(async () => {
if (changedFields.length > 0) {
// 调用handleValuesChange回调,传入所有表单值的深拷贝和变更的字段列表
+ const values = await forward.value.formApi?.getValues();
forward.value.handleValuesChange(
- cloneDeep(await forward.value.formApi.getValues()),
+ cloneDeep(values ?? {}) as Record,
changedFields,
);
}
@@ -109,7 +112,7 @@ onMounted(async () => {
diff --git a/packages/@core/ui-kit/shadcn-ui/src/components/back-top/back-top.vue b/packages/@core/ui-kit/shadcn-ui/src/components/back-top/back-top.vue
index 1f8b0bc77..8da6cde42 100644
--- a/packages/@core/ui-kit/shadcn-ui/src/components/back-top/back-top.vue
+++ b/packages/@core/ui-kit/shadcn-ui/src/components/back-top/back-top.vue
@@ -32,7 +32,7 @@ const { handleClick, visible } = useBackTop(props);