feat: add VbenForm component (#4352)

* feat: add form component

* fix: build error

* feat: add form adapter

* feat: add some component

* feat: add some component

* feat: add example

* feat: suppoer custom action button

* chore: update

* feat: add example

* feat: add formModel,formDrawer demo

* fix: build error

* fix: typo

* fix: ci error

---------

Co-authored-by: jinmao <jinmao88@qq.com>
Co-authored-by: likui628 <90845831+likui628@users.noreply.github.com>
This commit is contained in:
Vben
2024-09-10 21:48:51 +08:00
committed by GitHub
parent 86ed732ca8
commit 524b9badf2
271 changed files with 5974 additions and 1247 deletions

View File

@@ -11,6 +11,6 @@
"framework": "vite",
"aliases": {
"components": "@vben-core/shadcn-ui/components",
"utils": "@vben-core/shared"
"utils": "@vben-core/shared/utils"
}
}

View File

@@ -11,8 +11,8 @@
"license": "MIT",
"type": "module",
"scripts": {
"build": "pnpm unbuild",
"prepublishOnly": "npm run build"
"#build": "pnpm unbuild",
"#prepublishOnly": "npm run build"
},
"files": [
"dist"
@@ -20,24 +20,22 @@
"sideEffects": [
"**/*.css"
],
"main": "./dist/index.mjs",
"module": "./dist/index.mjs",
"#main": "./dist/index.mjs",
"main": "./src/index.ts",
"#module": "./dist/index.mjs",
"module": "./src/index.ts",
"exports": {
".": {
"types": "./src/index.ts",
"development": "./src/index.ts",
"default": "./dist/index.mjs"
},
"./*": {
"types": "./src/*/index.ts",
"development": "./src/*/index.ts",
"default": "./dist/*/index.mjs"
"//default": "./dist/index.mjs",
"default": "./src/index.ts"
}
},
"publishConfig": {
"exports": {
".": {
"default": "./dist/index.mjs"
"default": "./src/index.ts"
}
}
},
@@ -50,6 +48,7 @@
"class-variance-authority": "^0.7.0",
"lucide-vue-next": "^0.439.0",
"radix-vue": "^1.9.5",
"vee-validate": "^4.13.2",
"vue": "^3.5.3"
}
}

View File

@@ -0,0 +1,24 @@
import type { AsTag } from 'radix-vue';
import type { ButtonVariants, ButtonVariantSize } from '../ui/button';
import type { Component } from 'vue';
export interface VbenButtonProps {
/**
* The element or component this component should render as. Can be overwrite by `asChild`
* @defaultValue "div"
*/
as?: AsTag | Component;
/**
* Change the default rendered element for the one passed as a child, merging their props and behavior.
*
* Read our [Composition](https://www.radix-vue.com/guides/composition.html) guide for more details.
*/
asChild?: boolean;
class?: any;
disabled?: boolean;
loading?: boolean;
size?: ButtonVariantSize;
variant?: ButtonVariants;
}

View File

