diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 154922b3..b82fee1a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,7 +20,13 @@ permissions: jobs: post-update: # if: ${{ github.actor == 'dependabot[bot]' }} - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: + - ubuntu-latest + # - macos-latest + - windows-latest steps: - name: Checkout code uses: actions/checkout@v4 diff --git a/packages/@core/base/design/src/css/global.css b/packages/@core/base/design/src/css/global.css index 9fb8c9c7..f9810e72 100644 --- a/packages/@core/base/design/src/css/global.css +++ b/packages/@core/base/design/src/css/global.css @@ -32,9 +32,13 @@ body, html { @apply size-full overscroll-none; + + /* scrollbar-gutter: stable; */ } body { + @apply !pointer-events-auto; + min-height: 100vh; /* overflow: overlay; */ @@ -90,6 +94,7 @@ } /* 只有非mac下才进行调整,mac下使用默认滚动条 */ + html:not([data-platform='macOs']) { ::-webkit-scrollbar { @apply h-[10px] w-[10px]; diff --git a/packages/@core/base/shared/package.json b/packages/@core/base/shared/package.json index 0f5c7662..b12aff77 100644 --- a/packages/@core/base/shared/package.json +++ b/packages/@core/base/shared/package.json @@ -71,6 +71,7 @@ "dependencies": { "@ctrl/tinycolor": "^4.1.0", "@tanstack/vue-store": "^0.5.5", + "@vue/reactivity": "^3.5.4", "@vue/shared": "^3.5.4", "clsx": "^2.1.1", "defu": "^6.1.4", diff --git a/packages/@core/base/shared/src/utils/index.ts b/packages/@core/base/shared/src/utils/index.ts index e5526edf..ef180cf0 100644 --- a/packages/@core/base/shared/src/utils/index.ts +++ b/packages/@core/base/shared/src/utils/index.ts @@ -5,6 +5,7 @@ export * from './inference'; export * from './letter'; export * from './merge'; export * from './nprogress'; +export * from './reactivity'; export * from './state-handler'; export * from './to'; export * from './tree'; diff --git a/packages/@core/base/shared/src/utils/reactivity.ts b/packages/@core/base/shared/src/utils/reactivity.ts new file mode 100644 index 00000000..e2d66c38 --- /dev/null +++ b/packages/@core/base/shared/src/utils/reactivity.ts @@ -0,0 +1,26 @@ +import { isProxy, isReactive, isRef, toRaw } from '@vue/reactivity'; + +function deepToRaw>(sourceObj: T): T { + const objectIterator = (input: any): any => { + if (Array.isArray(input)) { + return input.map((item) => objectIterator(item)); + } + if (isRef(input) || isReactive(input) || isProxy(input)) { + return objectIterator(toRaw(input)); + } + if (input && typeof input === 'object') { + const result = {} as T; + for (const key in input) { + if (Object.prototype.hasOwnProperty.call(input, key)) { + result[key as keyof T] = objectIterator(input[key]); + } + } + return result; + } + return input; + }; + + return objectIterator(sourceObj); +} + +export { deepToRaw }; diff --git a/packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts b/packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts index e664c52f..eaa0cf84 100644 --- a/packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts +++ b/packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts @@ -41,6 +41,7 @@ export class ModalApi { isOpen: false, loading: false, modal: true, + openAutoFocus: false, showCancelButton: true, showConfirmButton: true, title: '', diff --git a/packages/@core/ui-kit/popup-ui/src/modal/modal.ts b/packages/@core/ui-kit/popup-ui/src/modal/modal.ts index 3ccbacd4..8a5bbf31 100644 --- a/packages/@core/ui-kit/popup-ui/src/modal/modal.ts +++ b/packages/@core/ui-kit/popup-ui/src/modal/modal.ts @@ -75,6 +75,10 @@ export interface ModalProps { * @default true */ modal?: boolean; + /** + * 是否自动聚焦 + */ + openAutoFocus?: boolean; /** * 是否显示取消按钮 * @default true diff --git a/packages/@core/ui-kit/popup-ui/src/modal/modal.vue b/packages/@core/ui-kit/popup-ui/src/modal/modal.vue index 8a5cc4a8..89ea4128 100644 --- a/packages/@core/ui-kit/popup-ui/src/modal/modal.vue +++ b/packages/@core/ui-kit/popup-ui/src/modal/modal.vue @@ -68,6 +68,7 @@ const { header, loading: showLoading, modal, + openAutoFocus, showCancelButton, showConfirmButton, title, @@ -133,6 +134,13 @@ function escapeKeyDown(e: KeyboardEvent) { e.preventDefault(); } } + +function handerOpenAutoFocus(e: Event) { + if (!openAutoFocus.value) { + e?.preventDefault(); + } +} + // pointer-down-outside function pointerDownOutside(e: Event) { const target = e.target as HTMLElement; @@ -166,6 +174,7 @@ function pointerDownOutside(e: Event) { close-class="top-3" @escape-key-down="escapeKeyDown" @interact-outside="interactOutside" + @open-auto-focus="handerOpenAutoFocus" @pointer-down-outside="pointerDownOutside" > { }); const tabsView = computed((): TabConfig[] => { - return props.tabs.map((tab) => { + return props.tabs.map((_tab) => { + const tab = deepToRaw(_tab); return { ...tab, affixTab: !!tab.meta?.affixTab, diff --git a/packages/@core/ui-kit/tabs-ui/src/components/tabs/tabs.vue b/packages/@core/ui-kit/tabs-ui/src/components/tabs/tabs.vue index af9842fb..96326e8d 100644 --- a/packages/@core/ui-kit/tabs-ui/src/components/tabs/tabs.vue +++ b/packages/@core/ui-kit/tabs-ui/src/components/tabs/tabs.vue @@ -7,6 +7,7 @@ import { computed } from 'vue'; import { Pin, X } from '@vben-core/icons'; import { VbenContextMenu, VbenIcon } from '@vben-core/shadcn-ui'; +import { deepToRaw } from '@vben-core/shared/utils'; interface Props extends TabsProps {} @@ -46,7 +47,8 @@ const typeWithClass = computed(() => { }); const tabsView = computed((): TabConfig[] => { - return props.tabs.map((tab) => { + return props.tabs.map((_tab) => { + const tab = deepToRaw(_tab); return { ...tab, affixTab: !!tab.meta?.affixTab, 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 258484b6..aeef4e19 100644 --- a/packages/effects/common-ui/src/ui/authentication/code-login.vue +++ b/packages/effects/common-ui/src/ui/authentication/code-login.vue @@ -22,6 +22,18 @@ interface Props { * @zh_CN 登陆路径 */ loginPath?: string; + /** + * @zh_CN 标题 + */ + title?: string; + /** + * @zh_CN 描述 + */ + subTitle?: string; + /** + * @zh_CN 按钮文本 + */ + submitButtonText?: string; } defineOptions({ @@ -31,6 +43,9 @@ defineOptions({ const props = withDefaults(defineProps(), { loading: false, loginPath: '/auth/login', + submitButtonText: '', + subTitle: '', + title: '', }); const emit = defineEmits<{ @@ -69,16 +84,22 @@ function goToLogin() {