@gv-tech/design-system 1.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/skills/dogfood-components/SKILL.md +34 -0
- package/.agent/skills/maintain-component/SKILL.md +42 -0
- package/.github/workflows/release-please.yml +2 -2
- package/.prettierignore +2 -0
- package/.release-please-manifest.json +3 -0
- package/CHANGELOG.md +90 -0
- package/dist/App.d.ts.map +1 -1
- package/dist/components/docs/Footer.d.ts.map +1 -1
- package/dist/components/docs/PropsTable.d.ts +13 -0
- package/dist/components/docs/PropsTable.d.ts.map +1 -0
- package/dist/components/docs/Sidebar.d.ts.map +1 -1
- package/dist/components/docs/index.d.ts +1 -0
- package/dist/components/docs/index.d.ts.map +1 -1
- package/dist/components/ui/accordion.test.d.ts +2 -0
- package/dist/components/ui/accordion.test.d.ts.map +1 -0
- package/dist/components/ui/alert-dialog.test.d.ts +2 -0
- package/dist/components/ui/alert-dialog.test.d.ts.map +1 -0
- package/dist/components/ui/alert.test.d.ts +2 -0
- package/dist/components/ui/alert.test.d.ts.map +1 -0
- package/dist/components/ui/aspect-ratio.test.d.ts +2 -0
- package/dist/components/ui/aspect-ratio.test.d.ts.map +1 -0
- package/dist/components/ui/avatar.test.d.ts +2 -0
- package/dist/components/ui/avatar.test.d.ts.map +1 -0
- package/dist/components/ui/badge.test.d.ts +2 -0
- package/dist/components/ui/badge.test.d.ts.map +1 -0
- package/dist/components/ui/breadcrumb.test.d.ts +2 -0
- package/dist/components/ui/breadcrumb.test.d.ts.map +1 -0
- package/dist/components/ui/button.test.d.ts +2 -0
- package/dist/components/ui/button.test.d.ts.map +1 -0
- package/dist/components/ui/calendar.d.ts.map +1 -1
- package/dist/components/ui/calendar.test.d.ts +2 -0
- package/dist/components/ui/calendar.test.d.ts.map +1 -0
- package/dist/components/ui/card.test.d.ts +2 -0
- package/dist/components/ui/card.test.d.ts.map +1 -0
- package/dist/components/ui/carousel.test.d.ts +2 -0
- package/dist/components/ui/carousel.test.d.ts.map +1 -0
- package/dist/components/ui/chart.test.d.ts +2 -0
- package/dist/components/ui/chart.test.d.ts.map +1 -0
- package/dist/components/ui/checkbox.test.d.ts +2 -0
- package/dist/components/ui/checkbox.test.d.ts.map +1 -0
- package/dist/components/ui/collapsible.test.d.ts +2 -0
- package/dist/components/ui/collapsible.test.d.ts.map +1 -0
- package/dist/components/ui/command.test.d.ts +2 -0
- package/dist/components/ui/command.test.d.ts.map +1 -0
- package/dist/components/ui/context-menu.test.d.ts +2 -0
- package/dist/components/ui/context-menu.test.d.ts.map +1 -0
- package/dist/components/ui/dialog.test.d.ts +2 -0
- package/dist/components/ui/dialog.test.d.ts.map +1 -0
- package/dist/components/ui/drawer.test.d.ts +2 -0
- package/dist/components/ui/drawer.test.d.ts.map +1 -0
- package/dist/components/ui/dropdown-menu.test.d.ts +2 -0
- package/dist/components/ui/dropdown-menu.test.d.ts.map +1 -0
- package/dist/components/ui/form.test.d.ts +2 -0
- package/dist/components/ui/form.test.d.ts.map +1 -0
- package/dist/components/ui/hover-card.test.d.ts +2 -0
- package/dist/components/ui/hover-card.test.d.ts.map +1 -0
- package/dist/components/ui/input.test.d.ts +2 -0
- package/dist/components/ui/input.test.d.ts.map +1 -0
- package/dist/components/ui/label.test.d.ts +2 -0
- package/dist/components/ui/label.test.d.ts.map +1 -0
- package/dist/components/ui/menubar.test.d.ts +2 -0
- package/dist/components/ui/menubar.test.d.ts.map +1 -0
- package/dist/components/ui/navigation-menu.test.d.ts +2 -0
- package/dist/components/ui/navigation-menu.test.d.ts.map +1 -0
- package/dist/components/ui/pagination.test.d.ts +2 -0
- package/dist/components/ui/pagination.test.d.ts.map +1 -0
- package/dist/components/ui/popover.test.d.ts +2 -0
- package/dist/components/ui/popover.test.d.ts.map +1 -0
- package/dist/components/ui/progress.d.ts.map +1 -1
- package/dist/components/ui/progress.test.d.ts +2 -0
- package/dist/components/ui/progress.test.d.ts.map +1 -0
- package/dist/components/ui/radio-group.test.d.ts +2 -0
- package/dist/components/ui/radio-group.test.d.ts.map +1 -0
- package/dist/components/ui/resizable.test.d.ts +2 -0
- package/dist/components/ui/resizable.test.d.ts.map +1 -0
- package/dist/components/ui/scroll-area.test.d.ts +2 -0
- package/dist/components/ui/scroll-area.test.d.ts.map +1 -0
- package/dist/components/ui/search.d.ts +16 -0
- package/dist/components/ui/search.d.ts.map +1 -0
- package/dist/components/ui/search.test.d.ts +2 -0
- package/dist/components/ui/search.test.d.ts.map +1 -0
- package/dist/components/ui/select.test.d.ts +2 -0
- package/dist/components/ui/select.test.d.ts.map +1 -0
- package/dist/components/ui/separator.test.d.ts +2 -0
- package/dist/components/ui/separator.test.d.ts.map +1 -0
- package/dist/components/ui/sheet.test.d.ts +2 -0
- package/dist/components/ui/sheet.test.d.ts.map +1 -0
- package/dist/components/ui/skeleton.test.d.ts +2 -0
- package/dist/components/ui/skeleton.test.d.ts.map +1 -0
- package/dist/components/ui/slider.test.d.ts +2 -0
- package/dist/components/ui/slider.test.d.ts.map +1 -0
- package/dist/components/ui/sonner.test.d.ts +2 -0
- package/dist/components/ui/sonner.test.d.ts.map +1 -0
- package/dist/components/ui/switch.test.d.ts +2 -0
- package/dist/components/ui/switch.test.d.ts.map +1 -0
- package/dist/components/ui/table.test.d.ts +2 -0
- package/dist/components/ui/table.test.d.ts.map +1 -0
- package/dist/components/ui/tabs.test.d.ts +2 -0
- package/dist/components/ui/tabs.test.d.ts.map +1 -0
- package/dist/components/ui/textarea.test.d.ts +2 -0
- package/dist/components/ui/textarea.test.d.ts.map +1 -0
- package/dist/components/ui/theme-toggle.d.ts +17 -0
- package/dist/components/ui/theme-toggle.d.ts.map +1 -0
- package/dist/components/ui/toast.test.d.ts +2 -0
- package/dist/components/ui/toast.test.d.ts.map +1 -0
- package/dist/components/ui/toggle-group.test.d.ts +2 -0
- package/dist/components/ui/toggle-group.test.d.ts.map +1 -0
- package/dist/components/ui/toggle.test.d.ts +2 -0
- package/dist/components/ui/toggle.test.d.ts.map +1 -0
- package/dist/components/ui/tooltip.test.d.ts +2 -0
- package/dist/components/ui/tooltip.test.d.ts.map +1 -0
- package/dist/index.cjs.js +3 -3
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.es.js +978 -860
- package/dist/index.es.js.map +1 -1
- package/dist/lib/tokens.d.ts +54 -0
- package/dist/lib/tokens.d.ts.map +1 -0
- package/dist/pages/ColorTokensDocs.d.ts +2 -0
- package/dist/pages/ColorTokensDocs.d.ts.map +1 -0
- package/dist/pages/GettingStarted.d.ts.map +1 -1
- package/dist/pages/components/AccordionDocs.d.ts.map +1 -1
- package/dist/pages/components/AlertDialogDocs.d.ts.map +1 -1
- package/dist/pages/components/AlertDocs.d.ts.map +1 -1
- package/dist/pages/components/AspectRatioDocs.d.ts.map +1 -1
- package/dist/pages/components/AvatarDocs.d.ts.map +1 -1
- package/dist/pages/components/BadgeDocs.d.ts.map +1 -1
- package/dist/pages/components/BreadcrumbDocs.d.ts.map +1 -1
- package/dist/pages/components/ButtonDocs.d.ts.map +1 -1
- package/dist/pages/components/CalendarDocs.d.ts.map +1 -1
- package/dist/pages/components/CardDocs.d.ts.map +1 -1
- package/dist/pages/components/CarouselDocs.d.ts.map +1 -1
- package/dist/pages/components/ChartDocs.d.ts.map +1 -1
- package/dist/pages/components/CheckboxDocs.d.ts.map +1 -1
- package/dist/pages/components/CollapsibleDocs.d.ts.map +1 -1
- package/dist/pages/components/CommandDocs.d.ts.map +1 -1
- package/dist/pages/components/ContextMenuDocs.d.ts.map +1 -1
- package/dist/pages/components/DialogDocs.d.ts.map +1 -1
- package/dist/pages/components/DrawerDocs.d.ts.map +1 -1
- package/dist/pages/components/DropdownMenuDocs.d.ts.map +1 -1
- package/dist/pages/components/FormDocs.d.ts.map +1 -1
- package/dist/pages/components/HoverCardDocs.d.ts.map +1 -1
- package/dist/pages/components/InputDocs.d.ts.map +1 -1
- package/dist/pages/components/LabelDocs.d.ts.map +1 -1
- package/dist/pages/components/MenubarDocs.d.ts.map +1 -1
- package/dist/pages/components/NavigationMenuDocs.d.ts.map +1 -1
- package/dist/pages/components/PaginationDocs.d.ts.map +1 -1
- package/dist/pages/components/PopoverDocs.d.ts.map +1 -1
- package/dist/pages/components/ProgressDocs.d.ts.map +1 -1
- package/dist/pages/components/RadioGroupDocs.d.ts.map +1 -1
- package/dist/pages/components/ResizableDocs.d.ts.map +1 -1
- package/dist/pages/components/ScrollAreaDocs.d.ts.map +1 -1
- package/dist/pages/components/SearchDocs.d.ts +2 -0
- package/dist/pages/components/SearchDocs.d.ts.map +1 -0
- package/dist/pages/components/SelectDocs.d.ts.map +1 -1
- package/dist/pages/components/SeparatorDocs.d.ts.map +1 -1
- package/dist/pages/components/SheetDocs.d.ts.map +1 -1
- package/dist/pages/components/SkeletonDocs.d.ts.map +1 -1
- package/dist/pages/components/SliderDocs.d.ts.map +1 -1
- package/dist/pages/components/SonnerDocs.d.ts.map +1 -1
- package/dist/pages/components/SwitchDocs.d.ts.map +1 -1
- package/dist/pages/components/TableDocs.d.ts.map +1 -1
- package/dist/pages/components/TabsDocs.d.ts.map +1 -1
- package/dist/pages/components/TextareaDocs.d.ts.map +1 -1
- package/dist/pages/components/ThemeToggleDocs.d.ts +2 -0
- package/dist/pages/components/ThemeToggleDocs.d.ts.map +1 -0
- package/dist/pages/components/ToastDocs.d.ts.map +1 -1
- package/dist/pages/components/ToggleDocs.d.ts.map +1 -1
- package/dist/pages/components/ToggleGroupDocs.d.ts.map +1 -1
- package/dist/pages/components/TooltipDocs.d.ts.map +1 -1
- package/dist/pages/index.d.ts +3 -0
- package/dist/pages/index.d.ts.map +1 -1
- package/dist/registry/accordion.test.json +13 -0
- package/dist/registry/alert-dialog.test.json +13 -0
- package/dist/registry/alert.test.json +13 -0
- package/dist/registry/aspect-ratio.test.json +13 -0
- package/dist/registry/avatar.test.json +13 -0
- package/dist/registry/badge.test.json +13 -0
- package/dist/registry/breadcrumb.test.json +13 -0
- package/dist/registry/button.test.json +13 -0
- package/dist/registry/calendar.json +1 -1
- package/dist/registry/calendar.test.json +13 -0
- package/dist/registry/card.test.json +13 -0
- package/dist/registry/carousel.test.json +13 -0
- package/dist/registry/chart.test.json +13 -0
- package/dist/registry/checkbox.test.json +13 -0
- package/dist/registry/collapsible.test.json +13 -0
- package/dist/registry/command.test.json +13 -0
- package/dist/registry/context-menu.test.json +13 -0
- package/dist/registry/dialog.test.json +13 -0
- package/dist/registry/drawer.test.json +13 -0
- package/dist/registry/dropdown-menu.test.json +13 -0
- package/dist/registry/form.test.json +13 -0
- package/dist/registry/hover-card.test.json +13 -0
- package/dist/registry/index.json +336 -0
- package/dist/registry/input.test.json +13 -0
- package/dist/registry/label.test.json +13 -0
- package/dist/registry/menubar.test.json +13 -0
- package/dist/registry/navigation-menu.test.json +13 -0
- package/dist/registry/pagination.test.json +13 -0
- package/dist/registry/popover.test.json +13 -0
- package/dist/registry/progress.json +1 -1
- package/dist/registry/progress.test.json +13 -0
- package/dist/registry/radio-group.test.json +13 -0
- package/dist/registry/resizable.test.json +13 -0
- package/dist/registry/scroll-area.test.json +13 -0
- package/dist/registry/search.json +13 -0
- package/dist/registry/search.test.json +13 -0
- package/dist/registry/select.test.json +13 -0
- package/dist/registry/separator.test.json +13 -0
- package/dist/registry/sheet.test.json +13 -0
- package/dist/registry/skeleton.test.json +13 -0
- package/dist/registry/slider.test.json +13 -0
- package/dist/registry/sonner.test.json +13 -0
- package/dist/registry/switch.test.json +13 -0
- package/dist/registry/table.test.json +13 -0
- package/dist/registry/tabs.test.json +13 -0
- package/dist/registry/textarea.test.json +13 -0
- package/dist/registry/theme-toggle.json +13 -0
- package/dist/registry/toast.test.json +13 -0
- package/dist/registry/toggle-group.test.json +13 -0
- package/dist/registry/toggle.test.json +13 -0
- package/dist/registry/tooltip.test.json +13 -0
- package/dist/setupTests.d.ts +2 -0
- package/dist/setupTests.d.ts.map +1 -0
- package/dist/{vendor-ZhQmrf1h.mjs → vendor-BLvpSabH.mjs} +7238 -7136
- package/dist/vendor-BLvpSabH.mjs.map +1 -0
- package/dist/vendor-n4WFhtJT.js +73 -0
- package/dist/vendor-n4WFhtJT.js.map +1 -0
- package/eslint.config.mjs +8 -81
- package/package.json +44 -46
- package/release-please-config.json +36 -0
- package/src/App.tsx +70 -7
- package/src/components/docs/Footer.tsx +51 -30
- package/src/components/docs/PropsTable.tsx +43 -0
- package/src/components/docs/Sidebar.tsx +57 -71
- package/src/components/docs/index.ts +1 -0
- package/src/components/ui/accordion.test.tsx +86 -0
- package/src/components/ui/alert-dialog.test.tsx +89 -0
- package/src/components/ui/alert.test.tsx +33 -0
- package/src/components/ui/aspect-ratio.test.tsx +34 -0
- package/src/components/ui/avatar.test.tsx +33 -0
- package/src/components/ui/badge.test.tsx +24 -0
- package/src/components/ui/breadcrumb.test.tsx +55 -0
- package/src/components/ui/button.test.tsx +62 -0
- package/src/components/ui/calendar.test.tsx +23 -0
- package/src/components/ui/calendar.tsx +14 -10
- package/src/components/ui/card.test.tsx +35 -0
- package/src/components/ui/carousel.test.tsx +37 -0
- package/src/components/ui/chart.test.tsx +62 -0
- package/src/components/ui/checkbox.test.tsx +30 -0
- package/src/components/ui/collapsible.test.tsx +51 -0
- package/src/components/ui/command.test.tsx +79 -0
- package/src/components/ui/context-menu.test.tsx +37 -0
- package/src/components/ui/dialog.test.tsx +66 -0
- package/src/components/ui/drawer.test.tsx +68 -0
- package/src/components/ui/dropdown-menu.test.tsx +93 -0
- package/src/components/ui/form.test.tsx +85 -0
- package/src/components/ui/hover-card.test.tsx +48 -0
- package/src/components/ui/input.test.tsx +33 -0
- package/src/components/ui/label.test.tsx +27 -0
- package/src/components/ui/menubar.test.tsx +92 -0
- package/src/components/ui/navigation-menu.test.tsx +53 -0
- package/src/components/ui/pagination.test.tsx +57 -0
- package/src/components/ui/popover.test.tsx +31 -0
- package/src/components/ui/progress.test.tsx +18 -0
- package/src/components/ui/progress.tsx +1 -0
- package/src/components/ui/radio-group.test.tsx +39 -0
- package/src/components/ui/resizable.test.tsx +23 -0
- package/src/components/ui/scroll-area.test.tsx +15 -0
- package/src/components/ui/search.test.tsx +75 -0
- package/src/components/ui/search.tsx +93 -0
- package/src/components/ui/select.test.tsx +42 -0
- package/src/components/ui/separator.test.tsx +16 -0
- package/src/components/ui/sheet.test.tsx +48 -0
- package/src/components/ui/skeleton.test.tsx +13 -0
- package/src/components/ui/slider.test.tsx +18 -0
- package/src/components/ui/sonner.test.tsx +13 -0
- package/src/components/ui/switch.test.tsx +22 -0
- package/src/components/ui/table.test.tsx +29 -0
- package/src/components/ui/tabs.test.tsx +43 -0
- package/src/components/ui/textarea.test.tsx +21 -0
- package/src/components/ui/theme-toggle.tsx +108 -0
- package/src/components/ui/toast.test.tsx +42 -0
- package/src/components/ui/toggle-group.test.tsx +40 -0
- package/src/components/ui/toggle.test.tsx +21 -0
- package/src/components/ui/tooltip.test.tsx +25 -0
- package/src/globals.css +39 -34
- package/src/index.ts +2 -0
- package/src/lib/tokens.ts +54 -0
- package/src/pages/ColorTokensDocs.tsx +181 -0
- package/src/pages/GettingStarted.tsx +55 -35
- package/src/pages/components/AccordionDocs.tsx +109 -0
- package/src/pages/components/AlertDialogDocs.tsx +88 -0
- package/src/pages/components/AlertDocs.tsx +20 -0
- package/src/pages/components/AspectRatioDocs.tsx +21 -0
- package/src/pages/components/AvatarDocs.tsx +48 -0
- package/src/pages/components/BadgeDocs.tsx +20 -0
- package/src/pages/components/BreadcrumbDocs.tsx +33 -0
- package/src/pages/components/ButtonDocs.tsx +43 -0
- package/src/pages/components/CalendarDocs.tsx +43 -0
- package/src/pages/components/CardDocs.tsx +20 -0
- package/src/pages/components/CarouselDocs.tsx +31 -0
- package/src/pages/components/ChartDocs.tsx +131 -101
- package/src/pages/components/CheckboxDocs.tsx +58 -0
- package/src/pages/components/CollapsibleDocs.tsx +51 -0
- package/src/pages/components/CommandDocs.tsx +109 -0
- package/src/pages/components/ContextMenuDocs.tsx +65 -0
- package/src/pages/components/DialogDocs.tsx +98 -11
- package/src/pages/components/DrawerDocs.tsx +210 -15
- package/src/pages/components/DropdownMenuDocs.tsx +273 -11
- package/src/pages/components/FormDocs.tsx +149 -70
- package/src/pages/components/HoverCardDocs.tsx +82 -5
- package/src/pages/components/InputDocs.tsx +51 -20
- package/src/pages/components/LabelDocs.tsx +40 -9
- package/src/pages/components/MenubarDocs.tsx +191 -18
- package/src/pages/components/NavigationMenuDocs.tsx +147 -49
- package/src/pages/components/PaginationDocs.tsx +27 -2
- package/src/pages/components/PopoverDocs.tsx +124 -2
- package/src/pages/components/ProgressDocs.tsx +54 -24
- package/src/pages/components/RadioGroupDocs.tsx +95 -1
- package/src/pages/components/ResizableDocs.tsx +102 -75
- package/src/pages/components/ScrollAreaDocs.tsx +64 -51
- package/src/pages/components/SearchDocs.tsx +194 -0
- package/src/pages/components/SelectDocs.tsx +119 -48
- package/src/pages/components/SeparatorDocs.tsx +37 -2
- package/src/pages/components/SheetDocs.tsx +112 -38
- package/src/pages/components/SkeletonDocs.tsx +16 -20
- package/src/pages/components/SliderDocs.tsx +96 -10
- package/src/pages/components/SonnerDocs.tsx +89 -61
- package/src/pages/components/SwitchDocs.tsx +65 -10
- package/src/pages/components/TableDocs.tsx +89 -14
- package/src/pages/components/TabsDocs.tsx +149 -37
- package/src/pages/components/TextareaDocs.tsx +38 -32
- package/src/pages/components/ThemeToggleDocs.tsx +122 -0
- package/src/pages/components/ToastDocs.tsx +104 -65
- package/src/pages/components/ToggleDocs.tsx +55 -38
- package/src/pages/components/ToggleGroupDocs.tsx +96 -58
- package/src/pages/components/TooltipDocs.tsx +112 -3
- package/src/pages/index.ts +3 -0
- package/src/setupTests.ts +47 -0
- package/temp.md +292 -0
- package/vitest.config.ts +4 -0
- package/dist/vendor-CMSUBoIg.js +0 -73
- package/dist/vendor-CMSUBoIg.js.map +0 -1
- package/dist/vendor-ZhQmrf1h.mjs.map +0 -1
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { zodResolver } from '@hookform/resolvers/zod';
|
|
2
|
+
import { render, screen, waitFor } from '@testing-library/react';
|
|
3
|
+
import userEvent from '@testing-library/user-event';
|
|
4
|
+
import { useForm } from 'react-hook-form';
|
|
5
|
+
import { describe, expect, it } from 'vitest';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import { Button } from './button';
|
|
8
|
+
import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from './form';
|
|
9
|
+
import { Input } from './input';
|
|
10
|
+
|
|
11
|
+
const formSchema = z.object({
|
|
12
|
+
username: z.string().min(2, {
|
|
13
|
+
message: 'Username must be at least 2 characters.',
|
|
14
|
+
}),
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
function TestForm({ onSubmit }: { onSubmit: (values: z.infer<typeof formSchema>) => void }) {
|
|
18
|
+
const form = useForm<z.infer<typeof formSchema>>({
|
|
19
|
+
resolver: zodResolver(formSchema),
|
|
20
|
+
defaultValues: {
|
|
21
|
+
username: '',
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<Form {...form}>
|
|
27
|
+
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
|
28
|
+
<FormField
|
|
29
|
+
control={form.control}
|
|
30
|
+
name="username"
|
|
31
|
+
render={({ field }) => (
|
|
32
|
+
<FormItem>
|
|
33
|
+
<FormLabel>Username</FormLabel>
|
|
34
|
+
<FormControl>
|
|
35
|
+
<Input placeholder="shadcn" {...field} />
|
|
36
|
+
</FormControl>
|
|
37
|
+
<FormDescription>This is your public display name.</FormDescription>
|
|
38
|
+
<FormMessage />
|
|
39
|
+
</FormItem>
|
|
40
|
+
)}
|
|
41
|
+
/>
|
|
42
|
+
<Button type="submit">Submit</Button>
|
|
43
|
+
</form>
|
|
44
|
+
</Form>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
describe('Form', () => {
|
|
49
|
+
it('renders form fields correctly', () => {
|
|
50
|
+
render(<TestForm onSubmit={() => {}} />);
|
|
51
|
+
|
|
52
|
+
expect(screen.getByLabelText('Username')).toBeInTheDocument();
|
|
53
|
+
expect(screen.getByPlaceholderText('shadcn')).toBeInTheDocument();
|
|
54
|
+
expect(screen.getByText('This is your public display name.')).toBeInTheDocument();
|
|
55
|
+
expect(screen.getByRole('button', { name: 'Submit' })).toBeInTheDocument();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('validates input and displays error message', async () => {
|
|
59
|
+
const user = userEvent.setup();
|
|
60
|
+
render(<TestForm onSubmit={() => {}} />);
|
|
61
|
+
|
|
62
|
+
const submitButton = screen.getByRole('button', { name: 'Submit' });
|
|
63
|
+
await user.click(submitButton);
|
|
64
|
+
|
|
65
|
+
await waitFor(() => {
|
|
66
|
+
expect(screen.getByText('Username must be at least 2 characters.')).toBeVisible();
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('submits valid data', async () => {
|
|
71
|
+
const user = userEvent.setup();
|
|
72
|
+
const { vi } = await import('vitest');
|
|
73
|
+
const mockSubmit = vi.fn();
|
|
74
|
+
|
|
75
|
+
render(<TestForm onSubmit={mockSubmit} />);
|
|
76
|
+
|
|
77
|
+
const input = screen.getByLabelText('Username');
|
|
78
|
+
await user.type(input, 'johndoe');
|
|
79
|
+
await user.click(screen.getByRole('button', { name: 'Submit' }));
|
|
80
|
+
|
|
81
|
+
await waitFor(() => {
|
|
82
|
+
expect(mockSubmit).toHaveBeenCalledWith({ username: 'johndoe' }, expect.anything());
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { render, screen, waitFor } from '@testing-library/react';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
3
|
+
import { describe, expect, it } from 'vitest';
|
|
4
|
+
import { HoverCard, HoverCardContent, HoverCardTrigger } from './hover-card';
|
|
5
|
+
|
|
6
|
+
describe('HoverCard', () => {
|
|
7
|
+
it('renders trigger correctly', () => {
|
|
8
|
+
render(
|
|
9
|
+
<HoverCard>
|
|
10
|
+
<HoverCardTrigger>Hover me</HoverCardTrigger>
|
|
11
|
+
<HoverCardContent>Content</HoverCardContent>
|
|
12
|
+
</HoverCard>,
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
expect(screen.getByText('Hover me')).toBeInTheDocument();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('shows content on hover', async () => {
|
|
19
|
+
const user = userEvent.setup();
|
|
20
|
+
render(
|
|
21
|
+
<HoverCard openDelay={0} closeDelay={0}>
|
|
22
|
+
<HoverCardTrigger>Hover me</HoverCardTrigger>
|
|
23
|
+
<HoverCardContent>Content</HoverCardContent>
|
|
24
|
+
</HoverCard>,
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
const trigger = screen.getByText('Hover me');
|
|
28
|
+
|
|
29
|
+
// Initial state
|
|
30
|
+
expect(screen.queryByText('Content')).not.toBeInTheDocument();
|
|
31
|
+
|
|
32
|
+
// Hover
|
|
33
|
+
await user.hover(trigger);
|
|
34
|
+
|
|
35
|
+
// Should be visible
|
|
36
|
+
await waitFor(() => {
|
|
37
|
+
expect(screen.getByText('Content')).toBeVisible();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Unhover
|
|
41
|
+
await user.unhover(trigger);
|
|
42
|
+
|
|
43
|
+
// Should be hidden
|
|
44
|
+
await waitFor(() => {
|
|
45
|
+
expect(screen.queryByText('Content')).not.toBeInTheDocument();
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { describe, expect, it } from 'vitest';
|
|
5
|
+
import { Input } from './input';
|
|
6
|
+
|
|
7
|
+
describe('Input', () => {
|
|
8
|
+
it('renders correctly', () => {
|
|
9
|
+
render(<Input placeholder="Enter text" />);
|
|
10
|
+
expect(screen.getByPlaceholderText('Enter text')).toBeInTheDocument();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('accepts user input', async () => {
|
|
14
|
+
const user = userEvent.setup();
|
|
15
|
+
render(<Input placeholder="Enter text" />);
|
|
16
|
+
|
|
17
|
+
const input = screen.getByPlaceholderText('Enter text');
|
|
18
|
+
await user.type(input, 'Hello World');
|
|
19
|
+
|
|
20
|
+
expect(input).toHaveValue('Hello World');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('handles disabled state', () => {
|
|
24
|
+
render(<Input disabled placeholder="Disabled" />);
|
|
25
|
+
expect(screen.getByPlaceholderText('Disabled')).toBeDisabled();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('forwards ref', () => {
|
|
29
|
+
const ref = React.createRef<HTMLInputElement>();
|
|
30
|
+
render(<Input ref={ref} />);
|
|
31
|
+
expect(ref.current).toBeInstanceOf(HTMLInputElement);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { Label } from './label';
|
|
4
|
+
|
|
5
|
+
describe('Label', () => {
|
|
6
|
+
it('renders correctly', () => {
|
|
7
|
+
render(<Label>Test Label</Label>);
|
|
8
|
+
expect(screen.getByText('Test Label')).toBeInTheDocument();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('renders within the DOM', () => {
|
|
12
|
+
const { container } = render(<Label>Test Label</Label>);
|
|
13
|
+
expect(container.firstChild).toBeInTheDocument();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('supports htmlFor attribute', () => {
|
|
17
|
+
render(
|
|
18
|
+
<>
|
|
19
|
+
<Label htmlFor="test-input">Test Input</Label>
|
|
20
|
+
<input id="test-input" />
|
|
21
|
+
</>,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const label = screen.getByText('Test Input');
|
|
25
|
+
expect(label).toHaveAttribute('for', 'test-input');
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
3
|
+
import { describe, expect, it } from 'vitest';
|
|
4
|
+
import {
|
|
5
|
+
Menubar,
|
|
6
|
+
MenubarCheckboxItem,
|
|
7
|
+
MenubarContent,
|
|
8
|
+
MenubarItem,
|
|
9
|
+
MenubarMenu,
|
|
10
|
+
MenubarRadioGroup,
|
|
11
|
+
MenubarRadioItem,
|
|
12
|
+
MenubarTrigger,
|
|
13
|
+
} from './menubar';
|
|
14
|
+
|
|
15
|
+
describe('Menubar', () => {
|
|
16
|
+
it('renders trigger correctly', () => {
|
|
17
|
+
render(
|
|
18
|
+
<Menubar>
|
|
19
|
+
<MenubarMenu>
|
|
20
|
+
<MenubarTrigger>File</MenubarTrigger>
|
|
21
|
+
<MenubarContent>
|
|
22
|
+
<MenubarItem>New Tab</MenubarItem>
|
|
23
|
+
</MenubarContent>
|
|
24
|
+
</MenubarMenu>
|
|
25
|
+
</Menubar>,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
expect(screen.getByText('File')).toBeInTheDocument();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('opens menu on click', async () => {
|
|
32
|
+
const user = userEvent.setup();
|
|
33
|
+
render(
|
|
34
|
+
<Menubar>
|
|
35
|
+
<MenubarMenu>
|
|
36
|
+
<MenubarTrigger>File</MenubarTrigger>
|
|
37
|
+
<MenubarContent>
|
|
38
|
+
<MenubarItem>New Tab</MenubarItem>
|
|
39
|
+
<MenubarItem>New Window</MenubarItem>
|
|
40
|
+
</MenubarContent>
|
|
41
|
+
</MenubarMenu>
|
|
42
|
+
</Menubar>,
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
await user.click(screen.getByText('File'));
|
|
46
|
+
|
|
47
|
+
expect(screen.getByText('New Tab')).toBeVisible();
|
|
48
|
+
expect(screen.getByText('New Window')).toBeVisible();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('handles checkbox items', async () => {
|
|
52
|
+
const user = userEvent.setup();
|
|
53
|
+
render(
|
|
54
|
+
<Menubar>
|
|
55
|
+
<MenubarMenu>
|
|
56
|
+
<MenubarTrigger>View</MenubarTrigger>
|
|
57
|
+
<MenubarContent>
|
|
58
|
+
<MenubarCheckboxItem checked>Show Sidebar</MenubarCheckboxItem>
|
|
59
|
+
<MenubarCheckboxItem checked={false}>Show Status Bar</MenubarCheckboxItem>
|
|
60
|
+
</MenubarContent>
|
|
61
|
+
</MenubarMenu>
|
|
62
|
+
</Menubar>,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
await user.click(screen.getByText('View'));
|
|
66
|
+
|
|
67
|
+
expect(screen.getByRole('menuitemcheckbox', { name: 'Show Sidebar' })).toBeChecked();
|
|
68
|
+
expect(screen.getByRole('menuitemcheckbox', { name: 'Show Status Bar' })).not.toBeChecked();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('handles radio items', async () => {
|
|
72
|
+
const user = userEvent.setup();
|
|
73
|
+
render(
|
|
74
|
+
<Menubar>
|
|
75
|
+
<MenubarMenu>
|
|
76
|
+
<MenubarTrigger>Profiles</MenubarTrigger>
|
|
77
|
+
<MenubarContent>
|
|
78
|
+
<MenubarRadioGroup value="andy">
|
|
79
|
+
<MenubarRadioItem value="andy">Andy</MenubarRadioItem>
|
|
80
|
+
<MenubarRadioItem value="benoit">Benoit</MenubarRadioItem>
|
|
81
|
+
</MenubarRadioGroup>
|
|
82
|
+
</MenubarContent>
|
|
83
|
+
</MenubarMenu>
|
|
84
|
+
</Menubar>,
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
await user.click(screen.getByText('Profiles'));
|
|
88
|
+
|
|
89
|
+
expect(screen.getByRole('menuitemradio', { name: 'Andy' })).toBeChecked();
|
|
90
|
+
expect(screen.getByRole('menuitemradio', { name: 'Benoit' })).not.toBeChecked();
|
|
91
|
+
});
|
|
92
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
3
|
+
import { describe, expect, it } from 'vitest';
|
|
4
|
+
import {
|
|
5
|
+
NavigationMenu,
|
|
6
|
+
NavigationMenuContent,
|
|
7
|
+
NavigationMenuItem,
|
|
8
|
+
NavigationMenuLink,
|
|
9
|
+
NavigationMenuList,
|
|
10
|
+
NavigationMenuTrigger,
|
|
11
|
+
} from './navigation-menu';
|
|
12
|
+
|
|
13
|
+
describe('NavigationMenu', () => {
|
|
14
|
+
it('renders trigger correctly', () => {
|
|
15
|
+
render(
|
|
16
|
+
<NavigationMenu>
|
|
17
|
+
<NavigationMenuList>
|
|
18
|
+
<NavigationMenuItem>
|
|
19
|
+
<NavigationMenuTrigger>Item One</NavigationMenuTrigger>
|
|
20
|
+
<NavigationMenuContent>
|
|
21
|
+
<NavigationMenuLink>Link One</NavigationMenuLink>
|
|
22
|
+
</NavigationMenuContent>
|
|
23
|
+
</NavigationMenuItem>
|
|
24
|
+
</NavigationMenuList>
|
|
25
|
+
</NavigationMenu>,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
expect(screen.getByText('Item One')).toBeInTheDocument();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('shows content on click (or hover depending on implementation)', async () => {
|
|
32
|
+
// Radix Navigation Menu usually works on hover for desktop, click for touch/mobile.
|
|
33
|
+
// In JSDOM, we can simulate clicks.
|
|
34
|
+
const user = userEvent.setup();
|
|
35
|
+
render(
|
|
36
|
+
<NavigationMenu>
|
|
37
|
+
<NavigationMenuList>
|
|
38
|
+
<NavigationMenuItem>
|
|
39
|
+
<NavigationMenuTrigger>Item One</NavigationMenuTrigger>
|
|
40
|
+
<NavigationMenuContent>
|
|
41
|
+
<NavigationMenuLink>Link One</NavigationMenuLink>
|
|
42
|
+
</NavigationMenuContent>
|
|
43
|
+
</NavigationMenuItem>
|
|
44
|
+
</NavigationMenuList>
|
|
45
|
+
</NavigationMenu>,
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const trigger = screen.getByText('Item One');
|
|
49
|
+
await user.click(trigger);
|
|
50
|
+
|
|
51
|
+
expect(screen.getByText('Link One')).toBeVisible();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import {
|
|
4
|
+
Pagination,
|
|
5
|
+
PaginationContent,
|
|
6
|
+
PaginationEllipsis,
|
|
7
|
+
PaginationItem,
|
|
8
|
+
PaginationLink,
|
|
9
|
+
PaginationNext,
|
|
10
|
+
PaginationPrevious,
|
|
11
|
+
} from './pagination';
|
|
12
|
+
|
|
13
|
+
describe('Pagination', () => {
|
|
14
|
+
it('renders correctly', () => {
|
|
15
|
+
render(
|
|
16
|
+
<Pagination>
|
|
17
|
+
<PaginationContent>
|
|
18
|
+
<PaginationItem>
|
|
19
|
+
<PaginationPrevious href="#" />
|
|
20
|
+
</PaginationItem>
|
|
21
|
+
<PaginationItem>
|
|
22
|
+
<PaginationLink href="#">1</PaginationLink>
|
|
23
|
+
</PaginationItem>
|
|
24
|
+
<PaginationItem>
|
|
25
|
+
<PaginationEllipsis />
|
|
26
|
+
</PaginationItem>
|
|
27
|
+
<PaginationItem>
|
|
28
|
+
<PaginationNext href="#" />
|
|
29
|
+
</PaginationItem>
|
|
30
|
+
</PaginationContent>
|
|
31
|
+
</Pagination>,
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
expect(screen.getByRole('navigation', { name: 'pagination' })).toBeInTheDocument();
|
|
35
|
+
expect(screen.getByText('Previous')).toBeInTheDocument();
|
|
36
|
+
expect(screen.getByText('1')).toBeInTheDocument();
|
|
37
|
+
expect(screen.getByText('Next')).toBeInTheDocument();
|
|
38
|
+
expect(screen.getByText('More pages')).toBeInTheDocument();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('marks active page correctly', () => {
|
|
42
|
+
render(
|
|
43
|
+
<Pagination>
|
|
44
|
+
<PaginationContent>
|
|
45
|
+
<PaginationItem>
|
|
46
|
+
<PaginationLink href="#" isActive>
|
|
47
|
+
1
|
|
48
|
+
</PaginationLink>
|
|
49
|
+
</PaginationItem>
|
|
50
|
+
</PaginationContent>
|
|
51
|
+
</Pagination>,
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
const link = screen.getByText('1').closest('a');
|
|
55
|
+
expect(link).toHaveAttribute('aria-current', 'page');
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
3
|
+
import { describe, expect, it } from 'vitest';
|
|
4
|
+
import { Popover, PopoverContent, PopoverTrigger } from './popover';
|
|
5
|
+
|
|
6
|
+
describe('Popover', () => {
|
|
7
|
+
it('renders trigger correctly', () => {
|
|
8
|
+
render(
|
|
9
|
+
<Popover>
|
|
10
|
+
<PopoverTrigger>Open</PopoverTrigger>
|
|
11
|
+
<PopoverContent>Content</PopoverContent>
|
|
12
|
+
</Popover>,
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
expect(screen.getByText('Open')).toBeInTheDocument();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('opens content on click', async () => {
|
|
19
|
+
const user = userEvent.setup();
|
|
20
|
+
render(
|
|
21
|
+
<Popover>
|
|
22
|
+
<PopoverTrigger>Open</PopoverTrigger>
|
|
23
|
+
<PopoverContent>Content</PopoverContent>
|
|
24
|
+
</Popover>,
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
await user.click(screen.getByText('Open'));
|
|
28
|
+
|
|
29
|
+
expect(screen.getByText('Content')).toBeVisible();
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { Progress } from './progress';
|
|
4
|
+
|
|
5
|
+
describe('Progress', () => {
|
|
6
|
+
it('renders correctly', () => {
|
|
7
|
+
render(<Progress value={50} aria-label="progress-bar" />);
|
|
8
|
+
expect(screen.getByRole('progressbar')).toBeInTheDocument();
|
|
9
|
+
expect(screen.getByRole('progressbar')).toHaveAttribute('aria-valuenow', '50');
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('renders correctly with no value', () => {
|
|
13
|
+
render(<Progress aria-label="progress-bar" />);
|
|
14
|
+
expect(screen.getByRole('progressbar')).toBeInTheDocument();
|
|
15
|
+
// When value is undefined, Radix UI might behave in specific ways, typically indeterminate or 0.
|
|
16
|
+
// Our wrapper: transform: `translateX(-${100 - (value || 0)}%)` -> -100%
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
3
|
+
import { describe, expect, it } from 'vitest';
|
|
4
|
+
import { RadioGroup, RadioGroupItem } from './radio-group';
|
|
5
|
+
|
|
6
|
+
describe('RadioGroup', () => {
|
|
7
|
+
it('renders correctly', () => {
|
|
8
|
+
render(
|
|
9
|
+
<RadioGroup defaultValue="option-one">
|
|
10
|
+
<RadioGroupItem value="option-one" id="option-one" aria-label="Option One" />
|
|
11
|
+
<RadioGroupItem value="option-two" id="option-two" aria-label="Option Two" />
|
|
12
|
+
</RadioGroup>,
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
expect(screen.getByRole('radio', { name: /Option One/i })).toBeInTheDocument();
|
|
16
|
+
// Radix RadioGroup renders standard inputs visually hidden.
|
|
17
|
+
// Testing library query by role 'radio' should find them.
|
|
18
|
+
// However, since we didn't provide labels, we might need to rely on 'checked' state or IDs.
|
|
19
|
+
|
|
20
|
+
const radio1 = screen.getByRole('radio', { checked: true });
|
|
21
|
+
expect(radio1).toBeInTheDocument();
|
|
22
|
+
expect(radio1).toHaveValue('option-one');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('changes value on click', async () => {
|
|
26
|
+
const user = userEvent.setup();
|
|
27
|
+
render(
|
|
28
|
+
<RadioGroup defaultValue="option-one">
|
|
29
|
+
<RadioGroupItem value="option-one" />
|
|
30
|
+
<RadioGroupItem value="option-two" data-testid="radio-two" />
|
|
31
|
+
</RadioGroup>,
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const radio2 = screen.getByTestId('radio-two');
|
|
35
|
+
await user.click(radio2);
|
|
36
|
+
|
|
37
|
+
expect(radio2).toBeChecked();
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from './resizable';
|
|
4
|
+
|
|
5
|
+
describe('Resizable', () => {
|
|
6
|
+
it('renders correctly', () => {
|
|
7
|
+
// Basic render test
|
|
8
|
+
render(
|
|
9
|
+
<ResizablePanelGroup direction="horizontal">
|
|
10
|
+
<ResizablePanel defaultSize={50}>
|
|
11
|
+
<div>One</div>
|
|
12
|
+
</ResizablePanel>
|
|
13
|
+
<ResizableHandle />
|
|
14
|
+
<ResizablePanel defaultSize={50}>
|
|
15
|
+
<div>Two</div>
|
|
16
|
+
</ResizablePanel>
|
|
17
|
+
</ResizablePanelGroup>,
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
expect(screen.getByText('One')).toBeInTheDocument();
|
|
21
|
+
expect(screen.getByText('Two')).toBeInTheDocument();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { ScrollArea, ScrollBar } from './scroll-area';
|
|
4
|
+
|
|
5
|
+
describe('ScrollArea', () => {
|
|
6
|
+
it('renders correctly', () => {
|
|
7
|
+
render(
|
|
8
|
+
<ScrollArea className="h-[200px] w-[350px]">
|
|
9
|
+
<div>Content</div>
|
|
10
|
+
<ScrollBar />
|
|
11
|
+
</ScrollArea>,
|
|
12
|
+
);
|
|
13
|
+
expect(screen.getByText('Content')).toBeInTheDocument();
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { fireEvent, render, screen } from '@testing-library/react';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
4
|
+
import { CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, Search, SearchTrigger } from './search';
|
|
5
|
+
|
|
6
|
+
// Mock CommandDialog since it uses Radix Dialog which might need a portal
|
|
7
|
+
vi.mock('@/components/ui/dialog', () => ({
|
|
8
|
+
Dialog: ({ children, open }: { children: React.ReactNode; open: boolean }) => (open ? <div>{children}</div> : null),
|
|
9
|
+
DialogContent: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
|
10
|
+
DialogPortal: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
|
11
|
+
DialogOverlay: () => null,
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
describe('Search', () => {
|
|
15
|
+
it('renders search trigger', () => {
|
|
16
|
+
render(<SearchTrigger />);
|
|
17
|
+
expect(screen.getByText('Search docs...')).toBeInTheDocument();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('opens search dialog when trigger is clicked (controlled)', () => {
|
|
21
|
+
const onOpenChange = vi.fn();
|
|
22
|
+
render(
|
|
23
|
+
<Search open={false} onOpenChange={onOpenChange}>
|
|
24
|
+
<CommandInput placeholder="Search..." />
|
|
25
|
+
</Search>,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
// The dialog should be closed initially
|
|
29
|
+
expect(screen.queryByPlaceholderText('Search...')).not.toBeInTheDocument();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('responds to keyboard shortcuts', () => {
|
|
33
|
+
render(
|
|
34
|
+
<Search>
|
|
35
|
+
<CommandInput placeholder="Search..." />
|
|
36
|
+
<CommandList>
|
|
37
|
+
<CommandItem>Result 1</CommandItem>
|
|
38
|
+
</CommandList>
|
|
39
|
+
</Search>,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
// Simulate Cmd+K
|
|
43
|
+
fireEvent.keyDown(document, { key: 'k', metaKey: true });
|
|
44
|
+
|
|
45
|
+
// Check if dialog content is visible
|
|
46
|
+
expect(screen.getByPlaceholderText('Search...')).toBeInTheDocument();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('filters results correctly', () => {
|
|
50
|
+
render(
|
|
51
|
+
<Search open={true}>
|
|
52
|
+
<CommandInput placeholder="Search..." />
|
|
53
|
+
<CommandList>
|
|
54
|
+
<CommandEmpty>No results.</CommandEmpty>
|
|
55
|
+
<CommandGroup heading="Components">
|
|
56
|
+
<SearchItem>Button</SearchItem>
|
|
57
|
+
<SearchItem>Input</SearchItem>
|
|
58
|
+
</CommandGroup>
|
|
59
|
+
</CommandList>
|
|
60
|
+
</Search>,
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const input = screen.getByPlaceholderText('Search...');
|
|
64
|
+
fireEvent.change(input, { target: { value: 'But' } });
|
|
65
|
+
|
|
66
|
+
expect(screen.getByText('Button')).toBeInTheDocument();
|
|
67
|
+
// cmdk removes non-matching items from the DOM
|
|
68
|
+
expect(screen.queryByText('Input')).not.toBeInTheDocument();
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Helper component for testing
|
|
73
|
+
function SearchItem({ children }: { children: React.ReactNode }) {
|
|
74
|
+
return <CommandItem>{children}</CommandItem>;
|
|
75
|
+
}
|