@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
|
@@ -1,18 +1,8 @@
|
|
|
1
|
+
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion';
|
|
1
2
|
import { Button } from '@/components/ui/button';
|
|
2
3
|
import { ScrollArea } from '@/components/ui/scroll-area';
|
|
3
4
|
import { cn } from '@/lib/utils';
|
|
4
|
-
import {
|
|
5
|
-
ChevronDown,
|
|
6
|
-
ChevronRight,
|
|
7
|
-
FormInput,
|
|
8
|
-
Home,
|
|
9
|
-
Layers,
|
|
10
|
-
LayoutGrid,
|
|
11
|
-
MessageSquare,
|
|
12
|
-
Navigation,
|
|
13
|
-
Sparkles,
|
|
14
|
-
Table2,
|
|
15
|
-
} from 'lucide-react';
|
|
5
|
+
import { FormInput, Home, Layers, LayoutGrid, MessageSquare, Navigation, Sparkles, Table2 } from 'lucide-react';
|
|
16
6
|
import * as React from 'react';
|
|
17
7
|
import { version } from '../../../package.json';
|
|
18
8
|
|
|
@@ -51,6 +41,7 @@ const categoryConfig: Record<ComponentCategory, { label: string; icon: React.Rea
|
|
|
51
41
|
export const navItems: NavItem[] = [
|
|
52
42
|
// Getting Started
|
|
53
43
|
{ id: 'getting-started', label: 'Introduction', category: 'getting-started' },
|
|
44
|
+
{ id: 'color-tokens', label: 'Color Tokens', category: 'getting-started' },
|
|
54
45
|
{ id: 'installation', label: 'Installation', category: 'getting-started' },
|
|
55
46
|
|
|
56
47
|
// Layout
|
|
@@ -102,6 +93,7 @@ export const navItems: NavItem[] = [
|
|
|
102
93
|
{ id: 'dropdown-menu', label: 'Dropdown Menu', category: 'overlay' },
|
|
103
94
|
{ id: 'context-menu', label: 'Context Menu', category: 'overlay' },
|
|
104
95
|
{ id: 'command', label: 'Command', category: 'overlay' },
|
|
96
|
+
{ id: 'search', label: 'Search', category: 'overlay' },
|
|
105
97
|
{ id: 'sheet', label: 'Sheet', category: 'overlay' },
|
|
106
98
|
{ id: 'drawer', label: 'Drawer', category: 'overlay' },
|
|
107
99
|
|
|
@@ -111,77 +103,71 @@ export const navItems: NavItem[] = [
|
|
|
111
103
|
{ id: 'carousel', label: 'Carousel', category: 'advanced' },
|
|
112
104
|
{ id: 'toggle', label: 'Toggle', category: 'advanced' },
|
|
113
105
|
{ id: 'toggle-group', label: 'Toggle Group', category: 'advanced' },
|
|
106
|
+
{ id: 'theme-toggle', label: 'Theme Toggle', category: 'advanced' },
|
|
114
107
|
];
|
|
115
108
|
|
|
116
109
|
export function Sidebar({ activeItem, onItemSelect }: SidebarProps) {
|
|
117
|
-
const [expandedCategories, setExpandedCategories] = React.useState<Set<ComponentCategory>>(
|
|
118
|
-
new Set(['getting-started', 'forms']),
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
const toggleCategory = (category: ComponentCategory) => {
|
|
122
|
-
setExpandedCategories((prev) => {
|
|
123
|
-
const next = new Set(prev);
|
|
124
|
-
if (next.has(category)) {
|
|
125
|
-
next.delete(category);
|
|
126
|
-
} else {
|
|
127
|
-
next.add(category);
|
|
128
|
-
}
|
|
129
|
-
return next;
|
|
130
|
-
});
|
|
131
|
-
};
|
|
132
|
-
|
|
133
110
|
const categories = Object.keys(categoryConfig) as ComponentCategory[];
|
|
111
|
+
const [expandedCategories, setExpandedCategories] = React.useState<string[]>(['getting-started', 'forms']);
|
|
112
|
+
|
|
113
|
+
// Ensure the category of the active item is expanded
|
|
114
|
+
React.useEffect(() => {
|
|
115
|
+
const activeNavItem = navItems.find((item) => item.id === activeItem);
|
|
116
|
+
if (activeNavItem && !expandedCategories.includes(activeNavItem.category)) {
|
|
117
|
+
setExpandedCategories((prev) => [...prev, activeNavItem.category]);
|
|
118
|
+
}
|
|
119
|
+
}, [activeItem, expandedCategories]);
|
|
134
120
|
|
|
135
121
|
return (
|
|
136
|
-
<div className="w-64 border-r bg-muted/
|
|
122
|
+
<div className="w-64 border-r bg-muted/50 flex flex-col h-full">
|
|
137
123
|
<div className="p-4 border-b">
|
|
138
124
|
<h2 className="font-semibold text-lg">GV Design System</h2>
|
|
139
125
|
<p className="text-xs text-muted-foreground">v{version}</p>
|
|
140
126
|
</div>
|
|
141
127
|
<ScrollArea className="flex-1">
|
|
142
128
|
<nav className="p-2">
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
<
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
</
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
)
|
|
184
|
-
|
|
129
|
+
<Accordion
|
|
130
|
+
type="multiple"
|
|
131
|
+
value={expandedCategories}
|
|
132
|
+
onValueChange={setExpandedCategories}
|
|
133
|
+
className="w-full space-y-1"
|
|
134
|
+
>
|
|
135
|
+
{categories.map((category) => {
|
|
136
|
+
const config = categoryConfig[category];
|
|
137
|
+
const items = navItems.filter((item) => item.category === category);
|
|
138
|
+
|
|
139
|
+
if (items.length === 0) return null;
|
|
140
|
+
|
|
141
|
+
return (
|
|
142
|
+
<AccordionItem key={category} value={category} className="border-none">
|
|
143
|
+
<AccordionTrigger className="flex items-center gap-2 px-2 py-1.5 text-sm font-medium rounded-md hover:bg-accent/50 transition-colors hover:no-underline [&>svg]:h-4 [&>svg]:w-4">
|
|
144
|
+
<div className="flex items-center gap-2 flex-1">
|
|
145
|
+
{config.icon}
|
|
146
|
+
<span className="text-left">{config.label}</span>
|
|
147
|
+
</div>
|
|
148
|
+
</AccordionTrigger>
|
|
149
|
+
<AccordionContent className="pb-1">
|
|
150
|
+
<div className="ml-4 mt-1 space-y-0.5 border-l pl-2">
|
|
151
|
+
{items.map((item) => (
|
|
152
|
+
<Button
|
|
153
|
+
key={item.id}
|
|
154
|
+
variant="ghost"
|
|
155
|
+
size="sm"
|
|
156
|
+
onClick={() => onItemSelect(item.id)}
|
|
157
|
+
className={cn(
|
|
158
|
+
'w-full justify-start h-8 px-2 font-normal',
|
|
159
|
+
activeItem === item.id && 'bg-accent text-accent-foreground',
|
|
160
|
+
)}
|
|
161
|
+
>
|
|
162
|
+
{item.label}
|
|
163
|
+
</Button>
|
|
164
|
+
))}
|
|
165
|
+
</div>
|
|
166
|
+
</AccordionContent>
|
|
167
|
+
</AccordionItem>
|
|
168
|
+
);
|
|
169
|
+
})}
|
|
170
|
+
</Accordion>
|
|
185
171
|
</nav>
|
|
186
172
|
</ScrollArea>
|
|
187
173
|
</div>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { CodeBlock } from './CodeBlock';
|
|
2
2
|
export { ComponentSection, ComponentShowcase } from './ComponentShowcase';
|
|
3
3
|
export { Footer } from './Footer';
|
|
4
|
+
export { PropsTable, type PropDefinition } from './PropsTable';
|
|
4
5
|
export { Sidebar, navItems, type ComponentCategory, type NavItem } from './Sidebar';
|
|
5
6
|
export { ThemeToggle } from './ThemeToggle';
|
|
@@ -0,0 +1,86 @@
|
|
|
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 { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from './accordion';
|
|
5
|
+
|
|
6
|
+
describe('Accordion', () => {
|
|
7
|
+
it('renders correctly', () => {
|
|
8
|
+
render(
|
|
9
|
+
<Accordion type="single" collapsible>
|
|
10
|
+
<AccordionItem value="item-1">
|
|
11
|
+
<AccordionTrigger>Trigger 1</AccordionTrigger>
|
|
12
|
+
<AccordionContent>Content 1</AccordionContent>
|
|
13
|
+
</AccordionItem>
|
|
14
|
+
</Accordion>,
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
expect(screen.getByText('Trigger 1')).toBeInTheDocument();
|
|
18
|
+
// Content should not be visible initially
|
|
19
|
+
expect(screen.queryByText('Content 1')).not.toBeInTheDocument();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('expands when clicked', async () => {
|
|
23
|
+
render(
|
|
24
|
+
<Accordion type="single" collapsible>
|
|
25
|
+
<AccordionItem value="item-1">
|
|
26
|
+
<AccordionTrigger>Trigger 1</AccordionTrigger>
|
|
27
|
+
<AccordionContent>Content 1</AccordionContent>
|
|
28
|
+
</AccordionItem>
|
|
29
|
+
</Accordion>,
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const trigger = screen.getByText('Trigger 1');
|
|
33
|
+
await userEvent.click(trigger);
|
|
34
|
+
|
|
35
|
+
await waitFor(() => {
|
|
36
|
+
expect(screen.getByText('Content 1')).toBeVisible();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('collapses when clicked again', async () => {
|
|
41
|
+
render(
|
|
42
|
+
<Accordion type="single" collapsible defaultValue="item-1">
|
|
43
|
+
<AccordionItem value="item-1">
|
|
44
|
+
<AccordionTrigger>Trigger 1</AccordionTrigger>
|
|
45
|
+
<AccordionContent>Content 1</AccordionContent>
|
|
46
|
+
</AccordionItem>
|
|
47
|
+
</Accordion>,
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// Initial state open
|
|
51
|
+
expect(screen.getByText('Content 1')).toBeVisible();
|
|
52
|
+
|
|
53
|
+
const trigger = screen.getByText('Trigger 1');
|
|
54
|
+
await userEvent.click(trigger);
|
|
55
|
+
|
|
56
|
+
await waitFor(() => {
|
|
57
|
+
expect(screen.queryByText('Content 1')).not.toBeInTheDocument();
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('handles single mode correctly', async () => {
|
|
62
|
+
render(
|
|
63
|
+
<Accordion type="single" collapsible>
|
|
64
|
+
<AccordionItem value="item-1">
|
|
65
|
+
<AccordionTrigger>Trigger 1</AccordionTrigger>
|
|
66
|
+
<AccordionContent>Content 1</AccordionContent>
|
|
67
|
+
</AccordionItem>
|
|
68
|
+
<AccordionItem value="item-2">
|
|
69
|
+
<AccordionTrigger>Trigger 2</AccordionTrigger>
|
|
70
|
+
<AccordionContent>Content 2</AccordionContent>
|
|
71
|
+
</AccordionItem>
|
|
72
|
+
</Accordion>,
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
// Click item 1
|
|
76
|
+
await userEvent.click(screen.getByText('Trigger 1'));
|
|
77
|
+
await waitFor(() => expect(screen.getByText('Content 1')).toBeVisible());
|
|
78
|
+
|
|
79
|
+
// Click item 2
|
|
80
|
+
await userEvent.click(screen.getByText('Trigger 2'));
|
|
81
|
+
await waitFor(() => expect(screen.getByText('Content 2')).toBeVisible());
|
|
82
|
+
|
|
83
|
+
// Item 1 should be closed
|
|
84
|
+
await waitFor(() => expect(screen.queryByText('Content 1')).not.toBeInTheDocument());
|
|
85
|
+
});
|
|
86
|
+
});
|
|
@@ -0,0 +1,89 @@
|
|
|
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 {
|
|
5
|
+
AlertDialog,
|
|
6
|
+
AlertDialogAction,
|
|
7
|
+
AlertDialogCancel,
|
|
8
|
+
AlertDialogContent,
|
|
9
|
+
AlertDialogDescription,
|
|
10
|
+
AlertDialogFooter,
|
|
11
|
+
AlertDialogHeader,
|
|
12
|
+
AlertDialogTitle,
|
|
13
|
+
AlertDialogTrigger,
|
|
14
|
+
} from './alert-dialog';
|
|
15
|
+
|
|
16
|
+
describe('AlertDialog', () => {
|
|
17
|
+
it('renders correctly', async () => {
|
|
18
|
+
render(
|
|
19
|
+
<AlertDialog>
|
|
20
|
+
<AlertDialogTrigger>Open</AlertDialogTrigger>
|
|
21
|
+
<AlertDialogContent>
|
|
22
|
+
<AlertDialogHeader>
|
|
23
|
+
<AlertDialogTitle>Are you sure?</AlertDialogTitle>
|
|
24
|
+
<AlertDialogDescription>This action cannot be undone.</AlertDialogDescription>
|
|
25
|
+
</AlertDialogHeader>
|
|
26
|
+
<AlertDialogFooter>
|
|
27
|
+
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
|
28
|
+
<AlertDialogAction>Continue</AlertDialogAction>
|
|
29
|
+
</AlertDialogFooter>
|
|
30
|
+
</AlertDialogContent>
|
|
31
|
+
</AlertDialog>,
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
expect(screen.getByText('Open')).toBeInTheDocument();
|
|
35
|
+
expect(screen.queryByText('Are you sure?')).not.toBeInTheDocument();
|
|
36
|
+
|
|
37
|
+
await userEvent.click(screen.getByText('Open'));
|
|
38
|
+
|
|
39
|
+
await waitFor(() => {
|
|
40
|
+
expect(screen.getByRole('alertdialog')).toBeInTheDocument();
|
|
41
|
+
expect(screen.getByText('Are you sure?')).toBeInTheDocument();
|
|
42
|
+
expect(screen.getByText('This action cannot be undone.')).toBeInTheDocument();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('closes when cancel is clicked', async () => {
|
|
47
|
+
render(
|
|
48
|
+
<AlertDialog>
|
|
49
|
+
<AlertDialogTrigger>Open</AlertDialogTrigger>
|
|
50
|
+
<AlertDialogContent>
|
|
51
|
+
<AlertDialogHeader>
|
|
52
|
+
<AlertDialogTitle>Are you sure?</AlertDialogTitle>
|
|
53
|
+
</AlertDialogHeader>
|
|
54
|
+
<AlertDialogFooter>
|
|
55
|
+
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
|
56
|
+
</AlertDialogFooter>
|
|
57
|
+
</AlertDialogContent>
|
|
58
|
+
</AlertDialog>,
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
await userEvent.click(screen.getByText('Open'));
|
|
62
|
+
await waitFor(() => expect(screen.getByRole('alertdialog')).toBeInTheDocument());
|
|
63
|
+
|
|
64
|
+
await userEvent.click(screen.getByText('Cancel'));
|
|
65
|
+
await waitFor(() => expect(screen.queryByRole('alertdialog')).not.toBeInTheDocument());
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('closes when action is clicked', async () => {
|
|
69
|
+
render(
|
|
70
|
+
<AlertDialog>
|
|
71
|
+
<AlertDialogTrigger>Open</AlertDialogTrigger>
|
|
72
|
+
<AlertDialogContent>
|
|
73
|
+
<AlertDialogHeader>
|
|
74
|
+
<AlertDialogTitle>Are you sure?</AlertDialogTitle>
|
|
75
|
+
</AlertDialogHeader>
|
|
76
|
+
<AlertDialogFooter>
|
|
77
|
+
<AlertDialogAction>Continue</AlertDialogAction>
|
|
78
|
+
</AlertDialogFooter>
|
|
79
|
+
</AlertDialogContent>
|
|
80
|
+
</AlertDialog>,
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
await userEvent.click(screen.getByText('Open'));
|
|
84
|
+
await waitFor(() => expect(screen.getByRole('alertdialog')).toBeInTheDocument());
|
|
85
|
+
|
|
86
|
+
await userEvent.click(screen.getByText('Continue'));
|
|
87
|
+
await waitFor(() => expect(screen.queryByRole('alertdialog')).not.toBeInTheDocument());
|
|
88
|
+
});
|
|
89
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { Alert, AlertDescription, AlertTitle } from './alert';
|
|
4
|
+
|
|
5
|
+
describe('Alert', () => {
|
|
6
|
+
it('renders correctly', () => {
|
|
7
|
+
render(
|
|
8
|
+
<Alert>
|
|
9
|
+
<AlertTitle>Heads up!</AlertTitle>
|
|
10
|
+
<AlertDescription>You can add components to your app using the cli.</AlertDescription>
|
|
11
|
+
</Alert>,
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
const alert = screen.getByRole('alert');
|
|
15
|
+
expect(alert).toBeInTheDocument();
|
|
16
|
+
expect(screen.getByText('Heads up!')).toBeInTheDocument();
|
|
17
|
+
expect(screen.getByText('You can add components to your app using the cli.')).toBeInTheDocument();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('renders destructive variant', () => {
|
|
21
|
+
render(
|
|
22
|
+
<Alert variant="destructive">
|
|
23
|
+
<AlertTitle>Error</AlertTitle>
|
|
24
|
+
<AlertDescription>Your session has expired.</AlertDescription>
|
|
25
|
+
</Alert>,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const alert = screen.getByRole('alert');
|
|
29
|
+
expect(alert).toBeInTheDocument();
|
|
30
|
+
expect(alert).toHaveClass('border-destructive/50');
|
|
31
|
+
expect(alert).toHaveClass('text-destructive');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { AspectRatio } from './aspect-ratio';
|
|
4
|
+
|
|
5
|
+
describe('AspectRatio', () => {
|
|
6
|
+
it('renders correctly', () => {
|
|
7
|
+
const { container } = render(
|
|
8
|
+
<AspectRatio ratio={16 / 9}>
|
|
9
|
+
<img src="test.jpg" alt="test" />
|
|
10
|
+
</AspectRatio>,
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
const img = screen.getByRole('img');
|
|
14
|
+
expect(img).toBeInTheDocument();
|
|
15
|
+
|
|
16
|
+
// Radix AspectRatio renders a wrapper with padding-bottom based on ratio
|
|
17
|
+
// We can check if the wrapper style is applied
|
|
18
|
+
const wrapper = container.firstChild;
|
|
19
|
+
expect(wrapper).toHaveStyle({ paddingBottom: expect.stringMatching(/%$/) });
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('renders with custom ratio', () => {
|
|
23
|
+
const { container } = render(
|
|
24
|
+
<AspectRatio ratio={1 / 1}>
|
|
25
|
+
<div>Square</div>
|
|
26
|
+
</AspectRatio>,
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
expect(screen.getByText('Square')).toBeInTheDocument();
|
|
30
|
+
const wrapper = container.firstChild;
|
|
31
|
+
// 1/1 ratio should be 100% padding-bottom
|
|
32
|
+
expect(wrapper).toHaveStyle({ paddingBottom: '100%' });
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { Avatar, AvatarFallback, AvatarImage } from './avatar';
|
|
4
|
+
|
|
5
|
+
describe('Avatar', () => {
|
|
6
|
+
it('renders correctly', () => {
|
|
7
|
+
render(
|
|
8
|
+
<Avatar>
|
|
9
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
|
|
10
|
+
<AvatarFallback>CN</AvatarFallback>
|
|
11
|
+
</Avatar>,
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
// In JSDOM, image loading might not happen immediately or at all without mocking.
|
|
15
|
+
// However, the elements should be in the DOM.
|
|
16
|
+
// Radix conditionally renders Image or Fallback.
|
|
17
|
+
// By default, it might render Image and hide Fallback, or vice versa depending on loading.
|
|
18
|
+
|
|
19
|
+
// Let's check that the root is present
|
|
20
|
+
const avatar = screen.getByText('CN')?.parentElement || screen.getByRole('img').parentElement;
|
|
21
|
+
expect(avatar).toBeInTheDocument();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('renders fallback when image is missing', () => {
|
|
25
|
+
render(
|
|
26
|
+
<Avatar>
|
|
27
|
+
<AvatarFallback>CN</AvatarFallback>
|
|
28
|
+
</Avatar>,
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
expect(screen.getByText('CN')).toBeInTheDocument();
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { Badge } from './badge';
|
|
4
|
+
|
|
5
|
+
describe('Badge', () => {
|
|
6
|
+
it('renders correctly', () => {
|
|
7
|
+
render(<Badge>Test Badge</Badge>);
|
|
8
|
+
expect(screen.getByText('Test Badge')).toBeInTheDocument();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('renders variants', () => {
|
|
12
|
+
const { rerender, getByText } = render(<Badge variant="default">Default</Badge>);
|
|
13
|
+
expect(getByText('Default')).toHaveClass('bg-primary');
|
|
14
|
+
|
|
15
|
+
rerender(<Badge variant="secondary">Secondary</Badge>);
|
|
16
|
+
expect(getByText('Secondary')).toHaveClass('bg-secondary');
|
|
17
|
+
|
|
18
|
+
rerender(<Badge variant="destructive">Destructive</Badge>);
|
|
19
|
+
expect(getByText('Destructive')).toHaveClass('bg-destructive');
|
|
20
|
+
|
|
21
|
+
rerender(<Badge variant="outline">Outline</Badge>);
|
|
22
|
+
expect(getByText('Outline')).toHaveClass('text-foreground');
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import {
|
|
4
|
+
Breadcrumb,
|
|
5
|
+
BreadcrumbItem,
|
|
6
|
+
BreadcrumbLink,
|
|
7
|
+
BreadcrumbList,
|
|
8
|
+
BreadcrumbPage,
|
|
9
|
+
BreadcrumbSeparator,
|
|
10
|
+
} from './breadcrumb';
|
|
11
|
+
|
|
12
|
+
describe('Breadcrumb', () => {
|
|
13
|
+
it('renders correctly', () => {
|
|
14
|
+
render(
|
|
15
|
+
<Breadcrumb>
|
|
16
|
+
<BreadcrumbList>
|
|
17
|
+
<BreadcrumbItem>
|
|
18
|
+
<BreadcrumbLink href="/">Home</BreadcrumbLink>
|
|
19
|
+
</BreadcrumbItem>
|
|
20
|
+
<BreadcrumbSeparator />
|
|
21
|
+
<BreadcrumbItem>
|
|
22
|
+
<BreadcrumbPage>Page</BreadcrumbPage>
|
|
23
|
+
</BreadcrumbItem>
|
|
24
|
+
</BreadcrumbList>
|
|
25
|
+
</Breadcrumb>,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const nav = screen.getByRole('navigation');
|
|
29
|
+
expect(nav).toBeInTheDocument();
|
|
30
|
+
expect(nav).toHaveAttribute('aria-label', 'breadcrumb');
|
|
31
|
+
|
|
32
|
+
const links = screen.getAllByRole('link');
|
|
33
|
+
expect(links).toHaveLength(2); // Link and Page (span role="link")
|
|
34
|
+
expect(links[0]).toHaveAttribute('href', '/');
|
|
35
|
+
expect(links[1]).toHaveTextContent('Page');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('renders custom separator', () => {
|
|
39
|
+
render(
|
|
40
|
+
<Breadcrumb>
|
|
41
|
+
<BreadcrumbList>
|
|
42
|
+
<BreadcrumbItem>
|
|
43
|
+
<BreadcrumbLink>Home</BreadcrumbLink>
|
|
44
|
+
</BreadcrumbItem>
|
|
45
|
+
<BreadcrumbSeparator>/</BreadcrumbSeparator>
|
|
46
|
+
<BreadcrumbItem>
|
|
47
|
+
<BreadcrumbPage>Page</BreadcrumbPage>
|
|
48
|
+
</BreadcrumbItem>
|
|
49
|
+
</BreadcrumbList>
|
|
50
|
+
</Breadcrumb>,
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
expect(screen.getByText('/')).toBeInTheDocument();
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
3
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
4
|
+
import { Button } from './button';
|
|
5
|
+
|
|
6
|
+
describe('Button', () => {
|
|
7
|
+
it('renders correctly', () => {
|
|
8
|
+
render(<Button>Click me</Button>);
|
|
9
|
+
expect(screen.getByRole('button', { name: /click me/i })).toBeInTheDocument();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('handles click events', async () => {
|
|
13
|
+
const handleClick = vi.fn();
|
|
14
|
+
render(<Button onClick={handleClick}>Click me</Button>);
|
|
15
|
+
|
|
16
|
+
await userEvent.click(screen.getByRole('button', { name: /click me/i }));
|
|
17
|
+
expect(handleClick).toHaveBeenCalledTimes(1);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('can be disabled', () => {
|
|
21
|
+
render(<Button disabled>Click me</Button>);
|
|
22
|
+
expect(screen.getByRole('button', { name: /click me/i })).toBeDisabled();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('supports asChild prop', () => {
|
|
26
|
+
render(
|
|
27
|
+
<Button asChild>
|
|
28
|
+
<a href="/test">Link Button</a>
|
|
29
|
+
</Button>,
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const link = screen.getByRole('link', { name: /link button/i });
|
|
33
|
+
expect(link).toBeInTheDocument();
|
|
34
|
+
expect(link).toHaveAttribute('href', '/test');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('Variants', () => {
|
|
38
|
+
const variants = ['default', 'destructive', 'outline', 'secondary', 'ghost', 'link'] as const;
|
|
39
|
+
|
|
40
|
+
variants.forEach((variant) => {
|
|
41
|
+
it(`renders ${variant} variant`, () => {
|
|
42
|
+
render(<Button variant={variant}>{variant}</Button>);
|
|
43
|
+
const button = screen.getByRole('button', { name: variant });
|
|
44
|
+
expect(button).toBeInTheDocument();
|
|
45
|
+
// We could check for specific classes here, but that might make tests too brittle
|
|
46
|
+
// checking the role and content presence is a good baseline
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('Sizes', () => {
|
|
52
|
+
const sizes = ['default', 'sm', 'lg', 'icon'] as const;
|
|
53
|
+
|
|
54
|
+
sizes.forEach((size) => {
|
|
55
|
+
it(`renders ${size} size`, () => {
|
|
56
|
+
render(<Button size={size}>{size}</Button>);
|
|
57
|
+
const button = screen.getByRole('button', { name: size });
|
|
58
|
+
expect(button).toBeInTheDocument();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { Calendar } from './calendar';
|
|
4
|
+
|
|
5
|
+
describe('Calendar', () => {
|
|
6
|
+
it('renders correctly', () => {
|
|
7
|
+
// Mock date to consistent rendering
|
|
8
|
+
const date = new Date(2023, 0, 1); // Jan 1, 2023
|
|
9
|
+
|
|
10
|
+
render(<Calendar mode="single" selected={date} month={date} />);
|
|
11
|
+
|
|
12
|
+
expect(screen.getByText('January 2023')).toBeInTheDocument();
|
|
13
|
+
const days = screen.getAllByText('1');
|
|
14
|
+
expect(days.length).toBeGreaterThan(0);
|
|
15
|
+
expect(screen.getByText('Su')).toBeInTheDocument(); // Sunday header
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('renders with class name', () => {
|
|
19
|
+
const { container } = render(<Calendar className="test-class" />);
|
|
20
|
+
// DayPicker renders a div with the class
|
|
21
|
+
expect(container.firstChild).toHaveClass('test-class');
|
|
22
|
+
});
|
|
23
|
+
});
|