mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-02-02 18:28:40 +08:00
fix: improve the dialog and drawer scrollbar experience, fix internal click failure problems and warnings (#4391)
* fix: improve the dialog and drawer scrollbar experience, fix internal click failure problems and warnings * chore: remove test code
This commit is contained in:
parent
bd6b724aaf
commit
d27e5eeef7
@ -37,10 +37,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@apply !pointer-events-auto;
|
|
||||||
|
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
|
|
||||||
|
/* pointer-events: auto !important; */
|
||||||
|
|
||||||
/* overflow: overlay; */
|
/* overflow: overlay; */
|
||||||
|
|
||||||
/* -webkit-font-smoothing: antialiased; */
|
/* -webkit-font-smoothing: antialiased; */
|
||||||
|
@ -50,3 +50,22 @@ export function getElementVisibleRect(
|
|||||||
width: Math.max(0, right - left),
|
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;
|
||||||
|
}
|
||||||
|
@ -2,6 +2,7 @@ export * from './use-content-style';
|
|||||||
export * from './use-is-mobile';
|
export * from './use-is-mobile';
|
||||||
export * from './use-namespace';
|
export * from './use-namespace';
|
||||||
export * from './use-priority-value';
|
export * from './use-priority-value';
|
||||||
|
export * from './use-scroll-lock';
|
||||||
export * from './use-simple-locale';
|
export * from './use-simple-locale';
|
||||||
export * from './use-sortable';
|
export * from './use-sortable';
|
||||||
export {
|
export {
|
||||||
|
48
packages/@core/composables/src/use-scroll-lock.ts
Normal file
48
packages/@core/composables/src/use-scroll-lock.ts
Normal file
@ -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<HTMLElement>(
|
||||||
|
`.${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<HTMLElement>(
|
||||||
|
`.${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 = '';
|
||||||
|
});
|
||||||
|
}
|
@ -4,6 +4,7 @@ import type { VbenLayoutProps } from './vben-layout';
|
|||||||
import type { CSSProperties } from 'vue';
|
import type { CSSProperties } from 'vue';
|
||||||
import { computed, ref, watch } from 'vue';
|
import { computed, ref, watch } from 'vue';
|
||||||
|
|
||||||
|
import { SCROLL_FIXED_CLASS } from '@vben-core/composables';
|
||||||
import { Menu } from '@vben-core/icons';
|
import { Menu } from '@vben-core/icons';
|
||||||
import { VbenIconButton } from '@vben-core/shadcn-ui';
|
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"
|
class="flex flex-1 flex-col overflow-hidden transition-all duration-300 ease-in"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
:class="{
|
:class="[
|
||||||
'shadow-[0_16px_24px_hsl(var(--background))]': scrollY > 20,
|
{
|
||||||
}"
|
'shadow-[0_16px_24px_hsl(var(--background))]': scrollY > 20,
|
||||||
|
},
|
||||||
|
SCROLL_FIXED_CLASS,
|
||||||
|
]"
|
||||||
:style="headerWrapperStyle"
|
:style="headerWrapperStyle"
|
||||||
class="overflow-hidden transition-all duration-200"
|
class="overflow-hidden transition-all duration-200"
|
||||||
>
|
>
|
||||||
|
@ -39,6 +39,7 @@ export class DrawerApi {
|
|||||||
isOpen: false,
|
isOpen: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
modal: true,
|
modal: true,
|
||||||
|
openAutoFocus: false,
|
||||||
showCancelButton: true,
|
showCancelButton: true,
|
||||||
showConfirmButton: true,
|
showConfirmButton: true,
|
||||||
title: '',
|
title: '',
|
||||||
|
@ -52,6 +52,10 @@ export interface DrawerProps {
|
|||||||
* @default true
|
* @default true
|
||||||
*/
|
*/
|
||||||
modal?: boolean;
|
modal?: boolean;
|
||||||
|
/**
|
||||||
|
* 是否自动聚焦
|
||||||
|
*/
|
||||||
|
openAutoFocus?: boolean;
|
||||||
/**
|
/**
|
||||||
* 是否显示取消按钮
|
* 是否显示取消按钮
|
||||||
* @default true
|
* @default true
|
||||||
|
@ -51,6 +51,7 @@ const {
|
|||||||
footer: showFooter,
|
footer: showFooter,
|
||||||
loading: showLoading,
|
loading: showLoading,
|
||||||
modal,
|
modal,
|
||||||
|
openAutoFocus,
|
||||||
showCancelButton,
|
showCancelButton,
|
||||||
showConfirmButton,
|
showConfirmButton,
|
||||||
title,
|
title,
|
||||||
@ -87,10 +88,21 @@ function pointerDownOutside(e: Event) {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handerOpenAutoFocus(e: Event) {
|
||||||
|
if (!openAutoFocus.value) {
|
||||||
|
e?.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleFocusOutside(e: Event) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Sheet
|
<Sheet
|
||||||
:modal="modal"
|
:modal="false"
|
||||||
:open="state?.isOpen"
|
:open="state?.isOpen"
|
||||||
@update:open="() => drawerApi?.close()"
|
@update:open="() => drawerApi?.close()"
|
||||||
>
|
>
|
||||||
@ -100,8 +112,13 @@ function pointerDownOutside(e: Event) {
|
|||||||
'!w-full': isMobile,
|
'!w-full': isMobile,
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
|
:modal="modal"
|
||||||
|
:open="state?.isOpen"
|
||||||
|
@close-auto-focus="handleFocusOutside"
|
||||||
@escape-key-down="escapeKeyDown"
|
@escape-key-down="escapeKeyDown"
|
||||||
|
@focus-outside="handleFocusOutside"
|
||||||
@interact-outside="interactOutside"
|
@interact-outside="interactOutside"
|
||||||
|
@open-auto-focus="handerOpenAutoFocus"
|
||||||
@pointer-down-outside="pointerDownOutside"
|
@pointer-down-outside="pointerDownOutside"
|
||||||
>
|
>
|
||||||
<SheetHeader
|
<SheetHeader
|
||||||
|
@ -95,7 +95,7 @@ async function checkProps(api: ExtendedDrawerApi, attrs: Record<string, any>) {
|
|||||||
const stateKeys = new Set(Object.keys(state));
|
const stateKeys = new Set(Object.keys(state));
|
||||||
|
|
||||||
for (const attr of Object.keys(attrs)) {
|
for (const attr of Object.keys(attrs)) {
|
||||||
if (stateKeys.has(attr)) {
|
if (stateKeys.has(attr) && !['class'].includes(attr)) {
|
||||||
// connectedComponent存在时,不要传入Drawer的props,会造成复杂度提升,如果你需要修改Drawer的props,请使用 useVbenDrawer 或者api
|
// connectedComponent存在时,不要传入Drawer的props,会造成复杂度提升,如果你需要修改Drawer的props,请使用 useVbenDrawer 或者api
|
||||||
console.warn(
|
console.warn(
|
||||||
`[Vben Drawer]: When 'connectedComponent' exists, do not set props or slots '${attr}', which will increase complexity. If you need to modify the props of Drawer, please use useVbenDrawer or api.`,
|
`[Vben Drawer]: When 'connectedComponent' exists, do not set props or slots '${attr}', which will increase complexity. If you need to modify the props of Drawer, please use useVbenDrawer or api.`,
|
||||||
|
@ -123,6 +123,7 @@ function handleFullscreen() {
|
|||||||
function interactOutside(e: Event) {
|
function interactOutside(e: Event) {
|
||||||
if (!closeOnClickModal.value) {
|
if (!closeOnClickModal.value) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function escapeKeyDown(e: KeyboardEvent) {
|
function escapeKeyDown(e: KeyboardEvent) {
|
||||||
@ -143,12 +144,18 @@ function pointerDownOutside(e: Event) {
|
|||||||
const isDismissableModal = !!target?.dataset.dismissableModal;
|
const isDismissableModal = !!target?.dataset.dismissableModal;
|
||||||
if (!closeOnClickModal.value || !isDismissableModal) {
|
if (!closeOnClickModal.value || !isDismissableModal) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleFocusOutside(e: Event) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Dialog
|
<Dialog
|
||||||
:modal="modal"
|
:modal="false"
|
||||||
:open="state?.isOpen"
|
:open="state?.isOpen"
|
||||||
@update:open="() => modalApi?.close()"
|
@update:open="() => modalApi?.close()"
|
||||||
>
|
>
|
||||||
@ -166,9 +173,13 @@ function pointerDownOutside(e: Event) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
|
:modal="modal"
|
||||||
|
:open="state?.isOpen"
|
||||||
:show-close="closable"
|
:show-close="closable"
|
||||||
close-class="top-3"
|
close-class="top-3"
|
||||||
|
@close-auto-focus="handleFocusOutside"
|
||||||
@escape-key-down="escapeKeyDown"
|
@escape-key-down="escapeKeyDown"
|
||||||
|
@focus-outside="handleFocusOutside"
|
||||||
@interact-outside="interactOutside"
|
@interact-outside="interactOutside"
|
||||||
@open-auto-focus="handerOpenAutoFocus"
|
@open-auto-focus="handerOpenAutoFocus"
|
||||||
@pointer-down-outside="pointerDownOutside"
|
@pointer-down-outside="pointerDownOutside"
|
||||||
|
@ -107,7 +107,7 @@ async function checkProps(api: ExtendedModalApi, attrs: Record<string, any>) {
|
|||||||
const stateKeys = new Set(Object.keys(state));
|
const stateKeys = new Set(Object.keys(state));
|
||||||
|
|
||||||
for (const attr of Object.keys(attrs)) {
|
for (const attr of Object.keys(attrs)) {
|
||||||
if (stateKeys.has(attr)) {
|
if (stateKeys.has(attr) && !['class'].includes(attr)) {
|
||||||
// connectedComponent存在时,不要传入Modal的props,会造成复杂度提升,如果你需要修改Modal的props,请使用 useModal 或者api
|
// connectedComponent存在时,不要传入Modal的props,会造成复杂度提升,如果你需要修改Modal的props,请使用 useModal 或者api
|
||||||
console.warn(
|
console.warn(
|
||||||
`[Vben Modal]: When 'connectedComponent' exists, do not set props or slots '${attr}', which will increase complexity. If you need to modify the props of Modal, please use useVbenModal or api.`,
|
`[Vben Modal]: When 'connectedComponent' exists, do not set props or slots '${attr}', which will increase complexity. If you need to modify the props of Modal, please use useVbenModal or api.`,
|
||||||
|
@ -7,6 +7,7 @@ export default defineBuildConfig({
|
|||||||
{
|
{
|
||||||
builder: 'mkdist',
|
builder: 'mkdist',
|
||||||
input: './src',
|
input: './src',
|
||||||
|
|
||||||
pattern: ['**/*'],
|
pattern: ['**/*'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@radix-icons/vue": "^1.0.0",
|
"@radix-icons/vue": "^1.0.0",
|
||||||
|
"@vben-core/composables": "workspace:*",
|
||||||
"@vben-core/icons": "workspace:*",
|
"@vben-core/icons": "workspace:*",
|
||||||
"@vben-core/shared": "workspace:*",
|
"@vben-core/shared": "workspace:*",
|
||||||
"@vben-core/typings": "workspace:*",
|
"@vben-core/typings": "workspace:*",
|
||||||
|
@ -9,16 +9,19 @@ import {
|
|||||||
DialogContent,
|
DialogContent,
|
||||||
type DialogContentEmits,
|
type DialogContentEmits,
|
||||||
type DialogContentProps,
|
type DialogContentProps,
|
||||||
DialogOverlay,
|
|
||||||
DialogPortal,
|
DialogPortal,
|
||||||
useForwardPropsEmits,
|
useForwardPropsEmits,
|
||||||
} from 'radix-vue';
|
} from 'radix-vue';
|
||||||
|
|
||||||
|
import DialogOverlay from './DialogOverlay.vue';
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<
|
defineProps<
|
||||||
{
|
{
|
||||||
class?: any;
|
class?: any;
|
||||||
closeClass?: any;
|
closeClass?: any;
|
||||||
|
modal?: boolean;
|
||||||
|
open?: boolean;
|
||||||
showClose?: boolean;
|
showClose?: boolean;
|
||||||
} & DialogContentProps
|
} & DialogContentProps
|
||||||
>(),
|
>(),
|
||||||
@ -27,7 +30,13 @@ const props = withDefaults(
|
|||||||
const emits = defineEmits<{ close: [] } & DialogContentEmits>();
|
const emits = defineEmits<{ close: [] } & DialogContentEmits>();
|
||||||
|
|
||||||
const delegatedProps = computed(() => {
|
const delegatedProps = computed(() => {
|
||||||
const { class: _, showClose: __, ...delegated } = props;
|
const {
|
||||||
|
class: _,
|
||||||
|
modal: _modal,
|
||||||
|
open: _open,
|
||||||
|
showClose: __,
|
||||||
|
...delegated
|
||||||
|
} = props;
|
||||||
|
|
||||||
return delegated;
|
return delegated;
|
||||||
});
|
});
|
||||||
@ -43,11 +52,7 @@ defineExpose({
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<DialogPortal>
|
<DialogPortal>
|
||||||
<DialogOverlay
|
<DialogOverlay v-if="open && modal" @click="() => emits('close')" />
|
||||||
class="data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 bg-overlay fixed inset-0 z-[1000]"
|
|
||||||
data-dismissable-modal="true"
|
|
||||||
@click="() => emits('close')"
|
|
||||||
/>
|
|
||||||
<DialogContent
|
<DialogContent
|
||||||
ref="contentRef"
|
ref="contentRef"
|
||||||
v-bind="forwarded"
|
v-bind="forwarded"
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useScrollLock } from '@vben-core/composables';
|
||||||
|
|
||||||
|
useScrollLock();
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 bg-overlay fixed inset-0 z-[1000]"
|
||||||
|
data-dismissable-modal="true"
|
||||||
|
></div>
|
||||||
|
</template>
|
@ -7,15 +7,17 @@ import {
|
|||||||
DialogContent,
|
DialogContent,
|
||||||
type DialogContentEmits,
|
type DialogContentEmits,
|
||||||
type DialogContentProps,
|
type DialogContentProps,
|
||||||
DialogOverlay,
|
|
||||||
DialogPortal,
|
DialogPortal,
|
||||||
useForwardPropsEmits,
|
useForwardPropsEmits,
|
||||||
} from 'radix-vue';
|
} from 'radix-vue';
|
||||||
|
|
||||||
import { type SheetVariants, sheetVariants } from './sheet';
|
import { type SheetVariants, sheetVariants } from './sheet';
|
||||||
|
import SheetOverlay from './SheetOverlay.vue';
|
||||||
|
|
||||||
interface SheetContentProps extends DialogContentProps {
|
interface SheetContentProps extends DialogContentProps {
|
||||||
class?: any;
|
class?: any;
|
||||||
|
modal?: boolean;
|
||||||
|
open?: boolean;
|
||||||
side?: SheetVariants['side'];
|
side?: SheetVariants['side'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +30,13 @@ const props = defineProps<SheetContentProps>();
|
|||||||
const emits = defineEmits<DialogContentEmits>();
|
const emits = defineEmits<DialogContentEmits>();
|
||||||
|
|
||||||
const delegatedProps = computed(() => {
|
const delegatedProps = computed(() => {
|
||||||
const { class: _, side: _side, ...delegated } = props;
|
const {
|
||||||
|
class: _,
|
||||||
|
modal: _modal,
|
||||||
|
open: _open,
|
||||||
|
side: _side,
|
||||||
|
...delegated
|
||||||
|
} = props;
|
||||||
|
|
||||||
return delegated;
|
return delegated;
|
||||||
});
|
});
|
||||||
@ -38,10 +46,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<DialogPortal>
|
<DialogPortal>
|
||||||
<DialogOverlay
|
<SheetOverlay v-if="open && modal" />
|
||||||
class="bg-overlay data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-[1000]"
|
|
||||||
data-dismissable-modal="true"
|
|
||||||
/>
|
|
||||||
<DialogContent
|
<DialogContent
|
||||||
:class="cn(sheetVariants({ side }), 'z-[1000]', props.class)"
|
:class="cn(sheetVariants({ side }), 'z-[1000]', props.class)"
|
||||||
v-bind="{ ...forwarded, ...$attrs }"
|
v-bind="{ ...forwarded, ...$attrs }"
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useScrollLock } from '@vben-core/composables';
|
||||||
|
|
||||||
|
useScrollLock();
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="bg-overlay data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-[1000]"
|
||||||
|
data-dismissable-modal="true"
|
||||||
|
></div>
|
||||||
|
</template>
|
@ -22,7 +22,7 @@ defineProps<{ showIcon?: boolean; theme?: string }>();
|
|||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const tabbarStore = useTabbarStore();
|
const tabbarStore = useTabbarStore();
|
||||||
const { toggleMaximize } = useContentMaximize();
|
const { contentIsMaximize, toggleMaximize } = useContentMaximize();
|
||||||
const { refreshTab, unpinTab } = useTabs();
|
const { refreshTab, unpinTab } = useTabs();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -73,7 +73,7 @@ if (!preferences.tabbar.persist) {
|
|||||||
<TabsToolMore v-if="preferences.tabbar.showMore" :menus="menus" />
|
<TabsToolMore v-if="preferences.tabbar.showMore" :menus="menus" />
|
||||||
<TabsToolScreen
|
<TabsToolScreen
|
||||||
v-if="preferences.tabbar.showMaximize"
|
v-if="preferences.tabbar.showMaximize"
|
||||||
:screen="preferences.sidebar.hidden"
|
:screen="contentIsMaximize"
|
||||||
@change="toggleMaximize"
|
@change="toggleMaximize"
|
||||||
@update:screen="toggleMaximize"
|
@update:screen="toggleMaximize"
|
||||||
/>
|
/>
|
||||||
|
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@ -884,6 +884,9 @@ importers:
|
|||||||
'@radix-icons/vue':
|
'@radix-icons/vue':
|
||||||
specifier: ^1.0.0
|
specifier: ^1.0.0
|
||||||
version: 1.0.0(vue@3.5.4(typescript@5.6.2))
|
version: 1.0.0(vue@3.5.4(typescript@5.6.2))
|
||||||
|
'@vben-core/composables':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../../composables
|
||||||
'@vben-core/icons':
|
'@vben-core/icons':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../base/icons
|
version: link:../../base/icons
|
||||||
|
@ -23,30 +23,32 @@ export async function run(options: RunOptions) {
|
|||||||
return (pkg?.packageJson as Record<string, any>)?.scripts?.[command];
|
return (pkg?.packageJson as Record<string, any>)?.scripts?.[command];
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectPkg = await select<any, string>({
|
let selectPkg: string | symbol;
|
||||||
message: `Select the app you need to run [${command}]:`,
|
if (selectPkgs.length > 1) {
|
||||||
options: selectPkgs.map((item) => ({
|
selectPkg = await select<any, string>({
|
||||||
label: item?.packageJson.name,
|
message: `Select the app you need to run [${command}]:`,
|
||||||
value: item?.packageJson.name,
|
options: selectPkgs.map((item) => ({
|
||||||
})),
|
label: item?.packageJson.name,
|
||||||
});
|
value: item?.packageJson.name,
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
|
||||||
if (isCancel(selectPkg) || !selectPkg) {
|
if (isCancel(selectPkg) || !selectPkg) {
|
||||||
cancel('👋 Has cancelled');
|
cancel('👋 Has cancelled');
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selectPkg = selectPkgs[0]?.packageJson?.name ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!selectPkg) {
|
||||||
|
console.error('No app found');
|
||||||
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
execaCommand(`pnpm --filter=${selectPkg} run ${command}`, {
|
execaCommand(`pnpm --filter=${selectPkg} run ${command}`, {
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
});
|
});
|
||||||
// const filters = [];
|
|
||||||
// for (const app of selectApps) {
|
|
||||||
// filters.push(`--filter=${app}`);
|
|
||||||
// }
|
|
||||||
// $.verbose = true;
|
|
||||||
// execaCommand(`turbo run ${command} ${filters}`, {
|
|
||||||
// stdio: 'inherit',
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user