diff --git a/apps/web-antd/src/router/index.ts b/apps/web-antd/src/router/index.ts index 313b372b..48402303 100644 --- a/apps/web-antd/src/router/index.ts +++ b/apps/web-antd/src/router/index.ts @@ -19,7 +19,12 @@ const router = createRouter({ : createWebHistory(import.meta.env.VITE_BASE), // 应该添加到路由的初始路由列表。 routes, - scrollBehavior: () => ({ left: 0, top: 0 }), + scrollBehavior: (to, _from, savedPosition) => { + if (savedPosition) { + return savedPosition; + } + return to.hash ? { behavior: 'smooth', el: to.hash } : { left: 0, top: 0 }; + }, // 是否应该禁止尾部斜杠。 // strict: true, }); diff --git a/apps/web-ele/src/router/index.ts b/apps/web-ele/src/router/index.ts index 313b372b..48402303 100644 --- a/apps/web-ele/src/router/index.ts +++ b/apps/web-ele/src/router/index.ts @@ -19,7 +19,12 @@ const router = createRouter({ : createWebHistory(import.meta.env.VITE_BASE), // 应该添加到路由的初始路由列表。 routes, - scrollBehavior: () => ({ left: 0, top: 0 }), + scrollBehavior: (to, _from, savedPosition) => { + if (savedPosition) { + return savedPosition; + } + return to.hash ? { behavior: 'smooth', el: to.hash } : { left: 0, top: 0 }; + }, // 是否应该禁止尾部斜杠。 // strict: true, }); diff --git a/apps/web-naive/src/router/index.ts b/apps/web-naive/src/router/index.ts index 313b372b..48402303 100644 --- a/apps/web-naive/src/router/index.ts +++ b/apps/web-naive/src/router/index.ts @@ -19,7 +19,12 @@ const router = createRouter({ : createWebHistory(import.meta.env.VITE_BASE), // 应该添加到路由的初始路由列表。 routes, - scrollBehavior: () => ({ left: 0, top: 0 }), + scrollBehavior: (to, _from, savedPosition) => { + if (savedPosition) { + return savedPosition; + } + return to.hash ? { behavior: 'smooth', el: to.hash } : { left: 0, top: 0 }; + }, // 是否应该禁止尾部斜杠。 // strict: true, }); diff --git a/docs/src/en/guide/essentials/development.md b/docs/src/en/guide/essentials/development.md index e8628b96..1aa4cbd1 100644 --- a/docs/src/en/guide/essentials/development.md +++ b/docs/src/en/guide/essentials/development.md @@ -55,15 +55,15 @@ The execution command is: `pnpm run [script]` or `npm run [script]`. // Build a local Docker image "build:docker": "./build-local-docker-image.sh", // Build the web-antd application separately - "build:antd": "pnpm run build --filter=@vben/web-antd", + "build:antd": "pnpm -F @vben/web-antd run build", // Build the documentation separately - "build:docs": "pnpm run build --filter=@vben/docs", + "build:docs": "pnpm -F @vben/docs run build", // Build the web-ele application separately - "build:ele": "pnpm run build --filter=@vben/web-ele", + "build:ele": "pnpm -F @vben/web-ele run build", // Build the web-naive application separately - "build:naive": "pnpm run build --filter=@vben/naive", + "build:naive": "pnpm -F @vben/web-naive run build", // Build the playground application separately - "build:play": "pnpm run build --filter=@vben/playground", + "build:play": "pnpm -F @vben/playground run build", // Changeset version management "changeset": "pnpm exec changeset", // Check for various issues in the project diff --git a/docs/src/en/guide/introduction/thin.md b/docs/src/en/guide/introduction/thin.md index a310ef39..4284339b 100644 --- a/docs/src/en/guide/introduction/thin.md +++ b/docs/src/en/guide/introduction/thin.md @@ -52,11 +52,11 @@ After slimming down, you may need to adjust commands according to your project. ```json { "scripts": { - "build:antd": "pnpm run build --filter=@vben/web-antd", - "build:docs": "pnpm run build --filter=@vben/docs", - "build:ele": "pnpm run build --filter=@vben/web-ele", - "build:naive": "pnpm run build --filter=@vben/web-naive", - "build:play": "pnpm run build --filter=@vben/playground", + "build:antd": "pnpm -F @vben/web-antd run build", + "build:docs": "pnpm -F @vben/docs run build", + "build:ele": "pnpm -F @vben/web-ele run build", + "build:naive": "pnpm -F @vben/web-naive run build", + "build:play": "pnpm -F @vben/playground run build", "dev:antd": "pnpm -F @vben/web-antd run dev", "dev:docs": "pnpm -F @vben/docs run dev", "dev:ele": "pnpm -F @vben/web-ele run dev", diff --git a/docs/src/guide/essentials/development.md b/docs/src/guide/essentials/development.md index ff731a2d..e19ac458 100644 --- a/docs/src/guide/essentials/development.md +++ b/docs/src/guide/essentials/development.md @@ -55,15 +55,15 @@ npm 脚本是项目常见的配置,用于执行一些常见的任务,比如 // 构建本地 docker 镜像 "build:docker": "./build-local-docker-image.sh", // 单独构建 web-antd 应用 - "build:antd": "pnpm run build --filter=@vben/web-antd", + "build:antd": "pnpm -F @vben/web-antd run build", // 单独构建文档 - "build:docs": "pnpm run build --filter=@vben/docs", + "build:docs": "pnpm -F @vben/docs run build", // 单独构建 web-ele 应用 - "build:ele": "pnpm run build --filter=@vben/web-ele", + "build:ele": "pnpm -F @vben/web-ele run build", // 单独构建 web-naive 应用 - "build:naive": "pnpm run build --filter=@vben/naive", + "build:naive": "pnpm -F @vben/web-naive run build", // 单独构建 playground 应用 - "build:play": "pnpm run build --filter=@vben/playground", + "build:play": "pnpm -F @vben/playground run build", // changeset 版本管理 "changeset": "pnpm exec changeset", // 检查项目各种问题 diff --git a/docs/src/guide/introduction/thin.md b/docs/src/guide/introduction/thin.md index 7df3c9f8..c78b586e 100644 --- a/docs/src/guide/introduction/thin.md +++ b/docs/src/guide/introduction/thin.md @@ -52,11 +52,11 @@ pnpm install ```json { "scripts": { - "build:antd": "pnpm run build --filter=@vben/web-antd", - "build:docs": "pnpm run build --filter=@vben/docs", - "build:ele": "pnpm run build --filter=@vben/web-ele", - "build:naive": "pnpm run build --filter=@vben/web-naive", - "build:play": "pnpm run build --filter=@vben/playground", + "build:antd": "pnpm -F @vben/web-antd run build", + "build:docs": "pnpm -F @vben/docs run build", + "build:ele": "pnpm -F @vben/web-ele run build", + "build:naive": "pnpm -F @vben/web-naive run build", + "build:play": "pnpm -F @vben/playground run build", "dev:antd": "pnpm -F @vben/web-antd run dev", "dev:docs": "pnpm -F @vben/docs run dev", "dev:ele": "pnpm -F @vben/web-ele run dev", diff --git a/package.json b/package.json index b6b9f3d8..7b43b8dd 100644 --- a/package.json +++ b/package.json @@ -29,11 +29,11 @@ "build": "cross-env NODE_OPTIONS=--max-old-space-size=8192 turbo build", "build:analyze": "turbo build:analyze", "build:docker": "./build-local-docker-image.sh", - "build:antd": "pnpm run build --filter=@vben/web-antd", - "build:docs": "pnpm run build --filter=@vben/docs", - "build:ele": "pnpm run build --filter=@vben/web-ele", - "build:naive": "pnpm run build --filter=@vben/web-naive", - "build:play": "pnpm run build --filter=@vben/playground", + "build:antd": "pnpm -F @vben/web-antd run build", + "build:docs": "pnpm -F @vben/docs run build", + "build:ele": "pnpm -F @vben/web-ele run build", + "build:naive": "pnpm -F @vben/web-naive run build", + "build:play": "pnpm -F @vben/playground run build", "changeset": "pnpm exec changeset", "check": "pnpm run check:circular && pnpm run check:dep && pnpm run check:type && pnpm check:cspell", "check:circular": "vsh check-circular", diff --git a/packages/@core/base/shared/src/utils/merge.ts b/packages/@core/base/shared/src/utils/merge.ts index 0a8a9ca3..c63733ab 100644 --- a/packages/@core/base/shared/src/utils/merge.ts +++ b/packages/@core/base/shared/src/utils/merge.ts @@ -1 +1 @@ -export { defu as merge } from 'defu'; +export { createDefu as createMerge, defu as merge } from 'defu'; 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 82e615fe..f4c92abd 100644 --- a/packages/@core/ui-kit/form-ui/src/form-api.ts +++ b/packages/@core/ui-kit/form-ui/src/form-api.ts @@ -10,7 +10,19 @@ import type { FormActions, VbenFormProps } from './types'; import { toRaw } from 'vue'; import { Store } from '@vben-core/shared/store'; -import { bindMethods, isFunction, StateHandler } from '@vben-core/shared/utils'; +import { + bindMethods, + createMerge, + isFunction, + StateHandler, +} from '@vben-core/shared/utils'; + +const merge = createMerge((originObj, key, updates) => { + if (Array.isArray(originObj[key]) && Array.isArray(updates)) { + originObj[key] = updates; + return true; + } +}); function getDefaultState(): VbenFormProps { return { @@ -138,9 +150,11 @@ export class FormApi { | Partial, ) { if (isFunction(stateOrFn)) { - this.store.setState(stateOrFn as (prev: VbenFormProps) => VbenFormProps); + this.store.setState((prev) => { + return merge(stateOrFn(prev), prev); + }); } else { - this.store.setState((prev) => ({ ...prev, ...stateOrFn })); + this.store.setState((prev) => merge(stateOrFn, prev)); } } diff --git a/packages/@core/ui-kit/form-ui/src/form-render/expandable.ts b/packages/@core/ui-kit/form-ui/src/form-render/expandable.ts index dcb5b019..a32614b2 100644 --- a/packages/@core/ui-kit/form-ui/src/form-render/expandable.ts +++ b/packages/@core/ui-kit/form-ui/src/form-render/expandable.ts @@ -22,7 +22,7 @@ export function useExpandable(props: FormRenderProps) { for (let index = 1; index <= rows; index++) { maxItem += mapping?.[index] ?? 0; } - return maxItem - 1; + return maxItem - 1 || 1; }); watch( @@ -50,11 +50,11 @@ export function useExpandable(props: FormRenderProps) { return; } // 小屏幕不计算 - if (breakpoints.smaller('sm').value) { - // 保持一行 - rowMapping.value = { 1: 2 }; - return; - } + // if (breakpoints.smaller('sm').value) { + // // 保持一行 + // rowMapping.value = { 1: 2 }; + // return; + // } const formItems = [...wrapperRef.value.children]; 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 1f7b2cb9..ee002592 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 @@ -29,10 +29,12 @@ export class DrawerApi { } = options; const defaultState: DrawerState = { + class: '', closable: true, closeOnClickModal: true, closeOnPressEscape: true, confirmLoading: false, + contentClass: '', footer: true, isOpen: false, loading: false, 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 20c34dd5..c3db0606 100644 --- a/packages/@core/ui-kit/popup-ui/src/drawer/drawer.ts +++ b/packages/@core/ui-kit/popup-ui/src/drawer/drawer.ts @@ -7,6 +7,7 @@ export interface DrawerProps { * 取消按钮文字 */ cancelText?: string; + class?: string; /** * 是否显示右上角的关闭按钮 * @default true @@ -31,6 +32,7 @@ export interface DrawerProps { * 确定按钮文字 */ confirmText?: string; + contentClass?: string; /** * 弹窗描述 */ 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 cc227588..4c441d98 100644 --- a/packages/@core/ui-kit/popup-ui/src/drawer/drawer.vue +++ b/packages/@core/ui-kit/popup-ui/src/drawer/drawer.vue @@ -26,14 +26,10 @@ import { import { cn } from '@vben-core/shared/utils'; interface Props extends DrawerProps { - class?: string; - contentClass?: string; drawerApi?: ExtendedDrawerApi; } const props = withDefaults(defineProps(), { - class: '', - contentClass: '', drawerApi: undefined, }); @@ -44,11 +40,13 @@ const state = props.drawerApi?.useStore?.(); const { cancelText, + class: drawerClass, closable, closeOnClickModal, closeOnPressEscape, confirmLoading, confirmText, + contentClass, description, footer: showFooter, loading: showLoading, @@ -98,7 +96,7 @@ function pointerDownOutside(e: Event) { > (), { - class: '', - contentClass: '', - footerClass: '', - headerClass: '', modalApi: undefined, }); @@ -55,17 +47,21 @@ const state = props.modalApi?.useStore?.(); const { cancelText, centered, + class: modalClass, closable, closeOnClickModal, closeOnPressEscape, confirmLoading, confirmText, + contentClass, description, draggable, footer: showFooter, + footerClass, fullscreen, fullscreenButton, header, + headerClass, loading: showLoading, modal, openAutoFocus, @@ -161,7 +157,7 @@ function pointerDownOutside(e: Event) { :class=" cn( 'border-border left-0 right-0 top-[10vh] mx-auto flex max-h-[80%] w-[520px] flex-col border p-0', - props.class, + modalClass, { 'left-0 top-0 size-full max-h-full !translate-x-0 !translate-y-0': shouldFullscreen, @@ -186,7 +182,7 @@ function pointerDownOutside(e: Event) { hidden: !header, 'cursor-move select-none': shouldDraggable, }, - props.headerClass, + headerClass, ) " > @@ -240,10 +236,7 @@ function pointerDownOutside(e: Event) { v-if="showFooter" ref="footerRef" :class=" - cn( - 'flex-row items-center justify-end border-t p-2', - props.footerClass, - ) + cn('flex-row items-center justify-end border-t p-2', footerClass) " > diff --git a/packages/@core/ui-kit/shadcn-ui/src/components/index.ts b/packages/@core/ui-kit/shadcn-ui/src/components/index.ts index 83ca3239..b4099279 100644 --- a/packages/@core/ui-kit/shadcn-ui/src/components/index.ts +++ b/packages/@core/ui-kit/shadcn-ui/src/components/index.ts @@ -20,6 +20,7 @@ export * from './render-content'; export * from './scrollbar'; export * from './segmented'; export * from './select'; +export * from './spine-text'; export * from './spinner'; export * from './swap'; export * from './tooltip'; diff --git a/packages/@core/ui-kit/shadcn-ui/src/components/spine-text/index.ts b/packages/@core/ui-kit/shadcn-ui/src/components/spine-text/index.ts new file mode 100644 index 00000000..a5298266 --- /dev/null +++ b/packages/@core/ui-kit/shadcn-ui/src/components/spine-text/index.ts @@ -0,0 +1 @@ +export { default as VbenSpineText } from './spine-text.vue'; diff --git a/packages/@core/ui-kit/shadcn-ui/src/components/spine-text/spine-text.vue b/packages/@core/ui-kit/shadcn-ui/src/components/spine-text/spine-text.vue new file mode 100644 index 00000000..ee0f453d --- /dev/null +++ b/packages/@core/ui-kit/shadcn-ui/src/components/spine-text/spine-text.vue @@ -0,0 +1,31 @@ + + diff --git a/packages/effects/common-ui/src/ui/authentication/code-login.vue b/packages/effects/common-ui/src/ui/authentication/code-login.vue index aeef4e19..4501c891 100644 --- a/packages/effects/common-ui/src/ui/authentication/code-login.vue +++ b/packages/effects/common-ui/src/ui/authentication/code-login.vue @@ -96,7 +96,14 @@ function goToLogin() {
- + {{ submitButtonText || $t('common.login') }} diff --git a/packages/effects/common-ui/src/ui/authentication/forget-password.vue b/packages/effects/common-ui/src/ui/authentication/forget-password.vue index 8e92dcb4..c6a7720f 100644 --- a/packages/effects/common-ui/src/ui/authentication/forget-password.vue +++ b/packages/effects/common-ui/src/ui/authentication/forget-password.vue @@ -91,7 +91,13 @@ function goToLogin() {
- + {{ submitButtonText || $t('authentication.sendResetLink') }} diff --git a/packages/effects/common-ui/src/ui/authentication/login.vue b/packages/effects/common-ui/src/ui/authentication/login.vue index 7330b061..a55b71a5 100644 --- a/packages/effects/common-ui/src/ui/authentication/login.vue +++ b/packages/effects/common-ui/src/ui/authentication/login.vue @@ -124,7 +124,14 @@ onMounted(() => { {{ $t('authentication.forgetPassword') }}
- + {{ submitButtonText || $t('common.login') }} diff --git a/packages/effects/common-ui/src/ui/authentication/register.vue b/packages/effects/common-ui/src/ui/authentication/register.vue index febf8dbd..ca745bb5 100644 --- a/packages/effects/common-ui/src/ui/authentication/register.vue +++ b/packages/effects/common-ui/src/ui/authentication/register.vue @@ -92,7 +92,14 @@ function goToLogin() { - + {{ submitButtonText || $t('authentication.signUp') }} diff --git a/playground/src/router/index.ts b/playground/src/router/index.ts index 313b372b..48402303 100644 --- a/playground/src/router/index.ts +++ b/playground/src/router/index.ts @@ -19,7 +19,12 @@ const router = createRouter({ : createWebHistory(import.meta.env.VITE_BASE), // 应该添加到路由的初始路由列表。 routes, - scrollBehavior: () => ({ left: 0, top: 0 }), + scrollBehavior: (to, _from, savedPosition) => { + if (savedPosition) { + return savedPosition; + } + return to.hash ? { behavior: 'smooth', el: to.hash } : { left: 0, top: 0 }; + }, // 是否应该禁止尾部斜杠。 // strict: true, }); diff --git a/playground/src/views/examples/form/custom.vue b/playground/src/views/examples/form/custom.vue index 6bbf0f24..c2756596 100644 --- a/playground/src/views/examples/form/custom.vue +++ b/playground/src/views/examples/form/custom.vue @@ -14,7 +14,7 @@ const [BaseForm] = useVbenForm({ componentProps: { class: 'w-full', }, - labelWidth: 200, + labelClass: 'w-2/6', }, // 使用 tailwindcss grid布局 // 提交函数 diff --git a/playground/src/views/examples/form/dynamic.vue b/playground/src/views/examples/form/dynamic.vue index 948dd629..217d177f 100644 --- a/playground/src/views/examples/form/dynamic.vue +++ b/playground/src/views/examples/form/dynamic.vue @@ -210,7 +210,6 @@ function onSubmit(values: Record) { function handleDelete() { formApi.setState((prev) => { return { - ...prev, schema: prev.schema?.filter((item) => item.fieldName !== 'field7'), }; }); @@ -219,7 +218,6 @@ function handleDelete() { function handleAdd() { formApi.setState((prev) => { return { - ...prev, schema: [ ...(prev?.schema ?? []), { @@ -235,7 +233,6 @@ function handleAdd() { function handleUpdate() { formApi.setState((prev) => { return { - ...prev, schema: prev.schema?.map((item) => { if (item.fieldName === 'field3') { return {