refactor: change the shadcn-ui directory and remove rarely used components (#4626)
This commit is contained in:
@@ -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 { ChevronDown } from 'lucide-vue-next';
|
||||
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">
|
||||
<ChevronDown
|
||||
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';
|
25
packages/@core/ui-kit/shadcn-ui/src/ui/avatar/Avatar.vue
Normal file
25
packages/@core/ui-kit/shadcn-ui/src/ui/avatar/Avatar.vue
Normal file
@@ -0,0 +1,25 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { AvatarRoot } from 'radix-vue';
|
||||
|
||||
import { avatarVariant, type AvatarVariants } from './avatar';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
class?: any;
|
||||
shape?: AvatarVariants['shape'];
|
||||
size?: AvatarVariants['size'];
|
||||
}>(),
|
||||
{
|
||||
shape: 'circle',
|
||||
size: 'sm',
|
||||
},
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AvatarRoot :class="cn(avatarVariant({ size, shape }), props.class)">
|
||||
<slot></slot>
|
||||
</AvatarRoot>
|
||||
</template>
|
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { AvatarFallback, type AvatarFallbackProps } from 'radix-vue';
|
||||
|
||||
const props = defineProps<AvatarFallbackProps>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AvatarFallback v-bind="props">
|
||||
<slot></slot>
|
||||
</AvatarFallback>
|
||||
</template>
|
@@ -0,0 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { AvatarImage, type AvatarImageProps } from 'radix-vue';
|
||||
|
||||
const props = defineProps<AvatarImageProps>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AvatarImage v-bind="props" class="h-full w-full object-cover" />
|
||||
</template>
|
20
packages/@core/ui-kit/shadcn-ui/src/ui/avatar/avatar.ts
Normal file
20
packages/@core/ui-kit/shadcn-ui/src/ui/avatar/avatar.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { cva, type VariantProps } from 'class-variance-authority';
|
||||
|
||||
export const avatarVariant = cva(
|
||||
'inline-flex items-center justify-center font-normal text-foreground select-none shrink-0 bg-secondary overflow-hidden',
|
||||
{
|
||||
variants: {
|
||||
shape: {
|
||||
circle: 'rounded-full',
|
||||
square: 'rounded-md',
|
||||
},
|
||||
size: {
|
||||
base: 'h-16 w-16 text-2xl',
|
||||
lg: 'h-32 w-32 text-5xl',
|
||||
sm: 'h-10 w-10 text-xs',
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
export type AvatarVariants = VariantProps<typeof avatarVariant>;
|
4
packages/@core/ui-kit/shadcn-ui/src/ui/avatar/index.ts
Normal file
4
packages/@core/ui-kit/shadcn-ui/src/ui/avatar/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './avatar';
|
||||
export { default as Avatar } from './Avatar.vue';
|
||||
export { default as AvatarFallback } from './AvatarFallback.vue';
|
||||
export { default as AvatarImage } from './AvatarImage.vue';
|
16
packages/@core/ui-kit/shadcn-ui/src/ui/badge/Badge.vue
Normal file
16
packages/@core/ui-kit/shadcn-ui/src/ui/badge/Badge.vue
Normal file
@@ -0,0 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { type BadgeVariants, badgeVariants } from './badge';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: any;
|
||||
variant?: BadgeVariants['variant'];
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="cn(badgeVariants({ variant }), props.class)">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
23
packages/@core/ui-kit/shadcn-ui/src/ui/badge/badge.ts
Normal file
23
packages/@core/ui-kit/shadcn-ui/src/ui/badge/badge.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { cva, type VariantProps } from 'class-variance-authority';
|
||||
|
||||
export const badgeVariants = cva(
|
||||
'inline-flex items-center rounded-md border border-border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
|
||||
{
|
||||
defaultVariants: {
|
||||
variant: 'default',
|
||||
},
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
'border-transparent bg-accent hover:bg-accent text-primary-foreground shadow',
|
||||
destructive:
|
||||
'border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive-hover',
|
||||
outline: 'text-foreground',
|
||||
secondary:
|
||||
'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
export type BadgeVariants = VariantProps<typeof badgeVariants>;
|
3
packages/@core/ui-kit/shadcn-ui/src/ui/badge/index.ts
Normal file
3
packages/@core/ui-kit/shadcn-ui/src/ui/badge/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './badge';
|
||||
|
||||
export { default as Badge } from './Badge.vue';
|
@@ -0,0 +1,11 @@
|
||||
<script lang="ts" setup>
|
||||
const props = defineProps<{
|
||||
class?: any;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nav :class="props.class" aria-label="breadcrumb" role="navigation">
|
||||
<slot></slot>
|
||||
</nav>
|
||||
</template>
|
@@ -0,0 +1,22 @@
|
||||
<script lang="ts" setup>
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { MoreHorizontal } from 'lucide-vue-next';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: any;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span
|
||||
:class="cn('flex h-9 w-9 items-center justify-center', props.class)"
|
||||
aria-hidden="true"
|
||||
role="presentation"
|
||||
>
|
||||
<slot>
|
||||
<MoreHorizontal class="h-4 w-4" />
|
||||
</slot>
|
||||
<span class="sr-only">More</span>
|
||||
</span>
|
||||
</template>
|
@@ -0,0 +1,17 @@
|
||||
<script lang="ts" setup>
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: any;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li
|
||||
:class="
|
||||
cn('hover:text-foreground inline-flex items-center gap-1.5', props.class)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
</li>
|
||||
</template>
|
@@ -0,0 +1,19 @@
|
||||
<script lang="ts" setup>
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { Primitive, type PrimitiveProps } from 'radix-vue';
|
||||
|
||||
const props = withDefaults(defineProps<{ class?: any } & PrimitiveProps>(), {
|
||||
as: 'a',
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Primitive
|
||||
:as="as"
|
||||
:as-child="asChild"
|
||||
:class="cn('hover:text-foreground transition-colors', props.class)"
|
||||
>
|
||||
<slot></slot>
|
||||
</Primitive>
|
||||
</template>
|
@@ -0,0 +1,20 @@
|
||||
<script lang="ts" setup>
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: any;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ol
|
||||
:class="
|
||||
cn(
|
||||
'text-muted-foreground flex flex-wrap items-center gap-1.5 break-words text-sm sm:gap-2.5',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
</ol>
|
||||
</template>
|
@@ -0,0 +1,18 @@
|
||||
<script lang="ts" setup>
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: any;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span
|
||||
:class="cn('text-foreground font-normal', props.class)"
|
||||
aria-current="page"
|
||||
aria-disabled="true"
|
||||
role="link"
|
||||
>
|
||||
<slot></slot>
|
||||
</span>
|
||||
</template>
|
@@ -0,0 +1,21 @@
|
||||
<script lang="ts" setup>
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { ChevronRight } from 'lucide-vue-next';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: any;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li
|
||||
:class="cn('[&>svg]:size-3.5', props.class)"
|
||||
aria-hidden="true"
|
||||
role="presentation"
|
||||
>
|
||||
<slot>
|
||||
<ChevronRight />
|
||||
</slot>
|
||||
</li>
|
||||
</template>
|
@@ -0,0 +1,7 @@
|
||||
export { default as Breadcrumb } from './Breadcrumb.vue';
|
||||
export { default as BreadcrumbEllipsis } from './BreadcrumbEllipsis.vue';
|
||||
export { default as BreadcrumbItem } from './BreadcrumbItem.vue';
|
||||
export { default as BreadcrumbLink } from './BreadcrumbLink.vue';
|
||||
export { default as BreadcrumbList } from './BreadcrumbList.vue';
|
||||
export { default as BreadcrumbPage } from './BreadcrumbPage.vue';
|
||||
export { default as BreadcrumbSeparator } from './BreadcrumbSeparator.vue';
|
30
packages/@core/ui-kit/shadcn-ui/src/ui/button/Button.vue
Normal file
30
packages/@core/ui-kit/shadcn-ui/src/ui/button/Button.vue
Normal file
@@ -0,0 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
import type { ButtonVariants, ButtonVariantSize } from './types';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { Primitive, type PrimitiveProps } from 'radix-vue';
|
||||
|
||||
import { buttonVariants } from './button';
|
||||
|
||||
interface Props extends PrimitiveProps {
|
||||
class?: any;
|
||||
size?: ButtonVariantSize;
|
||||
variant?: ButtonVariants;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
as: 'button',
|
||||
class: '',
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Primitive
|
||||
:as="as"
|
||||
:as-child="asChild"
|
||||
:class="cn(buttonVariants({ variant, size }), props.class)"
|
||||
>
|
||||
<slot></slot>
|
||||
</Primitive>
|
||||
</template>
|
34
packages/@core/ui-kit/shadcn-ui/src/ui/button/button.ts
Normal file
34
packages/@core/ui-kit/shadcn-ui/src/ui/button/button.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
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',
|
||||
{
|
||||
defaultVariants: {
|
||||
size: 'default',
|
||||
variant: 'default',
|
||||
},
|
||||
variants: {
|
||||
size: {
|
||||
default: 'h-9 px-4 py-2',
|
||||
icon: 'h-8 w-8 rounded-sm px-1 text-lg',
|
||||
lg: 'h-10 rounded-md px-8',
|
||||
sm: 'h-8 rounded-md px-3 text-xs',
|
||||
xs: 'h-8 w-8 rounded-sm px-1 text-xs',
|
||||
},
|
||||
variant: {
|
||||
default:
|
||||
'bg-primary text-primary-foreground shadow hover:bg-primary/90',
|
||||
destructive:
|
||||
'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive-hover',
|
||||
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
||||
heavy: 'hover:bg-heavy hover:text-heavy-foreground',
|
||||
icon: 'hover:bg-accent hover:text-accent-foreground text-foreground/80',
|
||||
link: 'text-primary underline-offset-4 hover:underline',
|
||||
outline:
|
||||
'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',
|
||||
secondary:
|
||||
'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
5
packages/@core/ui-kit/shadcn-ui/src/ui/button/index.ts
Normal file
5
packages/@core/ui-kit/shadcn-ui/src/ui/button/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export * from './button';
|
||||
|
||||
export { default as Button } from './Button.vue';
|
||||
|
||||
export type * from './types';
|
20
packages/@core/ui-kit/shadcn-ui/src/ui/button/types.ts
Normal file
20
packages/@core/ui-kit/shadcn-ui/src/ui/button/types.ts
Normal 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;
|
20
packages/@core/ui-kit/shadcn-ui/src/ui/card/Card.vue
Normal file
20
packages/@core/ui-kit/shadcn-ui/src/ui/card/Card.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: any;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="
|
||||
cn(
|
||||
'bg-card text-card-foreground border-border rounded-xl border',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
13
packages/@core/ui-kit/shadcn-ui/src/ui/card/CardContent.vue
Normal file
13
packages/@core/ui-kit/shadcn-ui/src/ui/card/CardContent.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: any;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="cn('p-6 pt-0', props.class)">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
@@ -0,0 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: any;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<p :class="cn('text-muted-foreground text-sm', props.class)">
|
||||
<slot></slot>
|
||||
</p>
|
||||
</template>
|
13
packages/@core/ui-kit/shadcn-ui/src/ui/card/CardFooter.vue
Normal file
13
packages/@core/ui-kit/shadcn-ui/src/ui/card/CardFooter.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: any;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="cn('flex items-center p-6 pt-0', props.class)">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
13
packages/@core/ui-kit/shadcn-ui/src/ui/card/CardHeader.vue
Normal file
13
packages/@core/ui-kit/shadcn-ui/src/ui/card/CardHeader.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: any;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="cn('flex flex-col gap-y-1.5 p-5', props.class)">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
13
packages/@core/ui-kit/shadcn-ui/src/ui/card/CardTitle.vue
Normal file
13
packages/@core/ui-kit/shadcn-ui/src/ui/card/CardTitle.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: any;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h3 :class="cn('font-semibold leading-none tracking-tight', props.class)">
|
||||
<slot></slot>
|
||||
</h3>
|
||||
</template>
|
6
packages/@core/ui-kit/shadcn-ui/src/ui/card/index.ts
Normal file
6
packages/@core/ui-kit/shadcn-ui/src/ui/card/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export { default as Card } from './Card.vue';
|
||||
export { default as CardContent } from './CardContent.vue';
|
||||
export { default as CardDescription } from './CardDescription.vue';
|
||||
export { default as CardFooter } from './CardFooter.vue';
|
||||
export { default as CardHeader } from './CardHeader.vue';
|
||||
export { default as CardTitle } from './CardTitle.vue';
|
45
packages/@core/ui-kit/shadcn-ui/src/ui/checkbox/Checkbox.vue
Normal file
45
packages/@core/ui-kit/shadcn-ui/src/ui/checkbox/Checkbox.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<script setup lang="ts">
|
||||
import type { CheckboxRootEmits, CheckboxRootProps } from 'radix-vue';
|
||||
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { Check } from 'lucide-vue-next';
|
||||
import {
|
||||
CheckboxIndicator,
|
||||
CheckboxRoot,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & CheckboxRootProps>();
|
||||
const emits = defineEmits<CheckboxRootEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<CheckboxRoot
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'focus-visible:ring-ring data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground border-border peer h-4 w-4 shrink-0 rounded-sm border focus-visible:outline-none focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<CheckboxIndicator
|
||||
class="flex h-full w-full items-center justify-center text-current"
|
||||
>
|
||||
<slot>
|
||||
<Check class="h-4 w-4" />
|
||||
</slot>
|
||||
</CheckboxIndicator>
|
||||
</CheckboxRoot>
|
||||
</template>
|
1
packages/@core/ui-kit/shadcn-ui/src/ui/checkbox/index.ts
Normal file
1
packages/@core/ui-kit/shadcn-ui/src/ui/checkbox/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as Checkbox } from './Checkbox.vue';
|
@@ -0,0 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import type { ContextMenuRootEmits, ContextMenuRootProps } from 'radix-vue';
|
||||
|
||||
import { ContextMenuRoot, useForwardPropsEmits } from 'radix-vue';
|
||||
|
||||
const props = withDefaults(defineProps<ContextMenuRootProps>(), {
|
||||
modal: false,
|
||||
});
|
||||
const emits = defineEmits<ContextMenuRootEmits>();
|
||||
|
||||
const forwarded = useForwardPropsEmits(props, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContextMenuRoot v-bind="forwarded">
|
||||
<slot></slot>
|
||||
</ContextMenuRoot>
|
||||
</template>
|
@@ -0,0 +1,44 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { Check } from 'lucide-vue-next';
|
||||
import {
|
||||
ContextMenuCheckboxItem,
|
||||
type ContextMenuCheckboxItemEmits,
|
||||
type ContextMenuCheckboxItemProps,
|
||||
ContextMenuItemIndicator,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & ContextMenuCheckboxItemProps>();
|
||||
const emits = defineEmits<ContextMenuCheckboxItemEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContextMenuCheckboxItem
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'focus:bg-accent focus:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<ContextMenuItemIndicator>
|
||||
<Check class="h-4 w-4" />
|
||||
</ContextMenuItemIndicator>
|
||||
</span>
|
||||
<slot></slot>
|
||||
</ContextMenuCheckboxItem>
|
||||
</template>
|
@@ -0,0 +1,40 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import {
|
||||
ContextMenuContent,
|
||||
type ContextMenuContentEmits,
|
||||
type ContextMenuContentProps,
|
||||
ContextMenuPortal,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & ContextMenuContentProps>();
|
||||
const emits = defineEmits<ContextMenuContentEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContextMenuPortal>
|
||||
<ContextMenuContent
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 border-border z-[1000] min-w-32 overflow-hidden rounded-md border p-1 shadow-md',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
</ContextMenuContent>
|
||||
</ContextMenuPortal>
|
||||
</template>
|
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { ContextMenuGroup, type ContextMenuGroupProps } from 'radix-vue';
|
||||
|
||||
const props = defineProps<ContextMenuGroupProps>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContextMenuGroup v-bind="props">
|
||||
<slot></slot>
|
||||
</ContextMenuGroup>
|
||||
</template>
|
@@ -0,0 +1,40 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import {
|
||||
ContextMenuItem,
|
||||
type ContextMenuItemEmits,
|
||||
type ContextMenuItemProps,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<
|
||||
{ class?: any; inset?: boolean } & ContextMenuItemProps
|
||||
>();
|
||||
const emits = defineEmits<ContextMenuItemEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContextMenuItem
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'focus:bg-accent focus:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
inset && 'pl-8',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
</ContextMenuItem>
|
||||
</template>
|
@@ -0,0 +1,32 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { ContextMenuLabel, type ContextMenuLabelProps } from 'radix-vue';
|
||||
|
||||
const props = defineProps<
|
||||
{ class?: any; inset?: boolean } & ContextMenuLabelProps
|
||||
>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContextMenuLabel
|
||||
v-bind="delegatedProps"
|
||||
:class="
|
||||
cn(
|
||||
'text-foreground px-2 py-1.5 text-sm font-semibold',
|
||||
inset && 'pl-8',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
</ContextMenuLabel>
|
||||
</template>
|
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { ContextMenuPortal, type ContextMenuPortalProps } from 'radix-vue';
|
||||
|
||||
const props = defineProps<ContextMenuPortalProps>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContextMenuPortal v-bind="props">
|
||||
<slot></slot>
|
||||
</ContextMenuPortal>
|
||||
</template>
|
@@ -0,0 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
ContextMenuRadioGroup,
|
||||
type ContextMenuRadioGroupEmits,
|
||||
type ContextMenuRadioGroupProps,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<ContextMenuRadioGroupProps>();
|
||||
const emits = defineEmits<ContextMenuRadioGroupEmits>();
|
||||
|
||||
const forwarded = useForwardPropsEmits(props, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContextMenuRadioGroup v-bind="forwarded">
|
||||
<slot></slot>
|
||||
</ContextMenuRadioGroup>
|
||||
</template>
|
@@ -0,0 +1,44 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { Circle } from 'lucide-vue-next';
|
||||
import {
|
||||
ContextMenuItemIndicator,
|
||||
ContextMenuRadioItem,
|
||||
type ContextMenuRadioItemEmits,
|
||||
type ContextMenuRadioItemProps,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & ContextMenuRadioItemProps>();
|
||||
const emits = defineEmits<ContextMenuRadioItemEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContextMenuRadioItem
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'focus:bg-accent focus:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<ContextMenuItemIndicator>
|
||||
<Circle class="h-2 w-2 fill-current" />
|
||||
</ContextMenuItemIndicator>
|
||||
</span>
|
||||
<slot></slot>
|
||||
</ContextMenuRadioItem>
|
||||
</template>
|
@@ -0,0 +1,25 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import {
|
||||
ContextMenuSeparator,
|
||||
type ContextMenuSeparatorProps,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & ContextMenuSeparatorProps>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContextMenuSeparator
|
||||
v-bind="delegatedProps"
|
||||
:class="cn('bg-border -mx-1 my-1 h-px', props.class)"
|
||||
/>
|
||||
</template>
|
@@ -0,0 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: any;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span
|
||||
:class="
|
||||
cn('text-muted-foreground ml-auto text-xs tracking-widest', props.class)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
</span>
|
||||
</template>
|
@@ -0,0 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
ContextMenuSub,
|
||||
type ContextMenuSubEmits,
|
||||
type ContextMenuSubProps,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<ContextMenuSubProps>();
|
||||
const emits = defineEmits<ContextMenuSubEmits>();
|
||||
|
||||
const forwarded = useForwardPropsEmits(props, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContextMenuSub v-bind="forwarded">
|
||||
<slot></slot>
|
||||
</ContextMenuSub>
|
||||
</template>
|
@@ -0,0 +1,37 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import {
|
||||
ContextMenuSubContent,
|
||||
type DropdownMenuSubContentEmits,
|
||||
type DropdownMenuSubContentProps,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & DropdownMenuSubContentProps>();
|
||||
const emits = defineEmits<DropdownMenuSubContentEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContextMenuSubContent
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 border-border z-50 min-w-32 overflow-hidden rounded-md border p-1 shadow-lg',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
</ContextMenuSubContent>
|
||||
</template>
|
@@ -0,0 +1,43 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { ChevronRight } from 'lucide-vue-next';
|
||||
import {
|
||||
ContextMenuSubTrigger,
|
||||
type ContextMenuSubTriggerProps,
|
||||
useForwardProps,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<
|
||||
{
|
||||
class?: any;
|
||||
inset?: boolean;
|
||||
} & ContextMenuSubTriggerProps
|
||||
>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwardedProps = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContextMenuSubTrigger
|
||||
v-bind="forwardedProps"
|
||||
:class="
|
||||
cn(
|
||||
'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none',
|
||||
inset && 'pl-8',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
<ChevronRight class="ml-auto h-4 w-4" />
|
||||
</ContextMenuSubTrigger>
|
||||
</template>
|
@@ -0,0 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
ContextMenuTrigger,
|
||||
type ContextMenuTriggerProps,
|
||||
useForwardProps,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<ContextMenuTriggerProps>();
|
||||
|
||||
const forwardedProps = useForwardProps(props);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContextMenuTrigger v-bind="forwardedProps">
|
||||
<slot></slot>
|
||||
</ContextMenuTrigger>
|
||||
</template>
|
14
packages/@core/ui-kit/shadcn-ui/src/ui/context-menu/index.ts
Normal file
14
packages/@core/ui-kit/shadcn-ui/src/ui/context-menu/index.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
export { default as ContextMenu } from './ContextMenu.vue';
|
||||
export { default as ContextMenuCheckboxItem } from './ContextMenuCheckboxItem.vue';
|
||||
export { default as ContextMenuContent } from './ContextMenuContent.vue';
|
||||
export { default as ContextMenuGroup } from './ContextMenuGroup.vue';
|
||||
export { default as ContextMenuItem } from './ContextMenuItem.vue';
|
||||
export { default as ContextMenuLabel } from './ContextMenuLabel.vue';
|
||||
export { default as ContextMenuRadioGroup } from './ContextMenuRadioGroup.vue';
|
||||
export { default as ContextMenuRadioItem } from './ContextMenuRadioItem.vue';
|
||||
export { default as ContextMenuSeparator } from './ContextMenuSeparator.vue';
|
||||
export { default as ContextMenuShortcut } from './ContextMenuShortcut.vue';
|
||||
export { default as ContextMenuSub } from './ContextMenuSub.vue';
|
||||
export { default as ContextMenuSubContent } from './ContextMenuSubContent.vue';
|
||||
export { default as ContextMenuSubTrigger } from './ContextMenuSubTrigger.vue';
|
||||
export { default as ContextMenuTrigger } from './ContextMenuTrigger.vue';
|
19
packages/@core/ui-kit/shadcn-ui/src/ui/dialog/Dialog.vue
Normal file
19
packages/@core/ui-kit/shadcn-ui/src/ui/dialog/Dialog.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
DialogRoot,
|
||||
type DialogRootEmits,
|
||||
type DialogRootProps,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<DialogRootProps>();
|
||||
const emits = defineEmits<DialogRootEmits>();
|
||||
|
||||
const forwarded = useForwardPropsEmits(props, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogRoot v-bind="forwarded">
|
||||
<slot></slot>
|
||||
</DialogRoot>
|
||||
</template>
|
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { DialogClose, type DialogCloseProps } from 'radix-vue';
|
||||
|
||||
const props = defineProps<DialogCloseProps>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogClose v-bind="props">
|
||||
<slot></slot>
|
||||
</DialogClose>
|
||||
</template>
|
@@ -0,0 +1,84 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { X } from 'lucide-vue-next';
|
||||
import {
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
type DialogContentEmits,
|
||||
type DialogContentProps,
|
||||
DialogPortal,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
import DialogOverlay from './DialogOverlay.vue';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<
|
||||
{
|
||||
class?: any;
|
||||
closeClass?: any;
|
||||
modal?: boolean;
|
||||
open?: boolean;
|
||||
showClose?: boolean;
|
||||
} & DialogContentProps
|
||||
>(),
|
||||
{ showClose: true },
|
||||
);
|
||||
const emits = defineEmits<{ close: [] } & DialogContentEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const {
|
||||
class: _,
|
||||
modal: _modal,
|
||||
open: _open,
|
||||
showClose: __,
|
||||
...delegated
|
||||
} = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
|
||||
const contentRef = ref<InstanceType<typeof DialogContent> | null>(null);
|
||||
|
||||
defineExpose({
|
||||
getContentRef: () => contentRef.value,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogPortal>
|
||||
<Transition name="fade">
|
||||
<DialogOverlay v-if="open && modal" @click="() => emits('close')" />
|
||||
</Transition>
|
||||
<DialogContent
|
||||
ref="contentRef"
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-top-[48%] fixed z-[1000] w-full p-6 shadow-lg outline-none sm:rounded-xl',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
|
||||
<DialogClose
|
||||
v-if="showClose"
|
||||
:class="
|
||||
cn(
|
||||
'data-[state=open]:bg-accent data-[state=open]:text-muted-foreground hover:bg-accent hover:text-accent-foreground text-foreground/80 flex-center absolute right-3 top-3 h-6 w-6 rounded-full px-1 text-lg opacity-70 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none',
|
||||
props.closeClass,
|
||||
)
|
||||
"
|
||||
@click="() => emits('close')"
|
||||
>
|
||||
<X class="h-4 w-4" />
|
||||
</DialogClose>
|
||||
</DialogContent>
|
||||
</DialogPortal>
|
||||
</template>
|
@@ -0,0 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import {
|
||||
DialogDescription,
|
||||
type DialogDescriptionProps,
|
||||
useForwardProps,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & DialogDescriptionProps>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwardedProps = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogDescription
|
||||
v-bind="forwardedProps"
|
||||
:class="cn('text-muted-foreground text-sm', props.class)"
|
||||
>
|
||||
<slot></slot>
|
||||
</DialogDescription>
|
||||
</template>
|
@@ -0,0 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
const props = defineProps<{ class?: any }>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="
|
||||
cn(
|
||||
'flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-x-2',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
@@ -0,0 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: any;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="cn('flex flex-col gap-y-1.5 text-center sm:text-left', props.class)"
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
@@ -0,0 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import { inject } from 'vue';
|
||||
|
||||
import { useScrollLock } from '@vben-core/composables';
|
||||
|
||||
useScrollLock();
|
||||
const id = inject('DISMISSABLE_MODAL_ID');
|
||||
</script>
|
||||
<template>
|
||||
<div
|
||||
:data-dismissable-modal="id"
|
||||
class="bg-overlay fixed inset-0 z-[1000]"
|
||||
></div>
|
||||
</template>
|
@@ -0,0 +1,66 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { X } from 'lucide-vue-next';
|
||||
import {
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
type DialogContentEmits,
|
||||
type DialogContentProps,
|
||||
DialogOverlay,
|
||||
DialogPortal,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & DialogContentProps>();
|
||||
const emits = defineEmits<DialogContentEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogPortal>
|
||||
<DialogOverlay
|
||||
class="data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 border-border fixed inset-0 z-[1000] grid place-items-center overflow-y-auto border bg-black/80"
|
||||
>
|
||||
<DialogContent
|
||||
:class="
|
||||
cn(
|
||||
'border-border bg-background relative z-50 my-8 grid w-full max-w-lg gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg md:w-full',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
v-bind="forwarded"
|
||||
@pointer-down-outside="
|
||||
(event) => {
|
||||
const originalEvent = event.detail.originalEvent;
|
||||
const target = originalEvent.target as HTMLElement;
|
||||
if (
|
||||
originalEvent.offsetX > target.clientWidth ||
|
||||
originalEvent.offsetY > target.clientHeight
|
||||
) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
|
||||
<DialogClose
|
||||
class="hover:bg-secondary absolute right-4 top-4 rounded-md p-0.5 transition-colors"
|
||||
>
|
||||
<X class="h-4 w-4" />
|
||||
<span class="sr-only">Close</span>
|
||||
</DialogClose>
|
||||
</DialogContent>
|
||||
</DialogOverlay>
|
||||
</DialogPortal>
|
||||
</template>
|
@@ -0,0 +1,28 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { DialogTitle, type DialogTitleProps, useForwardProps } from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & DialogTitleProps>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwardedProps = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogTitle
|
||||
v-bind="forwardedProps"
|
||||
:class="
|
||||
cn('text-lg font-semibold leading-none tracking-tight', props.class)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
</DialogTitle>
|
||||
</template>
|
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { DialogTrigger, type DialogTriggerProps } from 'radix-vue';
|
||||
|
||||
const props = defineProps<DialogTriggerProps>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogTrigger v-bind="props">
|
||||
<slot></slot>
|
||||
</DialogTrigger>
|
||||
</template>
|
9
packages/@core/ui-kit/shadcn-ui/src/ui/dialog/index.ts
Normal file
9
packages/@core/ui-kit/shadcn-ui/src/ui/dialog/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export { default as Dialog } from './Dialog.vue';
|
||||
export { default as DialogClose } from './DialogClose.vue';
|
||||
export { default as DialogContent } from './DialogContent.vue';
|
||||
export { default as DialogDescription } from './DialogDescription.vue';
|
||||
export { default as DialogFooter } from './DialogFooter.vue';
|
||||
export { default as DialogHeader } from './DialogHeader.vue';
|
||||
export { default as DialogScrollContent } from './DialogScrollContent.vue';
|
||||
export { default as DialogTitle } from './DialogTitle.vue';
|
||||
export { default as DialogTrigger } from './DialogTrigger.vue';
|
@@ -0,0 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
DropdownMenuRoot,
|
||||
type DropdownMenuRootEmits,
|
||||
type DropdownMenuRootProps,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = withDefaults(defineProps<DropdownMenuRootProps>(), {
|
||||
modal: false,
|
||||
});
|
||||
const emits = defineEmits<DropdownMenuRootEmits>();
|
||||
|
||||
const forwarded = useForwardPropsEmits(props, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenuRoot v-bind="forwarded">
|
||||
<slot></slot>
|
||||
</DropdownMenuRoot>
|
||||
</template>
|
@@ -0,0 +1,44 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { Check } from 'lucide-vue-next';
|
||||
import {
|
||||
DropdownMenuCheckboxItem,
|
||||
type DropdownMenuCheckboxItemEmits,
|
||||
type DropdownMenuCheckboxItemProps,
|
||||
DropdownMenuItemIndicator,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & DropdownMenuCheckboxItemProps>();
|
||||
const emits = defineEmits<DropdownMenuCheckboxItemEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenuCheckboxItem
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'focus:bg-accent focus:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<DropdownMenuItemIndicator>
|
||||
<Check class="h-4 w-4" />
|
||||
</DropdownMenuItemIndicator>
|
||||
</span>
|
||||
<slot></slot>
|
||||
</DropdownMenuCheckboxItem>
|
||||
</template>
|
@@ -0,0 +1,45 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import {
|
||||
DropdownMenuContent,
|
||||
type DropdownMenuContentEmits,
|
||||
type DropdownMenuContentProps,
|
||||
DropdownMenuPortal,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{ class?: any } & DropdownMenuContentProps>(),
|
||||
{
|
||||
sideOffset: 4,
|
||||
},
|
||||
);
|
||||
const emits = defineEmits<DropdownMenuContentEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenuPortal>
|
||||
<DropdownMenuContent
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 border-border z-[1000] min-w-32 overflow-hidden rounded-md border p-1 shadow-md',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenuPortal>
|
||||
</template>
|
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { DropdownMenuGroup, type DropdownMenuGroupProps } from 'radix-vue';
|
||||
|
||||
const props = defineProps<DropdownMenuGroupProps>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenuGroup v-bind="props">
|
||||
<slot></slot>
|
||||
</DropdownMenuGroup>
|
||||
</template>
|
@@ -0,0 +1,38 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import {
|
||||
DropdownMenuItem,
|
||||
type DropdownMenuItemProps,
|
||||
useForwardProps,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<
|
||||
{ class?: any; inset?: boolean } & DropdownMenuItemProps
|
||||
>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwardedProps = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenuItem
|
||||
v-bind="forwardedProps"
|
||||
:class="
|
||||
cn(
|
||||
'focus:bg-accent focus:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
inset && 'pl-8',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
</DropdownMenuItem>
|
||||
</template>
|
@@ -0,0 +1,34 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import {
|
||||
DropdownMenuLabel,
|
||||
type DropdownMenuLabelProps,
|
||||
useForwardProps,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<
|
||||
{ class?: any; inset?: boolean } & DropdownMenuLabelProps
|
||||
>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwardedProps = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenuLabel
|
||||
v-bind="forwardedProps"
|
||||
:class="
|
||||
cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', props.class)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
</DropdownMenuLabel>
|
||||
</template>
|
@@ -0,0 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
DropdownMenuRadioGroup,
|
||||
type DropdownMenuRadioGroupEmits,
|
||||
type DropdownMenuRadioGroupProps,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<DropdownMenuRadioGroupProps>();
|
||||
const emits = defineEmits<DropdownMenuRadioGroupEmits>();
|
||||
|
||||
const forwarded = useForwardPropsEmits(props, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenuRadioGroup v-bind="forwarded">
|
||||
<slot></slot>
|
||||
</DropdownMenuRadioGroup>
|
||||
</template>
|
@@ -0,0 +1,45 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { Circle } from 'lucide-vue-next';
|
||||
import {
|
||||
DropdownMenuItemIndicator,
|
||||
DropdownMenuRadioItem,
|
||||
type DropdownMenuRadioItemEmits,
|
||||
type DropdownMenuRadioItemProps,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & DropdownMenuRadioItemProps>();
|
||||
|
||||
const emits = defineEmits<DropdownMenuRadioItemEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenuRadioItem
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'focus:bg-accent focus:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<DropdownMenuItemIndicator>
|
||||
<Circle class="h-2 w-2 fill-current" />
|
||||
</DropdownMenuItemIndicator>
|
||||
</span>
|
||||
<slot></slot>
|
||||
</DropdownMenuRadioItem>
|
||||
</template>
|
@@ -0,0 +1,29 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import {
|
||||
DropdownMenuSeparator,
|
||||
type DropdownMenuSeparatorProps,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<
|
||||
{
|
||||
class?: any;
|
||||
} & DropdownMenuSeparatorProps
|
||||
>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenuSeparator
|
||||
v-bind="delegatedProps"
|
||||
:class="cn('bg-border -mx-1 my-1 h-px', props.class)"
|
||||
/>
|
||||
</template>
|
@@ -0,0 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: any;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span :class="cn('ml-auto text-xs tracking-widest opacity-60', props.class)">
|
||||
<slot></slot>
|
||||
</span>
|
||||
</template>
|
@@ -0,0 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
DropdownMenuSub,
|
||||
type DropdownMenuSubEmits,
|
||||
type DropdownMenuSubProps,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<DropdownMenuSubProps>();
|
||||
const emits = defineEmits<DropdownMenuSubEmits>();
|
||||
|
||||
const forwarded = useForwardPropsEmits(props, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenuSub v-bind="forwarded">
|
||||
<slot></slot>
|
||||
</DropdownMenuSub>
|
||||
</template>
|
@@ -0,0 +1,37 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import {
|
||||
DropdownMenuSubContent,
|
||||
type DropdownMenuSubContentEmits,
|
||||
type DropdownMenuSubContentProps,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & DropdownMenuSubContentProps>();
|
||||
const emits = defineEmits<DropdownMenuSubContentEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenuSubContent
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 border-border z-50 min-w-32 overflow-hidden rounded-md border p-1 shadow-lg',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
</DropdownMenuSubContent>
|
||||
</template>
|
@@ -0,0 +1,37 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { ChevronRight } from 'lucide-vue-next';
|
||||
import {
|
||||
DropdownMenuSubTrigger,
|
||||
type DropdownMenuSubTriggerProps,
|
||||
useForwardProps,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & DropdownMenuSubTriggerProps>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwardedProps = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenuSubTrigger
|
||||
v-bind="forwardedProps"
|
||||
:class="
|
||||
cn(
|
||||
'focus:bg-accent data-[state=open]:bg-accent flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
<ChevronRight class="ml-auto h-4 w-4" />
|
||||
</DropdownMenuSubTrigger>
|
||||
</template>
|
@@ -0,0 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
DropdownMenuTrigger,
|
||||
type DropdownMenuTriggerProps,
|
||||
useForwardProps,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<DropdownMenuTriggerProps>();
|
||||
|
||||
const forwardedProps = useForwardProps(props);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenuTrigger class="outline-none" v-bind="forwardedProps">
|
||||
<slot></slot>
|
||||
</DropdownMenuTrigger>
|
||||
</template>
|
@@ -0,0 +1,16 @@
|
||||
export { default as DropdownMenu } from './DropdownMenu.vue';
|
||||
|
||||
export { default as DropdownMenuCheckboxItem } from './DropdownMenuCheckboxItem.vue';
|
||||
export { default as DropdownMenuContent } from './DropdownMenuContent.vue';
|
||||
export { default as DropdownMenuGroup } from './DropdownMenuGroup.vue';
|
||||
export { default as DropdownMenuItem } from './DropdownMenuItem.vue';
|
||||
export { default as DropdownMenuLabel } from './DropdownMenuLabel.vue';
|
||||
export { default as DropdownMenuRadioGroup } from './DropdownMenuRadioGroup.vue';
|
||||
export { default as DropdownMenuRadioItem } from './DropdownMenuRadioItem.vue';
|
||||
export { default as DropdownMenuSeparator } from './DropdownMenuSeparator.vue';
|
||||
export { default as DropdownMenuShortcut } from './DropdownMenuShortcut.vue';
|
||||
export { default as DropdownMenuSub } from './DropdownMenuSub.vue';
|
||||
export { default as DropdownMenuSubContent } from './DropdownMenuSubContent.vue';
|
||||
export { default as DropdownMenuSubTrigger } from './DropdownMenuSubTrigger.vue';
|
||||
export { default as DropdownMenuTrigger } from './DropdownMenuTrigger.vue';
|
||||
export { DropdownMenuPortal } from 'radix-vue';
|
19
packages/@core/ui-kit/shadcn-ui/src/ui/form/FormControl.vue
Normal file
19
packages/@core/ui-kit/shadcn-ui/src/ui/form/FormControl.vue
Normal 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>
|
@@ -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>
|
20
packages/@core/ui-kit/shadcn-ui/src/ui/form/FormItem.vue
Normal file
20
packages/@core/ui-kit/shadcn-ui/src/ui/form/FormItem.vue
Normal 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>
|
18
packages/@core/ui-kit/shadcn-ui/src/ui/form/FormLabel.vue
Normal file
18
packages/@core/ui-kit/shadcn-ui/src/ui/form/FormLabel.vue
Normal 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>
|
18
packages/@core/ui-kit/shadcn-ui/src/ui/form/FormMessage.vue
Normal file
18
packages/@core/ui-kit/shadcn-ui/src/ui/form/FormMessage.vue
Normal 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>
|
11
packages/@core/ui-kit/shadcn-ui/src/ui/form/index.ts
Normal file
11
packages/@core/ui-kit/shadcn-ui/src/ui/form/index.ts
Normal 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';
|
@@ -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>;
|
38
packages/@core/ui-kit/shadcn-ui/src/ui/form/useFormField.ts
Normal file
38
packages/@core/ui-kit/shadcn-ui/src/ui/form/useFormField.ts
Normal 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,
|
||||
};
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
HoverCardRoot,
|
||||
type HoverCardRootEmits,
|
||||
type HoverCardRootProps,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = defineProps<HoverCardRootProps>();
|
||||
const emits = defineEmits<HoverCardRootEmits>();
|
||||
|
||||
const forwarded = useForwardPropsEmits(props, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<HoverCardRoot v-bind="forwarded">
|
||||
<slot></slot>
|
||||
</HoverCardRoot>
|
||||
</template>
|
@@ -0,0 +1,43 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import {
|
||||
HoverCardContent,
|
||||
type HoverCardContentProps,
|
||||
HoverCardPortal,
|
||||
useForwardProps,
|
||||
} from 'radix-vue';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{ class?: any } & HoverCardContentProps>(),
|
||||
{
|
||||
sideOffset: 4,
|
||||
},
|
||||
);
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwardedProps = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<HoverCardPortal>
|
||||
<HoverCardContent
|
||||
v-bind="forwardedProps"
|
||||
:class="
|
||||
cn(
|
||||
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 border-border z-[1000] w-64 rounded-md border p-4 shadow-md outline-none',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
</HoverCardContent>
|
||||
</HoverCardPortal>
|
||||
</template>
|
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { HoverCardTrigger, type HoverCardTriggerProps } from 'radix-vue';
|
||||
|
||||
const props = defineProps<HoverCardTriggerProps>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<HoverCardTrigger v-bind="props">
|
||||
<slot></slot>
|
||||
</HoverCardTrigger>
|
||||
</template>
|
@@ -0,0 +1,3 @@
|
||||
export { default as HoverCard } from './HoverCard.vue';
|
||||
export { default as HoverCardContent } from './HoverCardContent.vue';
|
||||
export { default as HoverCardTrigger } from './HoverCardTrigger.vue';
|
29
packages/@core/ui-kit/shadcn-ui/src/ui/index.ts
Normal file
29
packages/@core/ui-kit/shadcn-ui/src/ui/index.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
export * from './accordion';
|
||||
export * from './avatar';
|
||||
export * from './badge';
|
||||
export * from './breadcrumb';
|
||||
export * from './button';
|
||||
export * from './card';
|
||||
export * from './checkbox';
|
||||
export * from './dialog';
|
||||
export * from './dropdown-menu';
|
||||
export * from './form';
|
||||
export * from './hover-card';
|
||||
export * from './input';
|
||||
export * from './label';
|
||||
export * from './number-field';
|
||||
export * from './pagination';
|
||||
export * from './pin-input';
|
||||
export * from './popover';
|
||||
export * from './radio-group';
|
||||
export * from './scroll-area';
|
||||
export * from './select';
|
||||
export * from './separator';
|
||||
export * from './sheet';
|
||||
export * from './switch';
|
||||
export * from './tabs';
|
||||
export * from './textarea';
|
||||
export * from './toast';
|
||||
export * from './toggle';
|
||||
export * from './toggle-group';
|
||||
export * from './tooltip';
|
32
packages/@core/ui-kit/shadcn-ui/src/ui/input/Input.vue
Normal file
32
packages/@core/ui-kit/shadcn-ui/src/ui/input/Input.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { useVModel } from '@vueuse/core';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: any;
|
||||
defaultValue?: number | string;
|
||||
modelValue?: number | string;
|
||||
}>();
|
||||
|
||||
const emits = defineEmits<{
|
||||
(e: 'update:modelValue', payload: number | string): void;
|
||||
}>();
|
||||
|
||||
const modelValue = useVModel(props, 'modelValue', emits, {
|
||||
defaultValue: props.defaultValue,
|
||||
passive: true,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<input
|
||||
v-model="modelValue"
|
||||
:class="
|
||||
cn(
|
||||
'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,
|
||||
)
|
||||
"
|
||||
/>
|
||||
</template>
|
1
packages/@core/ui-kit/shadcn-ui/src/ui/input/index.ts
Normal file
1
packages/@core/ui-kit/shadcn-ui/src/ui/input/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as Input } from './Input.vue';
|
29
packages/@core/ui-kit/shadcn-ui/src/ui/label/Label.vue
Normal file
29
packages/@core/ui-kit/shadcn-ui/src/ui/label/Label.vue
Normal 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>
|
1
packages/@core/ui-kit/shadcn-ui/src/ui/label/index.ts
Normal file
1
packages/@core/ui-kit/shadcn-ui/src/ui/label/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as Label } from './Label.vue';
|
@@ -0,0 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
import type { NumberFieldRootEmits, NumberFieldRootProps } from 'radix-vue';
|
||||
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { NumberFieldRoot, useForwardPropsEmits } from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & NumberFieldRootProps>();
|
||||
const emits = defineEmits<NumberFieldRootEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NumberFieldRoot v-bind="forwarded" :class="cn('grid gap-1.5', props.class)">
|
||||
<slot></slot>
|
||||
</NumberFieldRoot>
|
||||
</template>
|
@@ -0,0 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: any;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="
|
||||
cn(
|
||||
'relative [&>[data-slot=input]]:has-[[data-slot=decrement]]:pl-5 [&>[data-slot=input]]:has-[[data-slot=increment]]:pr-5',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
@@ -0,0 +1,37 @@
|
||||
<script setup lang="ts">
|
||||
import type { NumberFieldDecrementProps } from 'radix-vue';
|
||||
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { Minus } from 'lucide-vue-next';
|
||||
import { NumberFieldDecrement, useForwardProps } from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & NumberFieldDecrementProps>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NumberFieldDecrement
|
||||
data-slot="decrement"
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'absolute left-0 top-1/2 -translate-y-1/2 p-3 disabled:cursor-not-allowed disabled:opacity-20',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot>
|
||||
<Minus class="h-4 w-4" />
|
||||
</slot>
|
||||
</NumberFieldDecrement>
|
||||
</template>
|
@@ -0,0 +1,37 @@
|
||||
<script setup lang="ts">
|
||||
import type { NumberFieldIncrementProps } from 'radix-vue';
|
||||
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { Plus } from 'lucide-vue-next';
|
||||
import { NumberFieldIncrement, useForwardProps } from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & NumberFieldIncrementProps>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NumberFieldIncrement
|
||||
data-slot="increment"
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'absolute right-0 top-1/2 -translate-y-1/2 p-3 disabled:cursor-not-allowed disabled:opacity-20',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot>
|
||||
<Plus class="h-4 w-4" />
|
||||
</slot>
|
||||
</NumberFieldIncrement>
|
||||
</template>
|
@@ -0,0 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { NumberFieldInput } from 'radix-vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NumberFieldInput
|
||||
:class="
|
||||
cn(
|
||||
'border-input placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full rounded-md border bg-transparent py-1 text-center text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50',
|
||||
)
|
||||
"
|
||||
data-slot="input"
|
||||
/>
|
||||
</template>
|
@@ -0,0 +1,5 @@
|
||||
export { default as NumberField } from './NumberField.vue';
|
||||
export { default as NumberFieldContent } from './NumberFieldContent.vue';
|
||||
export { default as NumberFieldDecrement } from './NumberFieldDecrement.vue';
|
||||
export { default as NumberFieldIncrement } from './NumberFieldIncrement.vue';
|
||||
export { default as NumberFieldInput } from './NumberFieldInput.vue';
|
@@ -0,0 +1,27 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { MoreHorizontal } from 'lucide-vue-next';
|
||||
import { PaginationEllipsis, type PaginationEllipsisProps } from 'radix-vue';
|
||||
|
||||
const props = defineProps<{ class?: any } & PaginationEllipsisProps>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PaginationEllipsis
|
||||
v-bind="delegatedProps"
|
||||
:class="cn('flex size-8 items-center justify-center', props.class)"
|
||||
>
|
||||
<slot>
|
||||
<MoreHorizontal class="size-4" />
|
||||
</slot>
|
||||
</PaginationEllipsis>
|
||||
</template>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user