@@ -1,20 +1,16 @@
<script setup lang="ts">
import type { VbenButtonProps } from './button';
import { computed } from 'vue';
import { LoaderCircle } from '@vben-core/icons';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { Primitive, type PrimitiveProps } from 'radix-vue';
import { Primitive } from 'radix-vue';
import { type ButtonVariants, buttonVariants } from '../ui/button';
import { buttonVariants } from '../ui/button';
interface Props extends PrimitiveProps {
class?: any;
disabled?: boolean;
loading?: boolean;
size?: ButtonVariants['size'];
variant?: ButtonVariants['variant'];
}
interface Props extends VbenButtonProps {}
const props = withDefaults(defineProps<Props>(), {
as: 'button',

View File

@@ -1,22 +1,21 @@
<script setup lang="ts">
import type { ButtonVariants } from '../ui/button';
import type { VbenButtonProps } from './button';
import { computed, useSlots } from 'vue';
import { cn } from '@vben-core/shared';
import { type PrimitiveProps } from 'radix-vue';
import { cn } from '@vben-core/shared/utils';
import { VbenTooltip } from '../tooltip';
import VbenButton from './button.vue';
interface Props extends PrimitiveProps {
interface Props extends VbenButtonProps {
class?: any;
disabled?: boolean;
onClick?: () => void;
tooltip?: string;
tooltipSide?: 'bottom' | 'left' | 'right' | 'top';
variant?: ButtonVariants['variant'];
variant?: ButtonVariants;
}
const props = withDefaults(defineProps<Props>(), {

View File

@@ -1,2 +1,3 @@
export type * from './button';
export { default as VbenButton } from './button.vue';
export { default as VbenIconButton } from './icon-button.vue';

View File

@@ -1,24 +1,26 @@
<script setup lang="ts">
import type { CheckboxRootEmits, CheckboxRootProps } from 'radix-vue';
import { useId } from 'vue';
import { useForwardPropsEmits } from 'radix-vue';
import { Checkbox } from '../ui/checkbox';
const props = defineProps<
{
name: string;
} & CheckboxRootProps
>();
const props = defineProps<CheckboxRootProps>();
const emits = defineEmits<CheckboxRootEmits>();
const checked = defineModel<boolean>('checked');
const forwarded = useForwardPropsEmits(props, emits);
const id = useId();
</script>
<template>
<Checkbox v-bind="forwarded" :id="name" v-model:checked="checked" />
<label :for="name" class="ml-2 cursor-pointer text-sm"> <slot></slot> </label>
<div class="flex items-center">
<Checkbox v-bind="forwarded" :id="id" v-model:checked="checked" />
<label :for="id" class="ml-2 cursor-pointer text-sm"> <slot></slot> </label>
</div>
</template>

View File

@@ -1,7 +1,7 @@
<script lang="ts" setup>
import { computed, onMounted, ref, unref, watch, watchEffect } from 'vue';
import { isNumber } from '@vben-core/shared';
import { isNumber } from '@vben-core/shared/utils';
import { TransitionPresets, useTransition } from '@vueuse/core';

View File

@@ -0,0 +1,36 @@
<script lang="ts" setup>
import { ChevronDown } from '@vben-core/icons';
import { cn } from '@vben-core/shared/utils';
const props = defineProps<{
class?: string;
}>();
// 控制箭头展开/收起状态
const collapsed = defineModel({ default: false });
</script>
<template>
<div
:class="
cn(
'text-primary hover:text-primary-hover inline-flex cursor-pointer items-center',
props.class,
)
"
@click="collapsed = !collapsed"
>
<slot :is-expanded="collapsed">
{{ collapsed }}
<!-- <span>{{ isExpanded ? '收起' : '展开' }}</span> -->
</slot>
<div
:class="{ 'rotate-180': !collapsed }"
class="transition-transform duration-300"
>
<slot name="icon">
<ChevronDown class="size-4" />
</slot>
</div>
</div>
</template>

View File

@@ -0,0 +1 @@
export { default as VbenExpandableArrow } from './expandable-arrow.vue';

View File

@@ -22,7 +22,7 @@ isFullscreen.value = !!(
</script>
<template>
<VbenIconButton @click="toggle">
<Minimize v-if="isFullscreen" class="size-4" />
<Maximize v-else class="size-4" />
<Minimize v-if="isFullscreen" class="text-foreground size-4" />
<Maximize v-else class="text-foreground size-4" />
</VbenIconButton>
</template>

View File

@@ -2,7 +2,12 @@
import { type Component, computed } from 'vue';
import { Icon, IconDefault } from '@vben-core/icons';
import { isFunction, isHttpUrl, isObject, isString } from '@vben-core/shared';
import {
isFunction,
isHttpUrl,
isObject,
isString,
} from '@vben-core/shared/utils';
const props = defineProps<{
// 没有是否显示默认图标

View File

@@ -6,10 +6,10 @@ export * from './checkbox';
export * from './context-menu';
export * from './count-to-animator';
export * from './dropdown-menu';
export * from './expandable-arrow';
export * from './full-screen';
export * from './hover-card';
export * from './icon';
export * from './input';
export * from './input-password';
export * from './link';
export * from './logo';
@@ -19,9 +19,11 @@ export * from './popover';
export * from './render-content';
export * from './scrollbar';
export * from './segmented';
export * from './select';
export * from './spinner';
export * from './swap';
export * from './tooltip';
export * from './ui/accordion';
export * from './ui/avatar';
export * from './ui/badge';
export * from './ui/breadcrumb';
@@ -30,16 +32,21 @@ export * from './ui/card';
export * from './ui/checkbox';
export * from './ui/dialog';
export * from './ui/dropdown-menu';
export * from './ui/form';
export * from './ui/hover-card';
export * from './ui/input';
export * from './ui/label';
export * from './ui/number-field';
export * from './ui/pin-input';
export * from './ui/popover';
export * from './ui/radio-group';
export * from './ui/scroll-area';
export * from './ui/select';
export * from './ui/separator';
export * from './ui/sheet';
export * from './ui/switch';
export * from './ui/tabs';
export * from './ui/textarea';
export * from './ui/toast';
export * from './ui/toggle';
export * from './ui/toggle-group';

View File

@@ -2,13 +2,18 @@
import { ref, useSlots } from 'vue';
import { Eye, EyeOff } from '@vben-core/icons';
import { cn } from '@vben-core/shared/utils';
import { useForwardProps } from 'radix-vue';
import { type InputProps, VbenInput } from '../input';
import { Input } from '../ui/input';
import PasswordStrength from './password-strength.vue';
interface Props extends InputProps {}
interface Props {
class?: any;
/**
* 是否显示密码强度
*/
passwordStrength?: boolean;
}
defineOptions({
inheritAttrs: false,
@@ -19,30 +24,30 @@ const props = defineProps<Props>();
const modelValue = defineModel<string>();
const slots = useSlots();
const forward = useForwardProps(props);
const show = ref(false);
</script>
<template>
<div class="relative">
<VbenInput
<div class="relative w-full">
<Input
v-bind="$attrs"
v-model="modelValue"
v-bind="{ ...forward, ...$attrs }"
:class="cn(props.class)"
:type="show ? 'text' : 'password'"
>
<template v-if="passwordStrength">
<PasswordStrength :password="modelValue" />
<p
v-if="slots.strengthText"
class="text-muted-foreground mt-1.5 text-xs"
>
<slot name="strengthText"> </slot>
</p>
</template>
</VbenInput>
/>
<template v-if="passwordStrength">
<PasswordStrength :password="modelValue" />
<p v-if="slots.strengthText" class="text-muted-foreground mt-1.5 text-xs">
<slot name="strengthText"> </slot>
</p>
</template>
<div
class="hover:text-foreground text-foreground/60 absolute inset-y-0 right-0 top-3 flex cursor-pointer pr-3 text-lg leading-5"
:class="{
'top-3': !!passwordStrength,
'top-1/2 -translate-y-1/2 items-center': !passwordStrength,
}"
class="hover:text-foreground text-foreground/60 absolute inset-y-0 right-0 flex cursor-pointer pr-3 text-lg leading-5"
@click="show = !show"
>
<Eye v-if="show" class="size-4" />

View File

@@ -1,2 +0,0 @@
export { default as VbenInput } from './input.vue';
export type * from './types';

View File

@@ -1,53 +0,0 @@
<script setup lang="ts">
import type { InputProps } from './types';
import { computed } from 'vue';
defineOptions({
inheritAttrs: false,
});
const props = defineProps<InputProps>();
const modelValue = defineModel<number | string>();
const inputClass = computed(() => {
if (props.status === 'error') {
return 'border-destructive';
}
return '';
});
</script>
<template>
<div class="relative mb-6">
<label
v-if="!label"
:for="name"
class="mb-2 block text-sm font-medium dark:text-white"
>
{{ label }}
</label>
<input
:id="name"
v-model="modelValue"
:class="[props.class, inputClass]"
autocomplete="off"
class="border-input bg-input-background ring-offset-background placeholder:text-muted-foreground/60 focus-visible:ring-ring focus:border-primary flex h-10 w-full rounded-md border p-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
required
type="text"
v-bind="$attrs"
/>
<slot></slot>
<Transition name="slide-up">
<p
v-if="status === 'error'"
class="text-destructive bottom-130 absolute mt-1 text-xs"
>
{{ errorTip }}
</p>
</Transition>
</div>
</template>

View File

@@ -1,25 +0,0 @@
interface InputProps {
class?: any;
/**
* 错误提示信息
*/
errorTip?: string;
/**
* 输入框的 label
*/
label?: string;
/**
* 输入框的 name
*/
name?: string;
/**
* 是否显示密码强度
*/
passwordStrength?: boolean;
/**
* 输入框的校验状态
*/
status?: 'default' | 'error';
}
export type { InputProps };

View File

@@ -1,5 +1,5 @@
<script setup lang="ts">
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { Primitive, type PrimitiveProps } from 'radix-vue';

View File

@@ -3,7 +3,7 @@ import type { MenuRecordBadgeRaw } from '@vben-core/typings';
import { computed } from 'vue';
import { isValidColor } from '@vben-core/shared';
import { isValidColor } from '@vben-core/shared/color';
import BadgeDot from './menu-badge-dot.vue';

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import type { PinInputProps } from './types';
import { computed, ref, watch } from 'vue';
import { computed, onBeforeUnmount, ref, useId, watch } from 'vue';
import { VbenButton } from '../button';
import { PinInput, PinInputGroup, PinInputInput } from '../ui/pin-input';
@@ -14,21 +14,27 @@ const props = withDefaults(defineProps<PinInputProps>(), {
btnLoading: false,
codeLength: 6,
handleSendCode: async () => {},
maxTime: 60,
});
const emit = defineEmits<{
complete: [];
}>();
const timer = ref<ReturnType<typeof setTimeout>>();
const modelValue = defineModel<string>();
const inputValue = ref<string[]>([]);
const countdown = ref(0);
const inputClass = computed(() => {
if (props.status === 'error') {
return 'border-destructive';
}
return '';
const btnText = computed(() => {
const countdownValue = countdown.value;
return props.createText?.(countdownValue);
});
const btnLoading = computed(() => {
return props.loading || countdown.value > 0;
});
watch(
@@ -42,45 +48,58 @@ function handleComplete(e: string[]) {
modelValue.value = e.join('');
emit('complete');
}
async function handleSend(e: Event) {
e?.preventDefault();
await props.handleSendCode();
countdown.value = props.maxTime;
startCountdown();
}
function startCountdown() {
if (countdown.value > 0) {
timer.value = setTimeout(() => {
countdown.value--;
startCountdown();
}, 1000);
}
}
onBeforeUnmount(() => {
countdown.value = 0;
clearTimeout(timer.value);
});
const id = useId();
</script>
<template>
<div class="relative mb-6">
<label :for="name" class="mb-2 block text-sm font-medium">
{{ label }}
</label>
<PinInput
:id="name"
v-model="inputValue"
:class="inputClass"
class="flex justify-between"
otp
placeholder="○"
type="number"
@complete="handleComplete"
>
<PinInputGroup>
<PinInput
:id="id"
v-model="inputValue"
class="flex w-full justify-between"
otp
placeholder=""
type="number"
@complete="handleComplete"
>
<div class="relative flex w-full">
<PinInputGroup class="mr-2">
<PinInputInput
v-for="(id, index) in codeLength"
:key="id"
v-for="(item, index) in codeLength"
:key="item"
:index="index"
/>
</PinInputGroup>
<VbenButton
:loading="btnLoading"
class="w-[300px] xl:w-full"
class="flex-grow"
size="lg"
variant="outline"
@click="handleSendCode"
@click="handleSend"
>
{{ btnText }}
</VbenButton>
</PinInput>
<p
v-if="status === 'error'"
class="text-destructive bottom-130 absolute mt-1 text-xs"
>
{{ errorTip }}
</p>
</div>
</div>
</PinInput>
</template>

View File

@@ -1,38 +1,26 @@
interface PinInputProps {
/**
* 发送验证码按钮loading
*/
btnLoading?: boolean;
/**
* 发送验证码按钮文本
*/
btnText?: string;
class?: any;
/**
* 验证码长度
*/
codeLength?: number;
/**
* 错误提示信息
* 发送验证码按钮文本
*/
errorTip?: string;
createText?: (countdown: number) => string;
/**
* 自定义验证码发送逻辑
* @returns
*/
handleSendCode?: () => Promise<void>;
/**
* 输入框的 label
* 发送验证码按钮loading
*/
label: string;
loading?: boolean;
/**
* 输入框的 name
* 最大重试时间
*/
name: string;
/**
* 输入框的校验状态
*/
status?: 'default' | 'error';
maxTime?: number;
}
export type { PinInputProps };

View File

@@ -1,26 +1,39 @@
<script setup lang="ts">
import type { Component } from 'vue';
<script lang="ts">
import type { Component, PropType } from 'vue';
import { defineComponent, h } from 'vue';
defineOptions({
import { isFunction, isObject } from '@vben-core/shared/utils';
export default defineComponent({
name: 'RenderContent',
});
const props = withDefaults(
defineProps<{
content: Component | string | undefined;
props?: Record<string, any>;
}>(),
{
props: () => ({}),
props: {
content: {
default: undefined as
| PropType<(() => any) | Component | string>
| undefined,
type: [Object, String, Function],
},
},
);
const isComponent = typeof props.content === 'object' && props.content !== null;
setup(props, { attrs, slots }) {
return () => {
if (!props.content) {
return null;
}
const isComponent =
(isObject(props.content) || isFunction(props.content)) &&
props.content !== null;
if (!isComponent) {
return props.content;
}
return h(props.content as never, {
...attrs,
props: {
...props,
...attrs,
},
slots,
});
};
},
});
</script>
<template>
<component :is="content" v-bind="props" v-if="isComponent" />
<template v-else-if="!isComponent">
{{ content }}
</template>
</template>

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { ScrollArea, ScrollBar } from '../ui/scroll-area';

View File

@@ -1,13 +1,11 @@
<script setup lang="ts">
import type { TabsIndicatorProps } from 'radix-vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import {
TabsIndicator,
type TabsIndicatorProps,
useForwardProps,
} from 'radix-vue';
import { TabsIndicator, useForwardProps } from 'radix-vue';
const props = defineProps<{ class?: any } & TabsIndicatorProps>();

View File

@@ -0,0 +1 @@
export { default as VbenSelect } from './select.vue';

View File

@@ -0,0 +1,29 @@
<script lang="ts" setup>
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '../ui/select';
interface Props {
class?: any;
options?: Array<{ label: string; value: string }>;
placeholder?: string;
}
const props = defineProps<Props>();
</script>
<template>
<Select>
<SelectTrigger :class="props.class">
<SelectValue :placeholder="placeholder" />
</SelectTrigger>
<SelectContent>
<template v-for="item in options" :key="item.value">
<SelectItem :value="item.value"> {{ item.label }} </SelectItem>
</template>
</SelectContent>
</Select>
</template>

View File

@@ -1,7 +1,7 @@
<script lang="ts" setup>
import { ref, watch } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
interface Props {
class?: string;

View File

@@ -1,7 +1,7 @@
<script lang="ts" setup>
import { ref, watch } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
interface Props {
class?: string;

View File

@@ -0,0 +1,31 @@
<script setup lang="ts">
import { cn } from '@vben-core/shared/utils';
import { CircleHelp } from 'lucide-vue-next';
import Tooltip from './tooltip.vue';
defineOptions({
inheritAttrs: false,
});
defineProps<{ triggerClass?: string }>();
</script>
<template>
<Tooltip :delay-duration="300" side="right">
<template #trigger>
<slot name="trigger">
<CircleHelp
:class="
cn(
'text-foreground/80 hover:text-foreground inline-flex size-5 cursor-pointer',
triggerClass,
)
"
/>
</slot>
</template>
<slot></slot>
</Tooltip>
</template>

View File

@@ -1 +1,2 @@
export { default as VbenHelpTooltip } from './help-tooltip.vue';
export { default as VbenTooltip } from './tooltip.vue';

View File

@@ -0,0 +1,19 @@
<script setup lang="ts">
import {
AccordionRoot,
type AccordionRootEmits,
type AccordionRootProps,
useForwardPropsEmits,
} from 'radix-vue';
const props = defineProps<AccordionRootProps>();
const emits = defineEmits<AccordionRootEmits>();
const forwarded = useForwardPropsEmits(props, emits);
</script>
<template>
<AccordionRoot v-bind="forwarded">
<slot></slot>
</AccordionRoot>
</template>

View File

@@ -0,0 +1,26 @@
<script setup lang="ts">
import { computed } from 'vue';
import { cn } from '@vben-core/shared/utils';
import { AccordionContent, type AccordionContentProps } from 'radix-vue';
const props = defineProps<{ class?: any } & AccordionContentProps>();
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;
return delegated;
});
</script>
<template>
<AccordionContent
v-bind="delegatedProps"
class="data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm"
>
<div :class="cn('pb-4 pt-0', props.class)">
<slot></slot>
</div>
</AccordionContent>
</template>

View File

@@ -0,0 +1,27 @@
<script setup lang="ts">
import { computed } from 'vue';
import { cn } from '@vben-core/shared/utils';
import {
AccordionItem,
type AccordionItemProps,
useForwardProps,
} from 'radix-vue';
const props = defineProps<{ class?: any } & AccordionItemProps>();
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;
return delegated;
});
const forwardedProps = useForwardProps(delegatedProps);
</script>
<template>
<AccordionItem v-bind="forwardedProps" :class="cn('border-b', props.class)">
<slot></slot>
</AccordionItem>
</template>

View File

@@ -0,0 +1,41 @@
<script setup lang="ts">
import { computed } from 'vue';
import { cn } from '@vben-core/shared/utils';
import { ChevronDownIcon } from '@radix-icons/vue';
import {
AccordionHeader,
AccordionTrigger,
type AccordionTriggerProps,
} from 'radix-vue';
const props = defineProps<{ class?: any } & AccordionTriggerProps>();
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;
return delegated;
});
</script>
<template>
<AccordionHeader class="flex">
<AccordionTrigger
v-bind="delegatedProps"
:class="
cn(
'flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',
props.class,
)
"
>
<slot></slot>
<slot name="icon">
<ChevronDownIcon
class="text-muted-foreground h-4 w-4 shrink-0 transition-transform duration-200"
/>
</slot>
</AccordionTrigger>
</AccordionHeader>
</template>

View File

@@ -0,0 +1,4 @@
export { default as Accordion } from './Accordion.vue';
export { default as AccordionContent } from './AccordionContent.vue';
export { default as AccordionItem } from './AccordionItem.vue';
export { default as AccordionTrigger } from './AccordionTrigger.vue';

View File

@@ -1,7 +1,5 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { AvatarRoot } from 'radix-vue';
@@ -9,7 +7,7 @@ import { avatarVariant, type AvatarVariants } from './avatar';
const props = withDefaults(
defineProps<{
class?: HTMLAttributes['class'];
class?: any;
shape?: AvatarVariants['shape'];
size?: AvatarVariants['size'];
}>(),

View File

@@ -1,12 +1,10 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { type BadgeVariants, badgeVariants } from './badge';
const props = defineProps<{
class?: HTMLAttributes['class'];
class?: any;
variant?: BadgeVariants['variant'];
}>();
</script>

View File

@@ -1,8 +1,6 @@
<script lang="ts" setup>
import type { HTMLAttributes } from 'vue';
const props = defineProps<{
class?: HTMLAttributes['class'];
class?: any;
}>();
</script>

View File

@@ -1,12 +1,10 @@
<script lang="ts" setup>
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { DotsHorizontalIcon } from '@radix-icons/vue';
const props = defineProps<{
class?: HTMLAttributes['class'];
class?: any;
}>();
</script>

View File

@@ -1,10 +1,8 @@
<script lang="ts" setup>
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
const props = defineProps<{
class?: HTMLAttributes['class'];
class?: any;
}>();
</script>

View File

@@ -1,16 +1,11 @@
<script lang="ts" setup>
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { Primitive, type PrimitiveProps } from 'radix-vue';
const props = withDefaults(
defineProps<{ class?: HTMLAttributes['class'] } & PrimitiveProps>(),
{
as: 'a',
},
);
const props = withDefaults(defineProps<{ class?: any } & PrimitiveProps>(), {
as: 'a',
});
</script>
<template>

View File

@@ -1,10 +1,8 @@
<script lang="ts" setup>
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
const props = defineProps<{
class?: HTMLAttributes['class'];
class?: any;
}>();
</script>

View File

@@ -1,10 +1,8 @@
<script lang="ts" setup>
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
const props = defineProps<{
class?: HTMLAttributes['class'];
class?: any;
}>();
</script>

View File

@@ -1,12 +1,10 @@
<script lang="ts" setup>
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { ChevronRightIcon } from '@radix-icons/vue';
const props = defineProps<{
class?: HTMLAttributes['class'];
class?: any;
}>();
</script>

View File

@@ -1,16 +1,16 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue';
import type { ButtonVariants, ButtonVariantSize } from './types';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { Primitive, type PrimitiveProps } from 'radix-vue';
import { type ButtonVariants, buttonVariants } from './button';
import { buttonVariants } from './button';
interface Props extends PrimitiveProps {
class?: HTMLAttributes['class'];
size?: ButtonVariants['size'];
variant?: 'heavy' & ButtonVariants['variant'];
class?: any;
size?: ButtonVariantSize;
variant?: 'heavy' & ButtonVariants;
}
const props = withDefaults(defineProps<Props>(), {

View File

@@ -1,4 +1,4 @@
import { cva, type VariantProps } from 'class-variance-authority';
import { cva } from 'class-variance-authority';
export const buttonVariants = cva(
'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',
@@ -32,5 +32,3 @@ export const buttonVariants = cva(
},
},
);
export type ButtonVariants = VariantProps<typeof buttonVariants>;

View File

@@ -1,3 +1,5 @@
export * from './button';
export { default as Button } from './Button.vue';
export type * from './types';

View File

@@ -0,0 +1,20 @@
export type ButtonVariantSize =
| 'default'
| 'icon'
| 'lg'
| 'sm'
| 'xs'
| null
| undefined;
export type ButtonVariants =
| 'default'
| 'destructive'
| 'ghost'
| 'heavy'
| 'icon'
| 'link'
| 'outline'
| 'secondary'
| null
| undefined;

View File

@@ -1,10 +1,8 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
const props = defineProps<{
class?: HTMLAttributes['class'];
class?: any;
}>();
</script>

View File

@@ -1,10 +1,8 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
const props = defineProps<{
class?: HTMLAttributes['class'];
class?: any;
}>();
</script>

View File

@@ -1,10 +1,8 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
const props = defineProps<{
class?: HTMLAttributes['class'];
class?: any;
}>();
</script>

View File

@@ -1,10 +1,8 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
const props = defineProps<{
class?: HTMLAttributes['class'];
class?: any;
}>();
</script>

View File

@@ -1,10 +1,8 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
const props = defineProps<{
class?: HTMLAttributes['class'];
class?: any;
}>();
</script>

View File

@@ -1,10 +1,8 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
const props = defineProps<{
class?: HTMLAttributes['class'];
class?: any;
}>();
</script>

View File

@@ -1,9 +1,9 @@
<script setup lang="ts">
import type { CheckboxRootEmits, CheckboxRootProps } from 'radix-vue';
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { CheckIcon } from '@radix-icons/vue';
import {
@@ -12,9 +12,7 @@ import {
useForwardPropsEmits,
} from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & CheckboxRootProps
>();
const props = defineProps<{ class?: any } & CheckboxRootProps>();
const emits = defineEmits<CheckboxRootEmits>();
const delegatedProps = computed(() => {

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { CheckIcon } from '@radix-icons/vue';
import {
@@ -12,9 +12,7 @@ import {
useForwardPropsEmits,
} from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & ContextMenuCheckboxItemProps
>();
const props = defineProps<{ class?: any } & ContextMenuCheckboxItemProps>();
const emits = defineEmits<ContextMenuCheckboxItemEmits>();
const delegatedProps = computed(() => {

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import {
ContextMenuContent,
@@ -11,9 +11,7 @@ import {
useForwardPropsEmits,
} from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & ContextMenuContentProps
>();
const props = defineProps<{ class?: any } & ContextMenuContentProps>();
const emits = defineEmits<ContextMenuContentEmits>();
const delegatedProps = computed(() => {

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import {
ContextMenuItem,
@@ -11,7 +11,7 @@ import {
} from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class']; inset?: boolean } & ContextMenuItemProps
{ class?: any; inset?: boolean } & ContextMenuItemProps
>();
const emits = defineEmits<ContextMenuItemEmits>();

View File

@@ -1,12 +1,12 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { ContextMenuLabel, type ContextMenuLabelProps } from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class']; inset?: boolean } & ContextMenuLabelProps
{ class?: any; inset?: boolean } & ContextMenuLabelProps
>();
const delegatedProps = computed(() => {

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { DotFilledIcon } from '@radix-icons/vue';
import {
@@ -12,9 +12,7 @@ import {
useForwardPropsEmits,
} from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & ContextMenuRadioItemProps
>();
const props = defineProps<{ class?: any } & ContextMenuRadioItemProps>();
const emits = defineEmits<ContextMenuRadioItemEmits>();
const delegatedProps = computed(() => {

View File

@@ -1,16 +1,14 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import {
ContextMenuSeparator,
type ContextMenuSeparatorProps,
} from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & ContextMenuSeparatorProps
>();
const props = defineProps<{ class?: any } & ContextMenuSeparatorProps>();
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;

View File

@@ -1,10 +1,8 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
const props = defineProps<{
class?: HTMLAttributes['class'];
class?: any;
}>();
</script>

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import {
ContextMenuSubContent,
@@ -10,9 +10,7 @@ import {
useForwardPropsEmits,
} from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & DropdownMenuSubContentProps
>();
const props = defineProps<{ class?: any } & DropdownMenuSubContentProps>();
const emits = defineEmits<DropdownMenuSubContentEmits>();
const delegatedProps = computed(() => {

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { ChevronRightIcon } from '@radix-icons/vue';
import {
@@ -12,7 +12,7 @@ import {
const props = defineProps<
{
class?: HTMLAttributes['class'];
class?: any;
inset?: boolean;
} & ContextMenuSubTriggerProps
>();

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { Cross2Icon } from '@radix-icons/vue';
import {

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import {
DialogDescription,
@@ -9,9 +9,7 @@ import {
useForwardProps,
} from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & DialogDescriptionProps
>();
const props = defineProps<{ class?: any } & DialogDescriptionProps>();
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;

View File

@@ -1,9 +1,7 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared/utils';
import { cn } from '@vben-core/shared';
const props = defineProps<{ class?: HTMLAttributes['class'] }>();
const props = defineProps<{ class?: any }>();
</script>
<template>

View File

@@ -1,10 +1,8 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
const props = defineProps<{
class?: HTMLAttributes['class'];
class?: any;
}>();
</script>

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import {
DialogClose,
@@ -13,9 +13,7 @@ import {
useForwardPropsEmits,
} from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & DialogContentProps
>();
const props = defineProps<{ class?: any } & DialogContentProps>();
const emits = defineEmits<DialogContentEmits>();
const delegatedProps = computed(() => {

View File

@@ -1,13 +1,11 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { DialogTitle, type DialogTitleProps, useForwardProps } from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & DialogTitleProps
>();
const props = defineProps<{ class?: any } & DialogTitleProps>();
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { CheckIcon } from '@radix-icons/vue';
import {
@@ -12,9 +12,7 @@ import {
useForwardPropsEmits,
} from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & DropdownMenuCheckboxItemProps
>();
const props = defineProps<{ class?: any } & DropdownMenuCheckboxItemProps>();
const emits = defineEmits<DropdownMenuCheckboxItemEmits>();
const delegatedProps = computed(() => {

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import {
DropdownMenuContent,
@@ -12,7 +12,7 @@ import {
} from 'radix-vue';
const props = withDefaults(
defineProps<{ class?: HTMLAttributes['class'] } & DropdownMenuContentProps>(),
defineProps<{ class?: any } & DropdownMenuContentProps>(),
{
sideOffset: 4,
},

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import {
DropdownMenuItem,
@@ -10,7 +10,7 @@ import {
} from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class']; inset?: boolean } & DropdownMenuItemProps
{ class?: any; inset?: boolean } & DropdownMenuItemProps
>();
const delegatedProps = computed(() => {

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import {
DropdownMenuLabel,
@@ -10,7 +10,7 @@ import {
} from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class']; inset?: boolean } & DropdownMenuLabelProps
{ class?: any; inset?: boolean } & DropdownMenuLabelProps
>();
const delegatedProps = computed(() => {

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { DotFilledIcon } from '@radix-icons/vue';
import {
@@ -12,9 +12,7 @@ import {
useForwardPropsEmits,
} from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & DropdownMenuRadioItemProps
>();
const props = defineProps<{ class?: any } & DropdownMenuRadioItemProps>();
const emits = defineEmits<DropdownMenuRadioItemEmits>();

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import {
DropdownMenuSeparator,
@@ -10,7 +10,7 @@ import {
const props = defineProps<
{
class?: HTMLAttributes['class'];
class?: any;
} & DropdownMenuSeparatorProps
>();

View File

@@ -1,10 +1,8 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
const props = defineProps<{
class?: HTMLAttributes['class'];
class?: any;
}>();
</script>

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import {
DropdownMenuSubContent,
@@ -10,9 +10,7 @@ import {
useForwardPropsEmits,
} from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & DropdownMenuSubContentProps
>();
const props = defineProps<{ class?: any } & DropdownMenuSubContentProps>();
const emits = defineEmits<DropdownMenuSubContentEmits>();
const delegatedProps = computed(() => {

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { ChevronRightIcon } from '@radix-icons/vue';
import {
@@ -10,9 +10,7 @@ import {
useForwardProps,
} from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & DropdownMenuSubTriggerProps
>();
const props = defineProps<{ class?: any } & DropdownMenuSubTriggerProps>();
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;

View File

@@ -0,0 +1,19 @@
<script lang="ts" setup>
import { Slot } from 'radix-vue';
import { useFormField } from './useFormField';
const { error, formDescriptionId, formItemId, formMessageId } = useFormField();
</script>
<template>
<Slot
:id="formItemId"
:aria-describedby="
!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`
"
:aria-invalid="!!error"
>
<slot></slot>
</Slot>
</template>

View File

@@ -0,0 +1,20 @@
<script lang="ts" setup>
import { cn } from '@vben-core/shared/utils';
import { useFormField } from './useFormField';
const props = defineProps<{
class?: any;
}>();
const { formDescriptionId } = useFormField();
</script>
<template>
<p
:id="formDescriptionId"
:class="cn('text-muted-foreground text-sm', props.class)"
>
<slot></slot>
</p>
</template>

View File

@@ -0,0 +1,20 @@
<script lang="ts" setup>
import { provide, useId } from 'vue';
import { cn } from '@vben-core/shared/utils';
import { FORM_ITEM_INJECTION_KEY } from './injectionKeys';
const props = defineProps<{
class?: any;
}>();
const id = useId() as string;
provide(FORM_ITEM_INJECTION_KEY, id);
</script>
<template>
<div :class="cn(props.class)">
<slot></slot>
</div>
</template>

View File

@@ -0,0 +1,18 @@
<script lang="ts" setup>
import type { LabelProps } from 'radix-vue';
import { cn } from '@vben-core/shared/utils';
import { Label } from '../label';
import { useFormField } from './useFormField';
const props = defineProps<{ class?: any } & LabelProps>();
const { formItemId } = useFormField();
</script>
<template>
<Label :class="cn(props.class)" :for="formItemId">
<slot></slot>
</Label>
</template>

View File

@@ -0,0 +1,18 @@
<script lang="ts" setup>
import { toValue } from 'vue';
import { ErrorMessage } from 'vee-validate';
import { useFormField } from './useFormField';
const { formMessageId, name } = useFormField();
</script>
<template>
<ErrorMessage
:id="formMessageId"
:name="toValue(name)"
as="p"
class="text-destructive text-[0.8rem]"
/>
</template>

View File

@@ -0,0 +1,11 @@
export { default as FormControl } from './FormControl.vue';
export { default as FormDescription } from './FormDescription.vue';
export { default as FormItem } from './FormItem.vue';
export { default as FormLabel } from './FormLabel.vue';
export { default as FormMessage } from './FormMessage.vue';
export { FORM_ITEM_INJECTION_KEY } from './injectionKeys';
export {
Field as FormField,
FieldArray as FormFieldArray,
Form,
} from 'vee-validate';

View File

@@ -0,0 +1,4 @@
import type { InjectionKey } from 'vue';
// eslint-disable-next-line symbol-description
export const FORM_ITEM_INJECTION_KEY = Symbol() as InjectionKey<string>;

View File

@@ -0,0 +1,38 @@
import { inject } from 'vue';
import {
FieldContextKey,
useFieldError,
useIsFieldDirty,
useIsFieldTouched,
useIsFieldValid,
} from 'vee-validate';
import { FORM_ITEM_INJECTION_KEY } from './injectionKeys';
export function useFormField() {
const fieldContext = inject(FieldContextKey);
const fieldItemContext = inject(FORM_ITEM_INJECTION_KEY);
if (!fieldContext)
throw new Error('useFormField should be used within <FormField>');
const { name } = fieldContext;
const id = fieldItemContext;
const fieldState = {
error: useFieldError(name),
isDirty: useIsFieldDirty(name),
isTouched: useIsFieldTouched(name),
valid: useIsFieldValid(name),
};
return {
formDescriptionId: `${id}-form-item-description`,
formItemId: `${id}-form-item`,
formMessageId: `${id}-form-item-message`,
id,
name,
...fieldState,
};
}

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import {
HoverCardContent,

View File

@@ -1,12 +1,10 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { useVModel } from '@vueuse/core';
const props = defineProps<{
class?: HTMLAttributes['class'];
class?: any;
defaultValue?: number | string;
modelValue?: number | string;
}>();
@@ -26,7 +24,7 @@ const modelValue = useVModel(props, 'modelValue', emits, {
v-model="modelValue"
:class="
cn(
'border-input placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full rounded-md border bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50',
'border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50',
props.class,
)
"

View File

@@ -0,0 +1,29 @@
<script setup lang="ts">
import { computed } from 'vue';
import { cn } from '@vben-core/shared/utils';
import { Label, type LabelProps } from 'radix-vue';
const props = defineProps<{ class?: any } & LabelProps>();
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;
return delegated;
});
</script>
<template>
<Label
v-bind="delegatedProps"
:class="
cn(
'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
props.class,
)
"
>
<slot></slot>
</Label>
</template>

View File

@@ -0,0 +1 @@
export { default as Label } from './Label.vue';

View File

@@ -1,15 +1,13 @@
<script setup lang="ts">
import type { NumberFieldRootEmits, NumberFieldRootProps } from 'radix-vue';
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { NumberFieldRoot, useForwardPropsEmits } from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & NumberFieldRootProps
>();
const props = defineProps<{ class?: any } & NumberFieldRootProps>();
const emits = defineEmits<NumberFieldRootEmits>();
const delegatedProps = computed(() => {

View File

@@ -1,10 +1,8 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
const props = defineProps<{
class?: HTMLAttributes['class'];
class?: any;
}>();
</script>

View File

@@ -1,16 +1,14 @@
<script setup lang="ts">
import type { NumberFieldDecrementProps } from 'radix-vue';
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { Minus } from 'lucide-vue-next';
import { NumberFieldDecrement, useForwardProps } from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & NumberFieldDecrementProps
>();
const props = defineProps<{ class?: any } & NumberFieldDecrementProps>();
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;

View File

@@ -1,16 +1,14 @@
<script setup lang="ts">
import type { NumberFieldIncrementProps } from 'radix-vue';
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { Plus } from 'lucide-vue-next';
import { NumberFieldIncrement, useForwardProps } from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & NumberFieldIncrementProps
>();
const props = defineProps<{ class?: any } & NumberFieldIncrementProps>();
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;

View File

@@ -1,5 +1,5 @@
<script setup lang="ts">
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { NumberFieldInput } from 'radix-vue';
</script>

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import {
PinInputRoot,
@@ -10,9 +10,7 @@ import {
useForwardPropsEmits,
} from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & PinInputRootProps
>();
const props = defineProps<{ class?: any } & PinInputRootProps>();
const emits = defineEmits<PinInputRootEmits>();
const delegatedProps = computed(() => {

View File

@@ -1,13 +1,11 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import { Primitive, type PrimitiveProps, useForwardProps } from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & PrimitiveProps
>();
const props = defineProps<{ class?: any } & PrimitiveProps>();
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;
return delegated;

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import {
PinInputInput,
@@ -9,9 +9,7 @@ import {
useForwardProps,
} from 'radix-vue';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & PinInputInputProps
>();
const props = defineProps<{ class?: any } & PinInputInputProps>();
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { cn } from '@vben-core/shared';
import { cn } from '@vben-core/shared/utils';
import {
PopoverContent,
@@ -16,7 +16,7 @@ defineOptions({
});
const props = withDefaults(
defineProps<{ class?: HTMLAttributes['class'] } & PopoverContentProps>(),
defineProps<{ class?: any } & PopoverContentProps>(),
{
align: 'center',
sideOffset: 4,

Some files were not shown because too many files have changed in this diff Show More