Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/design",
|
||||
"version": "5.5.0",
|
||||
"version": "5.5.1",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/icons",
|
||||
"version": "5.5.0",
|
||||
"version": "5.5.1",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/shared",
|
||||
"version": "5.5.0",
|
||||
"version": "5.5.1",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/typings",
|
||||
"version": "5.5.0",
|
||||
"version": "5.5.1",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/composables",
|
||||
"version": "5.5.0",
|
||||
"version": "5.5.1",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -65,6 +65,7 @@ exports[`defaultPreferences immutability test > should not modify the config obj
|
||||
"globalSearch": true,
|
||||
},
|
||||
"sidebar": {
|
||||
"autoActivateChild": false,
|
||||
"collapsed": false,
|
||||
"collapsedShowTitle": false,
|
||||
"enable": true,
|
||||
@@ -83,6 +84,7 @@ exports[`defaultPreferences immutability test > should not modify the config obj
|
||||
"showMaximize": true,
|
||||
"showMore": true,
|
||||
"styleType": "chrome",
|
||||
"wheelable": true,
|
||||
},
|
||||
"theme": {
|
||||
"builtinType": "default",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/preferences",
|
||||
"version": "5.5.0",
|
||||
"version": "5.5.1",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -65,6 +65,7 @@ const defaultPreferences: Preferences = {
|
||||
globalSearch: true,
|
||||
},
|
||||
sidebar: {
|
||||
autoActivateChild: false,
|
||||
collapsed: false,
|
||||
collapsedShowTitle: false,
|
||||
enable: true,
|
||||
@@ -83,6 +84,7 @@ const defaultPreferences: Preferences = {
|
||||
showMaximize: true,
|
||||
showMore: true,
|
||||
styleType: 'chrome',
|
||||
wheelable: true,
|
||||
},
|
||||
theme: {
|
||||
builtinType: 'default',
|
||||
|
@@ -125,6 +125,8 @@ interface NavigationPreferences {
|
||||
}
|
||||
|
||||
interface SidebarPreferences {
|
||||
/** 点击目录时自动激活子菜单 */
|
||||
autoActivateChild: boolean;
|
||||
/** 侧边栏是否折叠 */
|
||||
collapsed: boolean;
|
||||
/** 侧边栏折叠时,是否显示title */
|
||||
@@ -173,6 +175,8 @@ interface TabbarPreferences {
|
||||
showMore: boolean;
|
||||
/** 标签页风格 */
|
||||
styleType: TabsStyleType;
|
||||
/** 是否开启鼠标滚轮响应 */
|
||||
wheelable: boolean;
|
||||
}
|
||||
|
||||
interface ThemePreferences {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/form-ui",
|
||||
"version": "5.5.0",
|
||||
"version": "5.5.1",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -46,11 +46,15 @@ export function setupVbenForm<
|
||||
>(options: VbenFormAdapterOptions<T>) {
|
||||
const { config, defineRules } = options;
|
||||
|
||||
const { disabledOnChangeListener = false, emptyStateValue = undefined } =
|
||||
(config || {}) as FormCommonConfig;
|
||||
const {
|
||||
disabledOnChangeListener = true,
|
||||
disabledOnInputListener = true,
|
||||
emptyStateValue = undefined,
|
||||
} = (config || {}) as FormCommonConfig;
|
||||
|
||||
Object.assign(DEFAULT_FORM_COMMON_CONFIG, {
|
||||
disabledOnChangeListener,
|
||||
disabledOnInputListener,
|
||||
emptyStateValue,
|
||||
});
|
||||
|
||||
|
@@ -130,6 +130,11 @@ export class FormApi {
|
||||
return form.values;
|
||||
}
|
||||
|
||||
async isFieldValid(fieldName: string) {
|
||||
const form = await this.getForm();
|
||||
return form.isFieldValid(fieldName);
|
||||
}
|
||||
|
||||
merge(formApi: FormApi) {
|
||||
const chain = [this, formApi];
|
||||
const proxy = new Proxy(formApi, {
|
||||
@@ -348,4 +353,14 @@ export class FormApi {
|
||||
}
|
||||
return await this.submitForm();
|
||||
}
|
||||
|
||||
async validateField(fieldName: string, opts?: Partial<ValidationOptions>) {
|
||||
const form = await this.getForm();
|
||||
const validateResult = await form.validateField(fieldName, opts);
|
||||
|
||||
if (Object.keys(validateResult?.errors ?? {}).length > 0) {
|
||||
console.error('validate error', validateResult?.errors);
|
||||
}
|
||||
return validateResult;
|
||||
}
|
||||
}
|
||||
|
@@ -26,6 +26,7 @@ import { isEventObjectLike } from './helper';
|
||||
interface Props extends FormSchema {}
|
||||
|
||||
const {
|
||||
colon,
|
||||
commonComponentProps,
|
||||
component,
|
||||
componentProps,
|
||||
@@ -33,6 +34,7 @@ const {
|
||||
description,
|
||||
disabled,
|
||||
disabledOnChangeListener,
|
||||
disabledOnInputListener,
|
||||
emptyStateValue,
|
||||
fieldName,
|
||||
formFieldProps,
|
||||
@@ -227,10 +229,13 @@ function fieldBindEvent(slotProps: Record<string, any>) {
|
||||
|
||||
return onChange?.(e?.target?.[bindEventField] ?? e);
|
||||
},
|
||||
onInput: () => {},
|
||||
...(disabledOnInputListener ? { onInput: undefined } : {}),
|
||||
};
|
||||
}
|
||||
return {};
|
||||
return {
|
||||
...(disabledOnInputListener ? { onInput: undefined } : {}),
|
||||
...(disabledOnChangeListener ? { onChange: undefined } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
function createComponentProps(slotProps: Record<string, any>) {
|
||||
@@ -296,7 +301,10 @@ function autofocus() {
|
||||
:required="shouldRequired && !hideRequiredMark"
|
||||
:style="labelStyle"
|
||||
>
|
||||
{{ label }}
|
||||
<template v-if="label">
|
||||
<span>{{ label }}</span>
|
||||
<span v-if="colon" class="ml-[2px]">:</span>
|
||||
</template>
|
||||
</FormLabel>
|
||||
<div :class="cn('relative flex w-full items-center', wrapperClass)">
|
||||
<FormControl :class="cn(controlClass)">
|
||||
|
@@ -86,10 +86,12 @@ const computedSchema = computed(
|
||||
formFieldProps: Record<string, any>;
|
||||
} & Omit<FormSchema, 'formFieldProps'>)[] => {
|
||||
const {
|
||||
colon = false,
|
||||
componentProps = {},
|
||||
controlClass = '',
|
||||
disabled,
|
||||
disabledOnChangeListener = false,
|
||||
disabledOnChangeListener = true,
|
||||
disabledOnInputListener = true,
|
||||
emptyStateValue = undefined,
|
||||
formFieldProps = {},
|
||||
formItemClass = '',
|
||||
@@ -109,8 +111,10 @@ const computedSchema = computed(
|
||||
: false;
|
||||
|
||||
return {
|
||||
colon,
|
||||
disabled,
|
||||
disabledOnChangeListener,
|
||||
disabledOnInputListener,
|
||||
emptyStateValue,
|
||||
hideLabel,
|
||||
hideRequiredMark,
|
||||
|
@@ -136,6 +136,10 @@ type ComponentProps =
|
||||
| MaybeComponentProps;
|
||||
|
||||
export interface FormCommonConfig {
|
||||
/**
|
||||
* 在Label后显示一个冒号
|
||||
*/
|
||||
colon?: boolean;
|
||||
/**
|
||||
* 所有表单项的props
|
||||
*/
|
||||
@@ -151,9 +155,14 @@ export interface FormCommonConfig {
|
||||
disabled?: boolean;
|
||||
/**
|
||||
* 是否禁用所有表单项的change事件监听
|
||||
* @default false
|
||||
* @default true
|
||||
*/
|
||||
disabledOnChangeListener?: boolean;
|
||||
/**
|
||||
* 是否禁用所有表单项的input事件监听
|
||||
* @default true
|
||||
*/
|
||||
disabledOnInputListener?: boolean;
|
||||
/**
|
||||
* 所有表单项的空状态值,默认都是undefined,naive-ui的空状态值是null
|
||||
*/
|
||||
@@ -371,6 +380,7 @@ export interface VbenFormAdapterOptions<
|
||||
config?: {
|
||||
baseModelPropName?: string;
|
||||
disabledOnChangeListener?: boolean;
|
||||
disabledOnInputListener?: boolean;
|
||||
emptyStateValue?: null | undefined;
|
||||
modelPropNameMap?: Partial<Record<T, string>>;
|
||||
};
|
||||
|
@@ -6,7 +6,9 @@ import type { ExtendedFormApi, VbenFormProps } from './types';
|
||||
import { useForwardPriorityValues } from '@vben-core/composables';
|
||||
// import { isFunction } from '@vben-core/shared/utils';
|
||||
|
||||
import { toRaw, useTemplateRef, watch } from 'vue';
|
||||
import { nextTick, onMounted, useTemplateRef, watch } from 'vue';
|
||||
|
||||
import { cloneDeep } from '@vben-core/shared/utils';
|
||||
|
||||
import { useDebounceFn } from '@vueuse/core';
|
||||
|
||||
@@ -59,14 +61,16 @@ function handleKeyDownEnter(event: KeyboardEvent) {
|
||||
formActionsRef.value?.handleSubmit?.();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => form.values,
|
||||
useDebounceFn(() => {
|
||||
forward.value.handleValuesChange?.(toRaw(form.values));
|
||||
state.value.submitOnChange && props.formApi?.submitForm();
|
||||
}, 300),
|
||||
{ deep: true },
|
||||
);
|
||||
const handleValuesChangeDebounced = useDebounceFn((newVal) => {
|
||||
forward.value.handleValuesChange?.(cloneDeep(newVal));
|
||||
state.value.submitOnChange && formActionsRef.value?.handleSubmit?.();
|
||||
}, 300);
|
||||
|
||||
onMounted(async () => {
|
||||
// 只在挂载后开始监听,form.values会有一个初始化的过程
|
||||
await nextTick();
|
||||
watch(() => form.values, handleValuesChangeDebounced, { deep: true });
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/layout-ui",
|
||||
"version": "5.5.0",
|
||||
"version": "5.5.1",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/menu-ui",
|
||||
"version": "5.5.0",
|
||||
"version": "5.5.1",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -1,3 +1,4 @@
|
||||
export { default as MenuBadge } from './components/menu-badge.vue';
|
||||
export * from './components/normal-menu';
|
||||
export { default as Menu } from './menu.vue';
|
||||
export type * from './types';
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/shadcn-ui",
|
||||
"version": "5.5.0",
|
||||
"version": "5.5.1",
|
||||
"#main": "./dist/index.mjs",
|
||||
"#module": "./dist/index.mjs",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
|
@@ -47,6 +47,10 @@ watch(
|
||||
},
|
||||
);
|
||||
|
||||
watch(inputValue, (val) => {
|
||||
modelValue.value = val.join('');
|
||||
});
|
||||
|
||||
function handleComplete(e: string[]) {
|
||||
modelValue.value = e.join('');
|
||||
emit('complete');
|
||||
|
@@ -11,8 +11,8 @@ export const buttonVariants = cva(
|
||||
size: {
|
||||
default: 'h-9 px-4 py-2',
|
||||
icon: 'h-8 w-8 rounded-sm px-1 text-lg',
|
||||
lg: 'h-10 rounded-md px-8',
|
||||
sm: 'h-8 rounded-md px-3 text-xs',
|
||||
lg: 'h-10 rounded-md px-4',
|
||||
sm: 'h-8 rounded-md px-2 text-xs',
|
||||
xs: 'h-8 w-8 rounded-sm px-1 text-xs',
|
||||
},
|
||||
variant: {
|
||||
|
@@ -24,7 +24,7 @@ const forwardedProps = useForwardProps(delegatedProps);
|
||||
v-bind="forwardedProps"
|
||||
:class="
|
||||
cn(
|
||||
'border-input bg-background relative flex h-10 w-10 items-center justify-center border-y border-r text-center text-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md focus:relative focus:z-10 focus:outline-none focus:ring-2',
|
||||
'border-input bg-background relative flex h-10 w-8 items-center justify-center border-y border-r text-center text-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md focus:relative focus:z-10 focus:outline-none focus:ring-2 md:w-10',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/tabs-ui",
|
||||
"version": "5.5.0",
|
||||
"version": "5.5.1",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -19,6 +19,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
contentClass: 'vben-tabs-content',
|
||||
draggable: true,
|
||||
styleType: 'chrome',
|
||||
wheelable: true,
|
||||
});
|
||||
|
||||
const emit = defineEmits<TabsEmits>();
|
||||
@@ -27,6 +28,7 @@ const forward = useForwardPropsEmits(props, emit);
|
||||
|
||||
const {
|
||||
handleScrollAt,
|
||||
handleWheel,
|
||||
scrollbarRef,
|
||||
scrollDirection,
|
||||
scrollIsAtLeft,
|
||||
@@ -34,6 +36,14 @@ const {
|
||||
showScrollButton,
|
||||
} = useTabsViewScroll(props);
|
||||
|
||||
function onWheel(e: WheelEvent) {
|
||||
if (props.wheelable) {
|
||||
handleWheel(e);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
useTabsDrag(props, emit);
|
||||
</script>
|
||||
|
||||
@@ -69,6 +79,7 @@ useTabsDrag(props, emit);
|
||||
shadow-left
|
||||
shadow-right
|
||||
@scroll-at="handleScrollAt"
|
||||
@wheel="onWheel"
|
||||
>
|
||||
<TabsChrome
|
||||
v-if="styleType === 'chrome'"
|
||||
|
@@ -33,7 +33,6 @@ export interface TabsProps {
|
||||
* 仅限 tabs-chrome
|
||||
*/
|
||||
maxWidth?: number;
|
||||
|
||||
/**
|
||||
* @zh_CN tab最小宽度
|
||||
* 仅限 tabs-chrome
|
||||
@@ -44,15 +43,20 @@ export interface TabsProps {
|
||||
* @zh_CN 是否显示图标
|
||||
*/
|
||||
showIcon?: boolean;
|
||||
|
||||
/**
|
||||
* @zh_CN 标签页风格
|
||||
*/
|
||||
styleType?: TabsStyleType;
|
||||
|
||||
/**
|
||||
* @zh_CN 选项卡数据
|
||||
*/
|
||||
tabs?: TabDefinition[];
|
||||
|
||||
/**
|
||||
* @zh_CN 是否响应滚轮事件
|
||||
*/
|
||||
wheelable?: boolean;
|
||||
}
|
||||
|
||||
export interface TabConfig extends TabDefinition {
|
||||
|
@@ -142,6 +142,13 @@ export function useTabsViewScroll(props: TabsProps) {
|
||||
scrollIsAtRight.value = right;
|
||||
}, 100);
|
||||
|
||||
function handleWheel({ deltaY }: WheelEvent) {
|
||||
scrollViewportEl.value?.scrollBy({
|
||||
behavior: 'smooth',
|
||||
left: deltaY * 3,
|
||||
});
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.active,
|
||||
async () => {
|
||||
@@ -184,6 +191,7 @@ export function useTabsViewScroll(props: TabsProps) {
|
||||
|
||||
return {
|
||||
handleScrollAt,
|
||||
handleWheel,
|
||||
initScrollbar,
|
||||
scrollbarRef,
|
||||
scrollDirection,
|
||||
|
Reference in New Issue
Block a user