feat: support vue file unit testing, add some components unit testing (#4119)
parent
517acada1a
commit
3f9ce63868
|
@ -7,7 +7,7 @@ on:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy-push-playground-ftp:
|
deploy-push-playground-ftp:
|
||||||
name: Deploy Push Ftp
|
name: Deploy Push Playground Ftp
|
||||||
if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]')
|
if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
@ -46,7 +46,7 @@ jobs:
|
||||||
local-dir: ./docs/.vitepress/dist/
|
local-dir: ./docs/.vitepress/dist/
|
||||||
|
|
||||||
deploy-push-antd-ftp:
|
deploy-push-antd-ftp:
|
||||||
name: Deploy Push Ftp
|
name: Deploy Push Antd Ftp
|
||||||
if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]')
|
if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
@ -77,7 +77,7 @@ jobs:
|
||||||
local-dir: ./apps/web-antd/dist/
|
local-dir: ./apps/web-antd/dist/
|
||||||
|
|
||||||
deploy-push-ele-ftp:
|
deploy-push-ele-ftp:
|
||||||
name: Deploy Push Ftp
|
name: Deploy Push Element Ftp
|
||||||
if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]')
|
if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
@ -108,7 +108,7 @@ jobs:
|
||||||
local-dir: ./apps/web-ele/dist/
|
local-dir: ./apps/web-ele/dist/
|
||||||
|
|
||||||
deploy-push-naive-ftp:
|
deploy-push-naive-ftp:
|
||||||
name: Deploy Push Ftp
|
name: Deploy Push Naive Ftp
|
||||||
if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]')
|
if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
|
@ -70,6 +70,8 @@
|
||||||
"@vben/turbo-run": "workspace:*",
|
"@vben/turbo-run": "workspace:*",
|
||||||
"@vben/vite-config": "workspace:*",
|
"@vben/vite-config": "workspace:*",
|
||||||
"@vben/vsh": "workspace:*",
|
"@vben/vsh": "workspace:*",
|
||||||
|
"@vitejs/plugin-vue": "^5.1.2",
|
||||||
|
"@vitejs/plugin-vue-jsx": "^4.0.0",
|
||||||
"@vue/test-utils": "^2.4.6",
|
"@vue/test-utils": "^2.4.6",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
|
@ -85,6 +87,7 @@
|
||||||
"unbuild": "^2.0.0",
|
"unbuild": "^2.0.0",
|
||||||
"vite": "^5.4.0",
|
"vite": "^5.4.0",
|
||||||
"vitest": "^2.0.5",
|
"vitest": "^2.0.5",
|
||||||
|
"vue": "^3.4.37",
|
||||||
"vue-tsc": "^2.0.29"
|
"vue-tsc": "^2.0.29"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
AlertDialogHeader,
|
AlertDialogHeader,
|
||||||
AlertDialog as AlertDialogRoot,
|
AlertDialog as AlertDialogRoot,
|
||||||
AlertDialogTitle,
|
AlertDialogTitle,
|
||||||
} from '@vben-core/shadcn-ui/components/ui/alert-dialog';
|
} from '../ui/alert-dialog';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
cancelText?: string;
|
cancelText?: string;
|
||||||
|
|
|
@ -7,11 +7,7 @@ import type {
|
||||||
|
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
import {
|
import { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar';
|
||||||
Avatar,
|
|
||||||
AvatarFallback,
|
|
||||||
AvatarImage,
|
|
||||||
} from '@vben-core/shadcn-ui/components/ui/avatar';
|
|
||||||
|
|
||||||
interface Props extends AvatarRootProps, AvatarFallbackProps, AvatarImageProps {
|
interface Props extends AvatarRootProps, AvatarFallbackProps, AvatarImageProps {
|
||||||
alt?: string;
|
alt?: string;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { IBreadcrumb } from './interface';
|
import type { IBreadcrumb } from './types';
|
||||||
|
|
||||||
import { VbenIcon } from '../icon';
|
import { VbenIcon } from '../icon';
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { IBreadcrumb } from './interface';
|
import type { IBreadcrumb } from './types';
|
||||||
|
|
||||||
import { ChevronDown } from '@vben-core/icons';
|
import { ChevronDown } from '@vben-core/icons';
|
||||||
|
|
||||||
|
import { VbenIcon } from '../icon';
|
||||||
import {
|
import {
|
||||||
Breadcrumb,
|
Breadcrumb,
|
||||||
BreadcrumbItem,
|
BreadcrumbItem,
|
||||||
|
@ -9,15 +11,13 @@ import {
|
||||||
BreadcrumbList,
|
BreadcrumbList,
|
||||||
BreadcrumbPage,
|
BreadcrumbPage,
|
||||||
BreadcrumbSeparator,
|
BreadcrumbSeparator,
|
||||||
} from '@vben-core/shadcn-ui/components/ui/breadcrumb';
|
} from '../ui/breadcrumb';
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
DropdownMenuItem,
|
DropdownMenuItem,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from '@vben-core/shadcn-ui/components/ui/dropdown-menu';
|
} from '../ui/dropdown-menu';
|
||||||
|
|
||||||
import { VbenIcon } from '../icon';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
breadcrumbs: IBreadcrumb[];
|
breadcrumbs: IBreadcrumb[];
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export { default as VbenBreadcrumb } from './breadcrumb.vue';
|
export { default as VbenBreadcrumb } from './breadcrumb.vue';
|
||||||
export { default as VbenBackgroundBreadcrumb } from './breadcrumb-background.vue';
|
export { default as VbenBackgroundBreadcrumb } from './breadcrumb-background.vue';
|
||||||
|
|
||||||
export type * from './interface';
|
export type * from './types';
|
||||||
|
|
|
@ -2,14 +2,12 @@
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
import { LoaderCircle } from '@vben-core/icons';
|
import { LoaderCircle } from '@vben-core/icons';
|
||||||
import {
|
|
||||||
type ButtonVariants,
|
|
||||||
buttonVariants,
|
|
||||||
} from '@vben-core/shadcn-ui/components/ui/button';
|
|
||||||
import { cn } from '@vben-core/shared';
|
import { cn } from '@vben-core/shared';
|
||||||
|
|
||||||
import { Primitive, type PrimitiveProps } from 'radix-vue';
|
import { Primitive, type PrimitiveProps } from 'radix-vue';
|
||||||
|
|
||||||
|
import { type ButtonVariants, buttonVariants } from '../ui/button';
|
||||||
|
|
||||||
interface Props extends PrimitiveProps {
|
interface Props extends PrimitiveProps {
|
||||||
class?: any;
|
class?: any;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { ButtonVariants } from '@vben-core/shadcn-ui/components/ui/button';
|
import type { ButtonVariants } from '../ui/button';
|
||||||
|
|
||||||
import { computed, useSlots } from 'vue';
|
import { computed, useSlots } from 'vue';
|
||||||
|
|
||||||
import { VbenTooltip } from '@vben-core/shadcn-ui/components/tooltip';
|
|
||||||
import { cn } from '@vben-core/shared';
|
import { cn } from '@vben-core/shared';
|
||||||
|
|
||||||
import { type PrimitiveProps } from 'radix-vue';
|
import { type PrimitiveProps } from 'radix-vue';
|
||||||
|
|
||||||
|
import { VbenTooltip } from '../tooltip';
|
||||||
import VbenButton from './button.vue';
|
import VbenButton from './button.vue';
|
||||||
|
|
||||||
interface Props extends PrimitiveProps {
|
interface Props extends PrimitiveProps {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { CheckboxRootEmits, CheckboxRootProps } from 'radix-vue';
|
import type { CheckboxRootEmits, CheckboxRootProps } from 'radix-vue';
|
||||||
|
|
||||||
import { Checkbox } from '@vben-core/shadcn-ui/components/ui/checkbox';
|
|
||||||
|
|
||||||
import { useForwardPropsEmits } from 'radix-vue';
|
import { useForwardPropsEmits } from 'radix-vue';
|
||||||
|
|
||||||
|
import { Checkbox } from '../ui/checkbox';
|
||||||
|
|
||||||
const props = defineProps<
|
const props = defineProps<
|
||||||
{
|
{
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
@ -9,6 +9,8 @@ import type { IContextMenuItem } from './interface';
|
||||||
|
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
|
import { useForwardPropsEmits } from 'radix-vue';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ContextMenu,
|
ContextMenu,
|
||||||
ContextMenuContent,
|
ContextMenuContent,
|
||||||
|
@ -16,9 +18,7 @@ import {
|
||||||
ContextMenuSeparator,
|
ContextMenuSeparator,
|
||||||
ContextMenuShortcut,
|
ContextMenuShortcut,
|
||||||
ContextMenuTrigger,
|
ContextMenuTrigger,
|
||||||
} from '@vben-core/shadcn-ui/components/ui/context-menu';
|
} from '../ui/context-menu';
|
||||||
|
|
||||||
import { useForwardPropsEmits } from 'radix-vue';
|
|
||||||
|
|
||||||
const props = defineProps<
|
const props = defineProps<
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {
|
||||||
DropdownMenuItem,
|
DropdownMenuItem,
|
||||||
DropdownMenuSeparator,
|
DropdownMenuSeparator,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from '@vben-core/shadcn-ui/components/ui/dropdown-menu';
|
} from '../ui/dropdown-menu';
|
||||||
|
|
||||||
interface Props extends DropdownMenuProps {}
|
interface Props extends DropdownMenuProps {}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
DropdownMenuGroup,
|
DropdownMenuGroup,
|
||||||
DropdownMenuItem,
|
DropdownMenuItem,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from '@vben-core/shadcn-ui/components/ui/dropdown-menu';
|
} from '../ui/dropdown-menu';
|
||||||
|
|
||||||
interface Props extends DropdownMenuProps {}
|
interface Props extends DropdownMenuProps {}
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,13 @@ import type {
|
||||||
|
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
|
import { useForwardPropsEmits } from 'radix-vue';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
HoverCard,
|
HoverCard,
|
||||||
HoverCardContent,
|
HoverCardContent,
|
||||||
HoverCardTrigger,
|
HoverCardTrigger,
|
||||||
} from '@vben-core/shadcn-ui/components/ui/hover-card';
|
} from '../ui/hover-card';
|
||||||
|
|
||||||
import { useForwardPropsEmits } from 'radix-vue';
|
|
||||||
|
|
||||||
interface Props extends HoverCardRootProps {
|
interface Props extends HoverCardRootProps {
|
||||||
class?: any;
|
class?: any;
|
||||||
|
|
|
@ -2,13 +2,10 @@
|
||||||
import { ref, useSlots } from 'vue';
|
import { ref, useSlots } from 'vue';
|
||||||
|
|
||||||
import { Eye, EyeOff } from '@vben-core/icons';
|
import { Eye, EyeOff } from '@vben-core/icons';
|
||||||
import {
|
|
||||||
type InputProps,
|
|
||||||
VbenInput,
|
|
||||||
} from '@vben-core/shadcn-ui/components/input';
|
|
||||||
|
|
||||||
import { useForwardProps } from 'radix-vue';
|
import { useForwardProps } from 'radix-vue';
|
||||||
|
|
||||||
|
import { type InputProps, VbenInput } from '../input';
|
||||||
import PasswordStrength from './password-strength.vue';
|
import PasswordStrength from './password-strength.vue';
|
||||||
|
|
||||||
interface Props extends InputProps {}
|
interface Props extends InputProps {}
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
export { default as VbenInput } from './input.vue';
|
export { default as VbenInput } from './input.vue';
|
||||||
export type * from './interface';
|
export type * from './types';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { InputProps } from './interface';
|
import type { InputProps } from './types';
|
||||||
|
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
export { default as VbenPinInput } from './input.vue';
|
export { default as VbenPinInput } from './input.vue';
|
||||||
|
|
||||||
export type * from './interface';
|
export type * from './types';
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { PinInputProps } from './interface';
|
import type { PinInputProps } from './types';
|
||||||
|
|
||||||
import { computed, ref, watch } from 'vue';
|
import { computed, ref, watch } from 'vue';
|
||||||
|
|
||||||
import { VbenButton } from '@vben-core/shadcn-ui/components/button';
|
import { VbenButton } from '../button';
|
||||||
import {
|
import { PinInput, PinInputGroup, PinInputInput } from '../ui/pin-input';
|
||||||
PinInput,
|
|
||||||
PinInputGroup,
|
|
||||||
PinInputInput,
|
|
||||||
} from '@vben-core/shadcn-ui/components/ui/pin-input';
|
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
|
|
|
@ -7,13 +7,13 @@ import type {
|
||||||
|
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
|
import { useForwardPropsEmits } from 'radix-vue';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
PopoverContent,
|
PopoverContent,
|
||||||
Popover as PopoverRoot,
|
Popover as PopoverRoot,
|
||||||
PopoverTrigger,
|
PopoverTrigger,
|
||||||
} from '@vben-core/shadcn-ui/components/ui/popover';
|
} from '../ui/popover';
|
||||||
|
|
||||||
import { useForwardPropsEmits } from 'radix-vue';
|
|
||||||
|
|
||||||
interface Props extends PopoverRootProps {
|
interface Props extends PopoverRootProps {
|
||||||
class?: any;
|
class?: any;
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
import {
|
|
||||||
ScrollArea,
|
|
||||||
ScrollBar,
|
|
||||||
} from '@vben-core/shadcn-ui/components/ui/scroll-area';
|
|
||||||
import { cn } from '@vben-core/shared';
|
import { cn } from '@vben-core/shared';
|
||||||
|
|
||||||
|
import { ScrollArea, ScrollBar } from '../ui/scroll-area';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
class?: any;
|
class?: any;
|
||||||
horizontal?: boolean;
|
horizontal?: boolean;
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
export type * from './interface';
|
|
||||||
|
|
||||||
export { default as VbenSegmented } from './segmented.vue';
|
export { default as VbenSegmented } from './segmented.vue';
|
||||||
|
|
||||||
|
export type * from './types';
|
||||||
|
|
|
@ -1,16 +1,11 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { SegmentedItem } from './interface';
|
import type { SegmentedItem } from './types';
|
||||||
|
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
import {
|
|
||||||
Tabs,
|
|
||||||
TabsContent,
|
|
||||||
TabsList,
|
|
||||||
} from '@vben-core/shadcn-ui/components/ui/tabs';
|
|
||||||
|
|
||||||
import { TabsTrigger } from 'radix-vue';
|
import { TabsTrigger } from 'radix-vue';
|
||||||
|
|
||||||
|
import { Tabs, TabsContent, TabsList } from '../ui/tabs';
|
||||||
import TabsIndicator from './tabs-indicator.vue';
|
import TabsIndicator from './tabs-indicator.vue';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, useSlots } from 'vue';
|
import { computed, useSlots } from 'vue';
|
||||||
|
|
||||||
import {
|
import { X } from 'lucide-vue-next';
|
||||||
VbenButton,
|
|
||||||
VbenIconButton,
|
import { VbenButton, VbenIconButton } from '../button';
|
||||||
} from '@vben-core/shadcn-ui/components/button';
|
import { VbenScrollbar } from '../scrollbar';
|
||||||
import { VbenScrollbar } from '@vben-core/shadcn-ui/components/scrollbar';
|
|
||||||
import {
|
import {
|
||||||
Sheet,
|
Sheet,
|
||||||
SheetClose,
|
SheetClose,
|
||||||
|
@ -15,9 +14,7 @@ import {
|
||||||
SheetHeader,
|
SheetHeader,
|
||||||
SheetTitle,
|
SheetTitle,
|
||||||
SheetTrigger,
|
SheetTrigger,
|
||||||
} from '@vben-core/shadcn-ui/components/ui/sheet';
|
} from '../ui/sheet';
|
||||||
|
|
||||||
import { X } from 'lucide-vue-next';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
cancelText?: string;
|
cancelText?: string;
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
TooltipProvider,
|
TooltipProvider,
|
||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
} from '@vben-core/shadcn-ui/components/ui/tooltip';
|
} from '../ui/tooltip';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
contentClass?: any;
|
contentClass?: any;
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, type HTMLAttributes } from 'vue';
|
import { computed, type HTMLAttributes } from 'vue';
|
||||||
|
|
||||||
import { buttonVariants } from '@vben-core/shadcn-ui/components/ui/button';
|
|
||||||
import { cn } from '@vben-core/shared';
|
import { cn } from '@vben-core/shared';
|
||||||
|
|
||||||
import { AlertDialogAction, type AlertDialogActionProps } from 'radix-vue';
|
import { AlertDialogAction, type AlertDialogActionProps } from 'radix-vue';
|
||||||
|
|
||||||
|
import { buttonVariants } from '../button';
|
||||||
|
|
||||||
const props = defineProps<
|
const props = defineProps<
|
||||||
{ class?: HTMLAttributes['class'] } & AlertDialogActionProps
|
{ class?: HTMLAttributes['class'] } & AlertDialogActionProps
|
||||||
>();
|
>();
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, type HTMLAttributes } from 'vue';
|
import { computed, type HTMLAttributes } from 'vue';
|
||||||
|
|
||||||
import { buttonVariants } from '@vben-core/shadcn-ui/components/ui/button';
|
|
||||||
import { cn } from '@vben-core/shared';
|
import { cn } from '@vben-core/shared';
|
||||||
|
|
||||||
import { AlertDialogCancel, type AlertDialogCancelProps } from 'radix-vue';
|
import { AlertDialogCancel, type AlertDialogCancelProps } from 'radix-vue';
|
||||||
|
|
||||||
|
import { buttonVariants } from '../button';
|
||||||
|
|
||||||
const props = defineProps<
|
const props = defineProps<
|
||||||
{ class?: HTMLAttributes['class'] } & AlertDialogCancelProps
|
{ class?: HTMLAttributes['class'] } & AlertDialogCancelProps
|
||||||
>();
|
>();
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { toggleVariants } from '@vben-core/shadcn-ui/components/ui/toggle';
|
|
||||||
import type { VariantProps } from 'class-variance-authority';
|
import type { VariantProps } from 'class-variance-authority';
|
||||||
|
|
||||||
|
import type { toggleVariants } from '../toggle';
|
||||||
|
|
||||||
import { computed, type HTMLAttributes, provide } from 'vue';
|
import { computed, type HTMLAttributes, provide } from 'vue';
|
||||||
|
|
||||||
import { cn } from '@vben-core/shared';
|
import { cn } from '@vben-core/shared';
|
||||||
|
|
|
@ -3,7 +3,6 @@ import type { VariantProps } from 'class-variance-authority';
|
||||||
|
|
||||||
import { computed, type HTMLAttributes, inject } from 'vue';
|
import { computed, type HTMLAttributes, inject } from 'vue';
|
||||||
|
|
||||||
import { toggleVariants } from '@vben-core/shadcn-ui/components/ui/toggle';
|
|
||||||
import { cn } from '@vben-core/shared';
|
import { cn } from '@vben-core/shared';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -12,6 +11,8 @@ import {
|
||||||
useForwardProps,
|
useForwardProps,
|
||||||
} from 'radix-vue';
|
} from 'radix-vue';
|
||||||
|
|
||||||
|
import { toggleVariants } from '../toggle';
|
||||||
|
|
||||||
type ToggleGroupVariants = VariantProps<typeof toggleVariants>;
|
type ToggleGroupVariants = VariantProps<typeof toggleVariants>;
|
||||||
|
|
||||||
const props = defineProps<
|
const props = defineProps<
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { mount } from '@vue/test-utils';
|
||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
|
import { EllipsisText } from '..';
|
||||||
|
|
||||||
|
describe('ellipsis-text.vue', () => {
|
||||||
|
it('renders the correct content and truncates text', async () => {
|
||||||
|
const wrapper = mount(EllipsisText, {
|
||||||
|
props: {
|
||||||
|
line: 1,
|
||||||
|
title: 'Test Title',
|
||||||
|
},
|
||||||
|
slots: {
|
||||||
|
default: 'This is a very long text that should be truncated.',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.text()).toContain('This is a very long text');
|
||||||
|
// 检查 ellipsis 是否应用了正确的 class
|
||||||
|
const ellipsis = wrapper.find('.truncate');
|
||||||
|
expect(ellipsis.exists()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('expands text on click if expand is true', async () => {
|
||||||
|
const wrapper = mount(EllipsisText, {
|
||||||
|
props: {
|
||||||
|
expand: true,
|
||||||
|
line: 1,
|
||||||
|
},
|
||||||
|
slots: {
|
||||||
|
default: 'This is a very long text that should be truncated.',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const ellipsis = wrapper.find('.truncate');
|
||||||
|
await ellipsis.trigger('click');
|
||||||
|
expect(wrapper.emitted('expandChange')).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -51,6 +51,7 @@ interface Props {
|
||||||
*/
|
*/
|
||||||
tooltipOverlayStyle?: CSSProperties;
|
tooltipOverlayStyle?: CSSProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
expand: false,
|
expand: false,
|
||||||
line: 1,
|
line: 1,
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
import { mount } from '@vue/test-utils';
|
||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
|
import { Page } from '..';
|
||||||
|
|
||||||
|
describe('page.vue', () => {
|
||||||
|
it('renders title when passed', () => {
|
||||||
|
const wrapper = mount(Page, {
|
||||||
|
props: {
|
||||||
|
title: 'Test Title',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.text()).toContain('Test Title');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders description when passed', () => {
|
||||||
|
const wrapper = mount(Page, {
|
||||||
|
props: {
|
||||||
|
description: 'Test Description',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.text()).toContain('Test Description');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders default slot content', () => {
|
||||||
|
const wrapper = mount(Page, {
|
||||||
|
slots: {
|
||||||
|
default: '<p>Default Slot Content</p>',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.html()).toContain('<p>Default Slot Content</p>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders footer slot when showFooter is true', () => {
|
||||||
|
const wrapper = mount(Page, {
|
||||||
|
props: {
|
||||||
|
showFooter: true,
|
||||||
|
},
|
||||||
|
slots: {
|
||||||
|
footer: '<p>Footer Slot Content</p>',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.html()).toContain('<p>Footer Slot Content</p>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('applies the custom contentClass', () => {
|
||||||
|
const wrapper = mount(Page, {
|
||||||
|
props: {
|
||||||
|
contentClass: 'custom-class',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const contentDiv = wrapper.find('.m-4');
|
||||||
|
expect(contentDiv.classes()).toContain('custom-class');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not render description slot if description prop is provided', () => {
|
||||||
|
const wrapper = mount(Page, {
|
||||||
|
props: {
|
||||||
|
description: 'Test Description',
|
||||||
|
},
|
||||||
|
slots: {
|
||||||
|
description: '<p>Description Slot Content</p>',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.text()).toContain('Test Description');
|
||||||
|
expect(wrapper.html()).not.toContain('Description Slot Content');
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,13 +0,0 @@
|
||||||
<script setup lang="ts">
|
|
||||||
defineOptions({
|
|
||||||
name: 'PageFooter',
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div
|
|
||||||
class="bg-card align-center absolute bottom-0 left-0 right-0 flex px-6 py-4"
|
|
||||||
>
|
|
||||||
<slot></slot>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
|
@ -1,18 +0,0 @@
|
||||||
<script setup lang="ts">
|
|
||||||
import type { PageHeaderProps } from './page.ts';
|
|
||||||
|
|
||||||
defineOptions({
|
|
||||||
name: 'PageHeader',
|
|
||||||
});
|
|
||||||
|
|
||||||
const props = defineProps<PageHeaderProps>();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="bg-card px-6 py-4">
|
|
||||||
<div class="mb-2 flex justify-between text-xl font-bold leading-10">
|
|
||||||
{{ props.title }}
|
|
||||||
</div>
|
|
||||||
<slot></slot>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
|
@ -1,11 +0,0 @@
|
||||||
interface PageHeaderProps {
|
|
||||||
title?: string;
|
|
||||||
description?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Props extends PageHeaderProps {
|
|
||||||
contentClass?: string;
|
|
||||||
showFooter?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type { PageHeaderProps, Props };
|
|
|
@ -1,14 +1,17 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { Props } from './page';
|
interface Props {
|
||||||
|
title?: string;
|
||||||
import PageFooter from './page-footer.vue';
|
description?: string;
|
||||||
import PageHeader from './page-header.vue';
|
contentClass?: string;
|
||||||
|
showFooter?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'Page',
|
name: 'Page',
|
||||||
});
|
});
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
contentClass: '',
|
||||||
description: '',
|
description: '',
|
||||||
showFooter: false,
|
showFooter: false,
|
||||||
title: '',
|
title: '',
|
||||||
|
@ -17,22 +20,26 @@ const props = withDefaults(defineProps<Props>(), {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="relative h-full">
|
<div class="relative h-full">
|
||||||
<PageHeader
|
<div
|
||||||
v-if="description || $slots.description || title"
|
v-if="description || $slots.description || title"
|
||||||
:title="props.title"
|
class="bg-card px-6 py-4"
|
||||||
>
|
>
|
||||||
<template #default>
|
<div class="mb-2 flex justify-between text-xl font-bold leading-10">
|
||||||
|
{{ title }}
|
||||||
|
</div>
|
||||||
<template v-if="description">{{ description }}</template>
|
<template v-if="description">{{ description }}</template>
|
||||||
<slot v-else name="description"></slot>
|
<slot v-else name="description"></slot>
|
||||||
</template>
|
</div>
|
||||||
</PageHeader>
|
|
||||||
<div :class="contentClass" class="m-4">
|
<div :class="contentClass" class="m-4">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
<PageFooter v-if="props.showFooter">
|
|
||||||
<template #default>
|
<div
|
||||||
|
v-if="props.showFooter"
|
||||||
|
class="bg-card align-center absolute bottom-0 left-0 right-0 flex px-6 py-4"
|
||||||
|
>
|
||||||
<slot name="footer"></slot>
|
<slot name="footer"></slot>
|
||||||
</template>
|
</div>
|
||||||
</PageFooter>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { LoginCodeEmits } from './typings';
|
import type { LoginCodeEmits } from './types';
|
||||||
|
|
||||||
import { computed, onBeforeUnmount, reactive, ref } from 'vue';
|
import { computed, onBeforeUnmount, reactive, ref } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
|
@ -8,4 +8,4 @@ export type {
|
||||||
AuthenticationProps,
|
AuthenticationProps,
|
||||||
LoginAndRegisterParams,
|
LoginAndRegisterParams,
|
||||||
LoginCodeParams,
|
LoginCodeParams,
|
||||||
} from './typings';
|
} from './types';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { AuthenticationProps, LoginAndRegisterParams } from './typings';
|
import type { AuthenticationProps, LoginAndRegisterParams } from './types';
|
||||||
|
|
||||||
import { useForwardPropsEmits } from '@vben/hooks';
|
import { useForwardPropsEmits } from '@vben/hooks';
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { AuthenticationProps, LoginEmits } from './typings';
|
import type { AuthenticationProps, LoginEmits } from './types';
|
||||||
|
|
||||||
import { computed, reactive } from 'vue';
|
import { computed, reactive } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { RegisterEmits } from './typings';
|
import type { RegisterEmits } from './types';
|
||||||
|
|
||||||
import { computed, reactive } from 'vue';
|
import { computed, reactive } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { RegisterEmits } from './typings';
|
|
||||||
|
|
||||||
import { computed, reactive } from 'vue';
|
import { computed, reactive } from 'vue';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -19,6 +17,14 @@ interface Props {
|
||||||
text?: string;
|
text?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface LockAndRegisterParams {
|
||||||
|
lockScreenPassword: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RegisterEmits {
|
||||||
|
submit: [LockAndRegisterParams];
|
||||||
|
}
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'LockScreenModal',
|
name: 'LockScreenModal',
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
interface LockAndRegisterParams {
|
|
||||||
lockScreenPassword: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface RegisterEmits {
|
|
||||||
submit: [LockAndRegisterParams];
|
|
||||||
}
|
|
||||||
|
|
||||||
export type { LockAndRegisterParams, RegisterEmits };
|
|
|
@ -1,7 +1,11 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Page } from '@vben/common-ui';
|
import { Fallback } from '@vben/common-ui';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page description="当前页面仅 Admin 账号可见" title="页面访问测试" />
|
<Fallback
|
||||||
|
description="当前页面仅 Admin 账号可见"
|
||||||
|
status="coming-soon"
|
||||||
|
title="页面访问测试"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Page } from '@vben/common-ui';
|
import { Fallback } from '@vben/common-ui';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page description="当前页面仅 Super 账号可见" title="页面访问测试" />
|
<Fallback
|
||||||
|
description="当前页面仅 Super 账号可见"
|
||||||
|
status="coming-soon"
|
||||||
|
title="页面访问测试"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Page } from '@vben/common-ui';
|
import { Fallback } from '@vben/common-ui';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page description="当前页面仅 User 账号可见" title="页面访问测试" />
|
<Fallback
|
||||||
|
description="当前页面仅 User 账号可见"
|
||||||
|
status="coming-soon"
|
||||||
|
title="页面访问测试"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -55,6 +55,12 @@ importers:
|
||||||
'@vben/vsh':
|
'@vben/vsh':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:scripts/vsh
|
version: link:scripts/vsh
|
||||||
|
'@vitejs/plugin-vue':
|
||||||
|
specifier: ^5.1.2
|
||||||
|
version: 5.1.2(vite@5.4.0(@types/node@22.2.0)(sass@1.77.8)(terser@5.31.3))(vue@3.4.37(typescript@5.5.4))
|
||||||
|
'@vitejs/plugin-vue-jsx':
|
||||||
|
specifier: ^4.0.0
|
||||||
|
version: 4.0.0(vite@5.4.0(@types/node@22.2.0)(sass@1.77.8)(terser@5.31.3))(vue@3.4.37(typescript@5.5.4))
|
||||||
'@vue/test-utils':
|
'@vue/test-utils':
|
||||||
specifier: ^2.4.6
|
specifier: ^2.4.6
|
||||||
version: 2.4.6
|
version: 2.4.6
|
||||||
|
@ -100,6 +106,9 @@ importers:
|
||||||
vitest:
|
vitest:
|
||||||
specifier: ^2.0.5
|
specifier: ^2.0.5
|
||||||
version: 2.0.5(@types/node@22.2.0)(jsdom@24.1.1)(sass@1.77.8)(terser@5.31.3)
|
version: 2.0.5(@types/node@22.2.0)(jsdom@24.1.1)(sass@1.77.8)(terser@5.31.3)
|
||||||
|
vue:
|
||||||
|
specifier: ^3.4.37
|
||||||
|
version: 3.4.37(typescript@5.5.4)
|
||||||
vue-tsc:
|
vue-tsc:
|
||||||
specifier: ^2.0.29
|
specifier: ^2.0.29
|
||||||
version: 2.0.29(typescript@5.5.4)
|
version: 2.0.29(typescript@5.5.4)
|
||||||
|
@ -3344,6 +3353,7 @@ packages:
|
||||||
|
|
||||||
'@ls-lint/ls-lint@2.2.3':
|
'@ls-lint/ls-lint@2.2.3':
|
||||||
resolution: {integrity: sha512-ekM12jNm/7O2I/hsRv9HvYkRdfrHpiV1epVuI2NP+eTIcEgdIdKkKCs9KgQydu/8R5YXTov9aHdOgplmCHLupw==}
|
resolution: {integrity: sha512-ekM12jNm/7O2I/hsRv9HvYkRdfrHpiV1epVuI2NP+eTIcEgdIdKkKCs9KgQydu/8R5YXTov9aHdOgplmCHLupw==}
|
||||||
|
cpu: [x64, arm64, s390x]
|
||||||
os: [darwin, linux, win32]
|
os: [darwin, linux, win32]
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
import Vue from '@vitejs/plugin-vue';
|
||||||
|
import VueJsx from '@vitejs/plugin-vue-jsx';
|
||||||
import { defineConfig } from 'vitest/config';
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
plugins: [Vue(), VueJsx()],
|
||||||
test: {
|
test: {
|
||||||
environment: 'jsdom',
|
environment: 'jsdom',
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue