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:
@@ -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;
|
||||
}
|
@@ -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',
|
||||
|
@@ -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>(), {
|
||||
|
@@ -1,2 +1,3 @@
|
||||
export type * from './button';
|
||||
export { default as VbenButton } from './button.vue';
|
||||
export { default as VbenIconButton } from './icon-button.vue';
|
||||
|
@@ -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>
|
||||
|
@@ -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';
|
||||
|
||||
|
@@ -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>
|
@@ -0,0 +1 @@
|
||||
export { default as VbenExpandableArrow } from './expandable-arrow.vue';
|
@@ -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>
|
||||
|
@@ -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<{
|
||||
// 没有是否显示默认图标
|
||||
|
@@ -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';
|
||||
|
@@ -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" />
|
||||
|
@@ -1,2 +0,0 @@
|
||||
export { default as VbenInput } from './input.vue';
|
||||
export type * from './types';
|
@@ -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>
|
@@ -1,25 +0,0 @@
|
||||
interface InputProps {
|
||||
class?: any;
|
||||
/**
|
||||
* 错误提示信息
|
||||
*/
|
||||
errorTip?: string;
|
||||
/**
|
||||
* 输入框的 label
|
||||
*/
|
||||
label?: string;
|
||||
/**
|
||||
* 输入框的 name
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* 是否显示密码强度
|
||||
*/
|
||||
passwordStrength?: boolean;
|
||||
/**
|
||||
* 输入框的校验状态
|
||||
*/
|
||||
status?: 'default' | 'error';
|
||||
}
|
||||
|
||||
export type { InputProps };
|
@@ -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';
|
||||
|
||||
|
@@ -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';
|
||||
|
||||
|
@@ -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>
|
||||
|
@@ -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 };
|
||||
|
@@ -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>
|
||||
|
@@ -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';
|
||||
|
||||
|
@@ -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>();
|
||||
|
||||
|
@@ -0,0 +1 @@
|
||||
export { default as VbenSelect } from './select.vue';
|
@@ -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>
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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>
|
@@ -1 +1,2 @@
|
||||
export { default as VbenHelpTooltip } from './help-tooltip.vue';
|
||||
export { default as VbenTooltip } from './tooltip.vue';
|
||||
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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';
|
@@ -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'];
|
||||
}>(),
|
||||
|
@@ -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>
|
||||
|
@@ -1,8 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class'];
|
||||
class?: any;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -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>(), {
|
||||
|
@@ -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>;
|
||||
|
@@ -1,3 +1,5 @@
|
||||
export * from './button';
|
||||
|
||||
export { default as Button } from './Button.vue';
|
||||
|
||||
export type * from './types';
|
||||
|
@@ -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;
|
@@ -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>
|
||||
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -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(() => {
|
||||
|
@@ -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(() => {
|
||||
|
@@ -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(() => {
|
||||
|
@@ -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>();
|
||||
|
||||
|
@@ -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(() => {
|
||||
|
@@ -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(() => {
|
||||
|
@@ -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;
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -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(() => {
|
||||
|
@@ -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
|
||||
>();
|
||||
|
@@ -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 {
|
||||
|
@@ -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;
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -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(() => {
|
||||
|
@@ -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;
|
||||
|
@@ -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(() => {
|
||||
|
@@ -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,
|
||||
},
|
||||
|
@@ -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(() => {
|
||||
|
@@ -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(() => {
|
||||
|
@@ -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>();
|
||||
|
||||
|
@@ -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
|
||||
>();
|
||||
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -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(() => {
|
||||
|
@@ -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;
|
||||
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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';
|
@@ -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>;
|
@@ -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,
|
||||
};
|
||||
}
|
@@ -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,
|
||||
|
@@ -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,
|
||||
)
|
||||
"
|
||||
|
@@ -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>
|
@@ -0,0 +1 @@
|
||||
export { default as Label } from './Label.vue';
|
@@ -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(() => {
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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>
|
||||
|
@@ -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(() => {
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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,
|
||||
|
@@ -0,0 +1,29 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import {
|
||||
RadioGroupRoot,
|
||||
type RadioGroupRootEmits,
|
||||
type RadioGroupRootProps,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & RadioGroupRootProps>();
|
||||
const emits = defineEmits<RadioGroupRootEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<RadioGroupRoot :class="cn('grid gap-2', props.class)" v-bind="forwarded">
|
||||
<slot></slot>
|
||||
</RadioGroupRoot>
|
||||
</template>
|
@@ -0,0 +1,39 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { CheckIcon } from '@radix-icons/vue';
|
||||
import {
|
||||
RadioGroupIndicator,
|
||||
RadioGroupItem,
|
||||
type RadioGroupItemProps,
|
||||
useForwardProps,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & RadioGroupItemProps>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwardedProps = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<RadioGroupItem
|
||||
v-bind="forwardedProps"
|
||||
:class="
|
||||
cn(
|
||||
'border-primary text-primary focus-visible:ring-ring aspect-square h-4 w-4 rounded-full border shadow focus:outline-none focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<RadioGroupIndicator class="flex items-center justify-center">
|
||||
<CheckIcon class="fill-primary h-3.5 w-3.5" />
|
||||
</RadioGroupIndicator>
|
||||
</RadioGroupItem>
|
||||
</template>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user