feat(button): 添加SubmitButton组件并支持ant-design主题
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { PrimitiveProps } from 'reka-ui';
|
||||
|
||||
import type { ButtonVariants, ButtonVariantSize } from './types';
|
||||
import type { ButtonTheme, ButtonVariants, ButtonVariantSize } from './types';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
@@ -12,6 +12,7 @@ import { buttonVariants } from './button';
|
||||
interface Props extends PrimitiveProps {
|
||||
class?: any;
|
||||
size?: ButtonVariantSize;
|
||||
theme?: ButtonTheme;
|
||||
variant?: ButtonVariants;
|
||||
}
|
||||
|
||||
@@ -25,7 +26,8 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
<Primitive
|
||||
:as="as"
|
||||
:as-child="asChild"
|
||||
:class="cn(buttonVariants({ variant, size }), props.class)"
|
||||
disabled
|
||||
:class="cn(buttonVariants({ variant, size, theme }), props.class)"
|
||||
>
|
||||
<slot></slot>
|
||||
</Primitive>
|
||||
|
||||
@@ -6,18 +6,23 @@ export const buttonVariants = cva(
|
||||
defaultVariants: {
|
||||
size: 'default',
|
||||
variant: 'default',
|
||||
theme: 'default',
|
||||
},
|
||||
variants: {
|
||||
theme: {
|
||||
'ant-design': '',
|
||||
default: '',
|
||||
},
|
||||
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-4',
|
||||
sm: 'h-8 rounded-md px-2 text-xs',
|
||||
small: 'h-8 rounded-md px-2 text-xs',
|
||||
xs: 'h-8 w-8 rounded-sm px-1 text-xs',
|
||||
},
|
||||
variant: {
|
||||
default:
|
||||
'bg-primary text-primary-foreground shadow hover:bg-primary/90',
|
||||
default: 'bg-primary text-primary-foreground shadow hover:bg-primary/90',
|
||||
destructive:
|
||||
'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive-hover',
|
||||
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
||||
@@ -26,9 +31,20 @@ export const buttonVariants = cva(
|
||||
link: 'text-primary underline-offset-4 hover:underline',
|
||||
outline:
|
||||
'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',
|
||||
secondary:
|
||||
'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',
|
||||
secondary: 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',
|
||||
},
|
||||
},
|
||||
compoundVariants: [
|
||||
{
|
||||
theme: 'ant-design',
|
||||
size: 'default',
|
||||
class: 'h-8 rounded-md px-4 text-sm',
|
||||
},
|
||||
{
|
||||
theme: 'ant-design',
|
||||
size: 'small',
|
||||
class: 'h-6 rounded-md px-2 text-sm',
|
||||
},
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -3,6 +3,7 @@ export type ButtonVariantSize =
|
||||
| 'icon'
|
||||
| 'lg'
|
||||
| 'sm'
|
||||
| 'small'
|
||||
| 'xs'
|
||||
| null
|
||||
| undefined;
|
||||
@@ -18,3 +19,5 @@ export type ButtonVariants =
|
||||
| 'secondary'
|
||||
| null
|
||||
| undefined;
|
||||
|
||||
export type ButtonTheme = 'ant-design' | 'default';
|
||||
|
||||
@@ -8,6 +8,7 @@ export * from './json-viewer';
|
||||
export * from './loading';
|
||||
export * from './page';
|
||||
export * from './resize';
|
||||
export * from './submit-button';
|
||||
export * from './tippy';
|
||||
export * from './tree';
|
||||
export * from '@vben-core/form-ui';
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<script lang="ts" setup>
|
||||
import type { ButtonTheme, ButtonVariants, ButtonVariantSize } from '@vben-core/shadcn-ui';
|
||||
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { Button, VbenIcon } from '@vben-core/shadcn-ui';
|
||||
|
||||
interface SubmitProps {
|
||||
/**
|
||||
* @zh_CN 主题
|
||||
*/
|
||||
theme?: ButtonTheme;
|
||||
class?: string;
|
||||
/**
|
||||
* @zh_CN 最小加载时间
|
||||
* @en_US Minimum loading time
|
||||
*/
|
||||
minLoadingTime?: number;
|
||||
/**
|
||||
* @zh_CN 文字
|
||||
*/
|
||||
text?: string;
|
||||
size?: ButtonVariantSize;
|
||||
type?: ButtonVariants;
|
||||
/**
|
||||
* @zh_CN 提交函数
|
||||
*/
|
||||
submit?: () => Promise<void>;
|
||||
}
|
||||
|
||||
defineOptions({ name: 'Loading' });
|
||||
const props = defineProps<SubmitProps>();
|
||||
const spinning = ref(false);
|
||||
async function runSubmit() {
|
||||
if (props.submit) {
|
||||
spinning.value = true;
|
||||
await new Promise((resolve) => setTimeout(resolve, props.minLoadingTime || 0));
|
||||
await props.submit();
|
||||
spinning.value = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<Button
|
||||
:disabled="spinning"
|
||||
:theme="props.theme"
|
||||
:type="props.type ?? 'primary'"
|
||||
:size="props.size ?? 'default'"
|
||||
:class="props.class"
|
||||
@click="runSubmit()"
|
||||
>
|
||||
<VbenIcon
|
||||
v-if="spinning"
|
||||
class="mr-1 animate-spin"
|
||||
icon="ant-design:loading-3-quarters-outlined"
|
||||
fallback
|
||||
/>
|
||||
{{ props.text || '提交' }}
|
||||
</Button>
|
||||
</template>
|
||||
@@ -0,0 +1 @@
|
||||
export { default as SubmitButton } from './button.vue';
|
||||
Reference in New Issue
Block a user