refactor: 升级框架
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/shadcn-ui",
|
||||
"version": "5.5.6",
|
||||
"version": "5.5.7",
|
||||
"#main": "./dist/index.mjs",
|
||||
"#module": "./dist/index.mjs",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
|
||||
@@ -5,6 +5,8 @@ import type {
|
||||
AvatarRootProps,
|
||||
} from 'radix-vue';
|
||||
|
||||
import type { CSSProperties } from 'vue';
|
||||
|
||||
import type { ClassType } from '@vben-core/typings';
|
||||
|
||||
import { computed } from 'vue';
|
||||
@@ -16,6 +18,7 @@ interface Props extends AvatarFallbackProps, AvatarImageProps, AvatarRootProps {
|
||||
class?: ClassType;
|
||||
dot?: boolean;
|
||||
dotClass?: ClassType;
|
||||
fit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
|
||||
size?: number;
|
||||
}
|
||||
|
||||
@@ -28,6 +31,15 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
as: 'button',
|
||||
dot: false,
|
||||
dotClass: 'bg-green-500',
|
||||
fit: 'cover',
|
||||
});
|
||||
|
||||
const imageStyle = computed<CSSProperties>(() => {
|
||||
const { fit } = props;
|
||||
if (fit) {
|
||||
return { objectFit: fit };
|
||||
}
|
||||
return {};
|
||||
});
|
||||
|
||||
const text = computed(() => {
|
||||
@@ -51,7 +63,7 @@ const rootStyle = computed(() => {
|
||||
class="relative flex flex-shrink-0 items-center"
|
||||
>
|
||||
<Avatar :class="props.class" class="size-full">
|
||||
<AvatarImage :alt="alt" :src="src" />
|
||||
<AvatarImage :alt="alt" :src="src" :style="imageStyle" />
|
||||
<AvatarFallback>{{ text }}</AvatarFallback>
|
||||
</Avatar>
|
||||
<span
|
||||
|
||||
@@ -29,14 +29,25 @@ export type ValueType = boolean | number | string;
|
||||
|
||||
export interface VbenButtonGroupProps
|
||||
extends Pick<VbenButtonProps, 'disabled'> {
|
||||
/** 单选模式下允许清除选中 */
|
||||
allowClear?: boolean;
|
||||
/** 值改变前的回调 */
|
||||
beforeChange?: (
|
||||
value: ValueType,
|
||||
isChecked: boolean,
|
||||
) => boolean | PromiseLike<boolean | undefined> | undefined;
|
||||
/** 按钮样式 */
|
||||
btnClass?: any;
|
||||
/** 按钮间隔距离 */
|
||||
gap?: number;
|
||||
/** 多选模式下限制最多选择的数量。0表示不限制 */
|
||||
maxCount?: number;
|
||||
/** 是否允许多选 */
|
||||
multiple?: boolean;
|
||||
options?: { label: CustomRenderType; value: ValueType }[];
|
||||
/** 选项 */
|
||||
options?: { [key: string]: any; label: CustomRenderType; value: ValueType }[];
|
||||
/** 显示图标 */
|
||||
showIcon?: boolean;
|
||||
/** 尺寸 */
|
||||
size?: 'large' | 'middle' | 'small';
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ const props = withDefaults(defineProps<VbenButtonGroupProps>(), {
|
||||
multiple: false,
|
||||
showIcon: true,
|
||||
size: 'middle',
|
||||
allowClear: false,
|
||||
maxCount: 0,
|
||||
});
|
||||
const emit = defineEmits(['btnClick']);
|
||||
const btnDefaultProps = computed(() => {
|
||||
@@ -82,12 +84,22 @@ async function onBtnClick(value: ValueType) {
|
||||
if (innerValue.value.includes(value)) {
|
||||
innerValue.value = innerValue.value.filter((item) => item !== value);
|
||||
} else {
|
||||
if (props.maxCount > 0 && innerValue.value.length >= props.maxCount) {
|
||||
innerValue.value = innerValue.value.slice(0, props.maxCount - 1);
|
||||
}
|
||||
innerValue.value.push(value);
|
||||
}
|
||||
modelValue.value = innerValue.value;
|
||||
} else {
|
||||
innerValue.value = [value];
|
||||
modelValue.value = value;
|
||||
if (props.allowClear && innerValue.value.includes(value)) {
|
||||
innerValue.value = [];
|
||||
modelValue.value = undefined;
|
||||
emit('btnClick', undefined);
|
||||
return;
|
||||
} else {
|
||||
innerValue.value = [value];
|
||||
modelValue.value = value;
|
||||
}
|
||||
}
|
||||
emit('btnClick', value);
|
||||
}
|
||||
@@ -110,16 +122,23 @@ async function onBtnClick(value: ValueType) {
|
||||
v-bind="btnDefaultProps"
|
||||
:variant="innerValue.includes(btn.value) ? 'default' : 'outline'"
|
||||
@click="onBtnClick(btn.value)"
|
||||
type="button"
|
||||
>
|
||||
<div class="icon-wrapper" v-if="props.showIcon">
|
||||
<LoaderCircle
|
||||
class="animate-spin"
|
||||
v-if="loadingValues.includes(btn.value)"
|
||||
/>
|
||||
<CircleCheckBig v-else-if="innerValue.includes(btn.value)" />
|
||||
<Circle v-else />
|
||||
<slot
|
||||
name="icon"
|
||||
:loading="loadingValues.includes(btn.value)"
|
||||
:checked="innerValue.includes(btn.value)"
|
||||
>
|
||||
<LoaderCircle
|
||||
class="animate-spin"
|
||||
v-if="loadingValues.includes(btn.value)"
|
||||
/>
|
||||
<CircleCheckBig v-else-if="innerValue.includes(btn.value)" />
|
||||
<Circle v-else />
|
||||
</slot>
|
||||
</div>
|
||||
<slot name="option" :label="btn.label" :value="btn.value">
|
||||
<slot name="option" :label="btn.label" :value="btn.value" :data="btn">
|
||||
<VbenRenderContent :content="btn.label" />
|
||||
</slot>
|
||||
</Button>
|
||||
@@ -127,6 +146,9 @@ async function onBtnClick(value: ValueType) {
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
.vben-check-button-group {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
&:deep(.size-large) button {
|
||||
.icon-wrapper {
|
||||
margin-right: 0.3rem;
|
||||
@@ -159,5 +181,16 @@ async function onBtnClick(value: ValueType) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.no-gap > :deep(button):nth-of-type(1) {
|
||||
border-right-width: 0;
|
||||
}
|
||||
|
||||
&.no-gap {
|
||||
:deep(button + button) {
|
||||
margin-right: -1px;
|
||||
border-left-width: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -6,6 +6,10 @@ interface Props {
|
||||
* @zh_CN 是否收起文本
|
||||
*/
|
||||
collapsed?: boolean;
|
||||
/**
|
||||
* @zh_CN Logo 图片适应方式
|
||||
*/
|
||||
fit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
|
||||
/**
|
||||
* @zh_CN Logo 跳转地址
|
||||
*/
|
||||
@@ -38,6 +42,7 @@ withDefaults(defineProps<Props>(), {
|
||||
logoSize: 32,
|
||||
src: '',
|
||||
theme: 'light',
|
||||
fit: 'cover',
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -53,6 +58,7 @@ withDefaults(defineProps<Props>(), {
|
||||
:alt="text"
|
||||
:src="src"
|
||||
:size="logoSize"
|
||||
:fit="fit"
|
||||
class="relative rounded-none bg-transparent"
|
||||
/>
|
||||
<template v-if="!collapsed">
|
||||
|
||||
@@ -80,7 +80,7 @@ defineExpose({
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'z-popup bg-background w-full p-6 shadow-lg outline-none sm:rounded-xl',
|
||||
'z-popup bg-background p-6 shadow-lg outline-none sm:rounded-xl',
|
||||
'data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95',
|
||||
'data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95',
|
||||
{
|
||||
|
||||
@@ -224,15 +224,20 @@ defineExpose({
|
||||
:class="
|
||||
cn('cursor-pointer', getNodeClass?.(item), {
|
||||
'data-[selected]:bg-accent': !multiple,
|
||||
'cursor-not-allowed': disabled,
|
||||
})
|
||||
"
|
||||
v-bind="
|
||||
Object.assign(item.bind, {
|
||||
onfocus: disabled ? 'this.blur()' : undefined,
|
||||
})
|
||||
"
|
||||
v-bind="item.bind"
|
||||
@select="
|
||||
(event) => {
|
||||
if (event.detail.originalEvent.type === 'click') {
|
||||
event.preventDefault();
|
||||
}
|
||||
onSelect(item, event.detail.isSelected);
|
||||
!disabled && onSelect(item, event.detail.isSelected);
|
||||
}
|
||||
"
|
||||
@toggle="
|
||||
@@ -240,7 +245,7 @@ defineExpose({
|
||||
if (event.detail.originalEvent.type === 'click') {
|
||||
event.preventDefault();
|
||||
}
|
||||
onToggle(item);
|
||||
!disabled && onToggle(item);
|
||||
}
|
||||
"
|
||||
class="tree-node focus:ring-grass8 my-0.5 flex items-center rounded px-2 py-1 outline-none focus:ring-2"
|
||||
@@ -262,10 +267,11 @@ defineExpose({
|
||||
<Checkbox
|
||||
v-if="multiple"
|
||||
:checked="isSelected"
|
||||
:disabled="disabled"
|
||||
:indeterminate="isIndeterminate"
|
||||
@click="
|
||||
() => {
|
||||
handleSelect();
|
||||
!disabled && handleSelect();
|
||||
// onSelect(item, !isSelected);
|
||||
}
|
||||
"
|
||||
@@ -276,7 +282,7 @@ defineExpose({
|
||||
(_event) => {
|
||||
// $event.stopPropagation();
|
||||
// $event.preventDefault();
|
||||
handleSelect();
|
||||
!disabled && handleSelect();
|
||||
// onSelect(item, !isSelected);
|
||||
}
|
||||
"
|
||||
|
||||
Reference in New Issue
Block a user