@catalystsoftware/ui 1.0.2 → 1.0.5
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/data/tailwind.config.js +261 -3821
- package/dist/components/catalyst-ui/buttons/burger.tsx +207 -0
- package/dist/components/catalyst-ui/core/data-display/timeline.tsx +210 -0
- package/dist/components/catalyst-ui/core/feedback/alert.tsx +491 -0
- package/dist/components/catalyst-ui/core/feedback/spinner-1.tsx +65 -0
- package/dist/components/catalyst-ui/core/feedback/toast.tsx +1857 -0
- package/dist/components/catalyst-ui/core/navigation/menu.tsx +164 -0
- package/dist/components/catalyst-ui/forms/toggle-class.tsx +176 -0
- package/dist/components/catalyst-ui/hooks/use-copy-to-clipboard.tsx +419 -0
- package/dist/components/catalyst-ui/hooks/use-counter.tsx +13 -0
- package/dist/components/catalyst-ui/hooks/use-event-listener.tsx +23 -0
- package/dist/components/catalyst-ui/hooks/use-export-markdown.tsx +47 -0
- package/dist/components/catalyst-ui/hooks/use-focus.tsx +17 -0
- package/dist/components/catalyst-ui/hooks/use-interval.tsx +23 -0
- package/dist/components/catalyst-ui/hooks/use-is-client.tsx +16 -0
- package/dist/components/catalyst-ui/hooks/use-media-query.tsx +19 -0
- package/dist/components/catalyst-ui/hooks/use-mobile.tsx +19 -0
- package/dist/components/catalyst-ui/hooks/use-resize-observer.tsx +81 -0
- package/dist/components/catalyst-ui/hooks/use-timeout.tsx +21 -0
- package/dist/components/catalyst-ui/hooks/use-timer.tsx +209 -0
- package/dist/components/catalyst-ui/hooks/use-toggle.tsx +12 -0
- package/dist/components/catalyst-ui/media/image.tsx +13 -0
- package/dist/components/catalyst-ui/overlays/dual-sidebar.tsx +4142 -0
- package/dist/components/catalyst-ui/overlays/sidebar-original.tsx +726 -0
- package/dist/components/catalyst-ui/primitives/accordion.tsx +250 -0
- package/dist/components/catalyst-ui/primitives/alert-dialog.tsx +126 -0
- package/dist/components/catalyst-ui/primitives/aspect-ratio.tsx +9 -0
- package/dist/components/catalyst-ui/primitives/avatar.tsx +296 -0
- package/dist/components/catalyst-ui/primitives/badge.tsx +57 -0
- package/dist/components/catalyst-ui/primitives/breadcrumb.tsx +101 -0
- package/dist/components/catalyst-ui/primitives/button.tsx +265 -0
- package/dist/components/catalyst-ui/primitives/calendar-v4.tsx +208 -0
- package/dist/components/catalyst-ui/primitives/calendar.tsx +295 -0
- package/dist/components/catalyst-ui/primitives/card.tsx +618 -0
- package/dist/components/catalyst-ui/primitives/carousel.tsx +238 -0
- package/dist/components/catalyst-ui/primitives/chart.tsx +347 -0
- package/dist/components/catalyst-ui/primitives/checkbox.tsx +225 -0
- package/dist/components/catalyst-ui/primitives/collapsible.tsx +212 -0
- package/dist/components/catalyst-ui/primitives/command.tsx +393 -0
- package/dist/components/catalyst-ui/primitives/context-menu.tsx +236 -0
- package/dist/components/catalyst-ui/primitives/dialog.tsx +471 -0
- package/dist/components/catalyst-ui/primitives/drawer.tsx +761 -0
- package/dist/components/catalyst-ui/primitives/dropdown-menu.tsx +290 -0
- package/dist/components/catalyst-ui/primitives/empty.tsx +104 -0
- package/dist/components/catalyst-ui/primitives/field.tsx +244 -0
- package/dist/components/catalyst-ui/primitives/hover-card.tsx +124 -0
- package/dist/components/catalyst-ui/primitives/input-otp.tsx +76 -0
- package/dist/components/catalyst-ui/primitives/input.tsx +64 -0
- package/dist/components/catalyst-ui/primitives/item.tsx +196 -0
- package/dist/components/catalyst-ui/primitives/kbd.tsx +75 -0
- package/dist/components/catalyst-ui/primitives/label.tsx +24 -0
- package/dist/components/catalyst-ui/primitives/navigation-menu.tsx +150 -0
- package/dist/components/catalyst-ui/primitives/pagination.tsx +198 -0
- package/dist/components/catalyst-ui/primitives/popover.tsx +232 -0
- package/dist/components/catalyst-ui/primitives/progress.tsx +34 -0
- package/dist/components/catalyst-ui/primitives/radio-group.tsx +43 -0
- package/dist/components/catalyst-ui/primitives/resizable.tsx +56 -0
- package/dist/components/catalyst-ui/primitives/select.tsx +155 -0
- package/dist/components/catalyst-ui/primitives/separator.tsx +74 -0
- package/dist/components/catalyst-ui/primitives/sheet.tsx +126 -0
- package/dist/components/catalyst-ui/primitives/skeleton.tsx +15 -0
- package/dist/components/catalyst-ui/primitives/slider.tsx +27 -0
- package/dist/components/catalyst-ui/primitives/switch.tsx +187 -0
- package/dist/components/catalyst-ui/primitives/tabs.tsx +335 -0
- package/dist/components/catalyst-ui/primitives/textarea.tsx +24 -0
- package/dist/components/catalyst-ui/primitives/toggle-group.tsx +55 -0
- package/dist/components/catalyst-ui/primitives/toggle.tsx +42 -0
- package/dist/components/catalyst-ui/primitives/tooltip.tsx +116 -0
- package/dist/components/catalyst-ui/utils/basic-auth.tsx +40 -0
- package/dist/components/catalyst-ui/utils/context-storage.tsx +19 -0
- package/dist/components/catalyst-ui/utils/cors-middleware.tsx +71 -0
- package/dist/components/catalyst-ui/utils/deferred-content.tsx +595 -0
- package/dist/components/catalyst-ui/utils/honeypot-middleware.tsx +38 -0
- package/dist/components/catalyst-ui/utils/incId.tsx +75 -0
- package/dist/components/catalyst-ui/utils/jwk-auth.tsx +36 -0
- package/dist/components/catalyst-ui/utils/request-id.tsx +14 -0
- package/dist/components/catalyst-ui/utils/secure-headers.tsx +37 -0
- package/dist/components/catalyst-ui/utils/server-timing.tsx +23 -0
- package/dist/components/catalyst-ui/utils/utils.ts +43 -0
- package/dist/components/catalyst-ui/utils/with-cookie.tsx +43 -0
- package/dist/components/catalyst-ui/x/accordian-x.tsx +428 -0
- package/dist/components/catalyst-ui/x/alert-x.tsx +413 -0
- package/dist/components/catalyst-ui/x/animated-text-x.tsx +2242 -0
- package/dist/components/catalyst-ui/x/avatar-x.tsx +515 -0
- package/dist/components/catalyst-ui/x/badge-x.tsx +670 -0
- package/dist/components/catalyst-ui/x/button-X.tsx +2857 -0
- package/dist/components/catalyst-ui/x/button-group-x.tsx +847 -0
- package/dist/components/catalyst-ui/x/calendar-x.tsx +1910 -0
- package/dist/components/catalyst-ui/x/card-x.tsx +2597 -0
- package/dist/components/catalyst-ui/x/checkbox-x.tsx +656 -0
- package/dist/components/catalyst-ui/x/collapsible-x.tsx +1360 -0
- package/dist/components/catalyst-ui/x/combobox-x.tsx +911 -0
- package/dist/components/catalyst-ui/x/data-table-x.tsx +1753 -0
- package/dist/components/catalyst-ui/x/date-picker-x.tsx +648 -0
- package/dist/components/catalyst-ui/x/dialog-x.tsx +659 -0
- package/dist/components/catalyst-ui/x/dropdown-menu-x.tsx +612 -0
- package/dist/components/catalyst-ui/x/hover-card-x.tsx +375 -0
- package/dist/components/catalyst-ui/x/icon-x.tsx +840 -0
- package/dist/components/catalyst-ui/x/input-mask-x.tsx +981 -0
- package/dist/components/catalyst-ui/x/input-otp-x.tsx +659 -0
- package/dist/components/catalyst-ui/x/loader-x.tsx +1757 -0
- package/dist/components/catalyst-ui/x/pagination-x.tsx +622 -0
- package/dist/components/catalyst-ui/x/popover-x.tsx +744 -0
- package/dist/components/catalyst-ui/x/radio-group-x.tsx +499 -0
- package/dist/components/catalyst-ui/x/select-x.tsx +1127 -0
- package/dist/components/catalyst-ui/x/sheet-x.tsx +668 -0
- package/dist/components/catalyst-ui/x/switch-x.tsx +681 -0
- package/dist/components/catalyst-ui/x/table-x.tsx +574 -0
- package/dist/components/catalyst-ui/x/tabs-x.tsx +839 -0
- package/dist/components/catalyst-ui/x/textarea-x.tsx +1263 -0
- package/dist/components/catalyst-ui/x/tooltip-x.tsx +396 -0
- package/dist/components/catalyst-ui/x/tracker-x.tsx +560 -0
- package/dist/data/bg-data.tsx +901 -0
- package/dist/data/buttons-data.tsx +2327 -0
- package/dist/data/charts-data.tsx +102 -0
- package/dist/data/chat-data.tsx +83 -0
- package/dist/data/code-data.tsx +1040 -0
- package/dist/data/comboboxes-data.tsx +1843 -0
- package/dist/data/command-data.tsx +1381 -0
- package/dist/data/core-data.tsx +15953 -0
- package/dist/data/crm-data.tsx +47 -0
- package/dist/data/data.tsx +159 -0
- package/dist/data/date-and-time-data.tsx +554 -0
- package/dist/data/dependencies.tsx +7 -0
- package/dist/data/ecommerce-data.tsx +1387 -0
- package/dist/data/forms-data.tsx +7890 -0
- package/dist/data/hooks-data.tsx +5487 -0
- package/dist/data/index.ts +34 -0
- package/dist/data/inputs-data.tsx +557 -0
- package/dist/data/interactive-data.tsx +5394 -0
- package/dist/data/lofi-data.tsx +18295 -0
- package/dist/data/marketing-data.tsx +2546 -0
- package/dist/data/media-data.tsx +1510 -0
- package/dist/data/motion-data.tsx +5801 -0
- package/dist/data/overlay-data.tsx +4136 -0
- package/dist/data/pdf-data.tsx +124 -0
- package/dist/data/pos-data.tsx +213 -0
- package/dist/data/postcss.config.js +6 -0
- package/dist/data/primitive-data.tsx +5170 -0
- package/dist/data/prompt-data.tsx +1226 -0
- package/dist/data/requiredLibs.ts +4 -0
- package/dist/data/sandbox-data.tsx +1 -0
- package/dist/data/sidebars-data.tsx +5421 -0
- package/dist/data/stacks-data.tsx +32 -0
- package/dist/data/table-data.tsx +706 -0
- package/dist/data/tailwind.config.js +270 -0
- package/dist/data/tailwind.config.ngin.js +3830 -0
- package/dist/data/tailwind.css +431 -0
- package/dist/data/tools-data.tsx +6910 -0
- package/dist/data/typography-data.tsx +2050 -0
- package/dist/data/utils-data.tsx +6500 -0
- package/dist/data/x-data.tsx +1171 -0
- package/dist/data.tsx +159 -0
- package/package.json +1 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -362
|
@@ -0,0 +1,4142 @@
|
|
|
1
|
+
import React, { createContext, useCallback, useContext, useEffect, useState, forwardRef } from "react";
|
|
2
|
+
import { type VariantProps, cva } from "class-variance-authority";
|
|
3
|
+
import { useIsMobile } from "~/modules/hooks/use-mobile";
|
|
4
|
+
import { cn, Loader } from "~/components/catalyst-ui";
|
|
5
|
+
import { Button, Drawer, TooltipProvider, Tooltip, TooltipContent, TooltipTrigger, Input, Skeleton, Separator, Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Dialog, DialogContent, DialogDescription, DialogTitle, DialogTrigger, LoaderX, } from "~/components/catalyst-ui";
|
|
6
|
+
import { useNavigation, NavLink, useLocation } from "@remix-run/react";
|
|
7
|
+
import { Drawer as DrawerPrimitive } from "vaul";
|
|
8
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
9
|
+
import * as AvatarPrimitive from '@radix-ui/react-avatar'
|
|
10
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
11
|
+
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
|
|
12
|
+
import { Bell, Bot, Globe, Home, Keyboard, Link, Lock, Menu, MessageCircle, Paintbrush, Settings, Video, } from "lucide-react";
|
|
13
|
+
import { Circle, Check, ChevronRight } from "@catalystsoftware/icons";
|
|
14
|
+
import { Sidebar, SidebarContent, SidebarGroup, SidebarGroupContent, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarProvider, } from "~/components/catalyst-ui";
|
|
15
|
+
import { motion } from "motion/react";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ DualSidebar System ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
19
|
+
* ★ ━━━━ ☆ ━━━━ ━━━━ ☆ ━━━━ ★
|
|
20
|
+
* type SidebarVariant = 'sidebar' | 'inset' | 'floating' | 'frosted' | 'card' | 'glass' | 'compact-card' | 'bordered' | 'minimal' | 'elevated'
|
|
21
|
+
* type SidebarSide = 'left' | 'right'
|
|
22
|
+
* type SidebarCollapsible = 'offcanvas' | 'icon' | 'none'
|
|
23
|
+
* type DSTheme = 'neutral' | 'red' | 'orange' | 'green' | 'blue' | 'violet' | 'default'
|
|
24
|
+
*
|
|
25
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━ Basic Setup ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
26
|
+
* ```jsx
|
|
27
|
+
* // App.tsx or root component
|
|
28
|
+
* <DSProvider>
|
|
29
|
+
* <DSLeft variant="sidebar">
|
|
30
|
+
* <DSHeader>Left Sidebar</DSHeader>
|
|
31
|
+
* <DSContent>
|
|
32
|
+
* <DSMenu>
|
|
33
|
+
* <DSMenuLink to="/dashboard" icon={<Home />}>Dashboard</DSMenuLink>
|
|
34
|
+
* <DSMenuLink to="/profile" icon={<User />}>Profile</DSMenuLink>
|
|
35
|
+
* </DSMenu>
|
|
36
|
+
* </DSContent>
|
|
37
|
+
* </DSLeft>
|
|
38
|
+
*
|
|
39
|
+
* <DSRight variant="floating">
|
|
40
|
+
* <DSHeader>Right Sidebar</DSHeader>
|
|
41
|
+
* <DSContent>Right content</DSContent>
|
|
42
|
+
* </DSRight>
|
|
43
|
+
*
|
|
44
|
+
* <DSInset>
|
|
45
|
+
* <main>Main content here</main>
|
|
46
|
+
* </DSInset>
|
|
47
|
+
* </DSProvider>
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━ With Icon Sidebars ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
51
|
+
* ```jsx
|
|
52
|
+
* <DSProvider>
|
|
53
|
+
* <DSLeftIcon iconWidth="48px">
|
|
54
|
+
* <DSContent>
|
|
55
|
+
* <DSMenu>
|
|
56
|
+
* <DSMenuButton tooltip="Dashboard"><Home /></DSMenuButton>
|
|
57
|
+
* <DSMenuButton tooltip="Profile"><User /></DSMenuButton>
|
|
58
|
+
* </DSMenu>
|
|
59
|
+
* </DSContent>
|
|
60
|
+
* </DSLeftIcon>
|
|
61
|
+
*
|
|
62
|
+
* <DSLeft variant="sidebar">
|
|
63
|
+
* <DSHeader>Full Sidebar</DSHeader>
|
|
64
|
+
* <DSContent>Expanded content</DSContent>
|
|
65
|
+
* </DSLeft>
|
|
66
|
+
*
|
|
67
|
+
* <DSInset>
|
|
68
|
+
* Main content area
|
|
69
|
+
* </DSInset>
|
|
70
|
+
* </DSProvider>
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━ Variant Examples ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
74
|
+
* ```jsx
|
|
75
|
+
* // Inset variant
|
|
76
|
+
* <DSLeft variant="inset">
|
|
77
|
+
* <DSHeader>Inset Sidebar</DSHeader>
|
|
78
|
+
* <DSContent>Rounded sidebar with padding</DSContent>
|
|
79
|
+
* </DSLeft>
|
|
80
|
+
*
|
|
81
|
+
* // Floating variant
|
|
82
|
+
* <DSRight variant="floating">
|
|
83
|
+
* <DSHeader>Floating Sidebar</DSHeader>
|
|
84
|
+
* <DSContent>Rounded with shadow</DSContent>
|
|
85
|
+
* </DSRight>
|
|
86
|
+
*
|
|
87
|
+
* // Frosted glass variant
|
|
88
|
+
* <DSLeft variant="frosted">
|
|
89
|
+
* <DSHeader>Glass Sidebar</DSHeader>
|
|
90
|
+
* <DSContent>Backdrop blur effect</DSContent>
|
|
91
|
+
* </DSLeft>
|
|
92
|
+
*
|
|
93
|
+
* // Card variant
|
|
94
|
+
* <DSRight variant="card">
|
|
95
|
+
* <DSHeader>Card Sidebar</DSHeader>
|
|
96
|
+
* <DSContent>Card-like appearance</DSContent>
|
|
97
|
+
* </DSRight>
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━ Menu Components ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
101
|
+
* ```jsx
|
|
102
|
+
* <DSMenu>
|
|
103
|
+
* // Regular menu button
|
|
104
|
+
* <DSMenuButton variant="default" icon={<Home />}>
|
|
105
|
+
* Dashboard
|
|
106
|
+
* </DSMenuButton>
|
|
107
|
+
*
|
|
108
|
+
* // Active menu button
|
|
109
|
+
* <DSMenuButton isActive variant="solid" icon={<Settings />}>
|
|
110
|
+
* Settings
|
|
111
|
+
* </DSMenuButton>
|
|
112
|
+
*
|
|
113
|
+
* // With badge
|
|
114
|
+
* <DSMenuButton icon={<Bell />}>
|
|
115
|
+
* Notifications
|
|
116
|
+
* <DSMenuBadge variant="primary">5</DSMenuBadge>
|
|
117
|
+
* </DSMenuButton>
|
|
118
|
+
*
|
|
119
|
+
* // Navigation link with loading state
|
|
120
|
+
* <DSMenuLink to="/dashboard" icon={<Home />}>
|
|
121
|
+
* Dashboard
|
|
122
|
+
* </DSMenuLink>
|
|
123
|
+
*
|
|
124
|
+
* // External link
|
|
125
|
+
* <DSMenuAnchor to="https://example.com" icon={<ExternalLink />}>
|
|
126
|
+
* External
|
|
127
|
+
* </DSMenuAnchor>
|
|
128
|
+
*
|
|
129
|
+
* // With submenu
|
|
130
|
+
* <DSMenuItem>
|
|
131
|
+
* <DSMenuButton icon={<Folder />}>Documents</DSMenuButton>
|
|
132
|
+
* <DSMenuSub>
|
|
133
|
+
* <DSMenuSubButton>Resume.pdf</DSMenuSubButton>
|
|
134
|
+
* <DSMenuSubButton>Projects.zip</DSMenuSubButton>
|
|
135
|
+
* </DSMenuSub>
|
|
136
|
+
* </DSMenuItem>
|
|
137
|
+
* </DSMenu>
|
|
138
|
+
* ```
|
|
139
|
+
*
|
|
140
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━ Group Components ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
141
|
+
* ```jsx
|
|
142
|
+
* <DSGroup variant="card">
|
|
143
|
+
* <DSGroupLabel variant="prominent">Account</DSGroupLabel>
|
|
144
|
+
* <DSGroupContent>
|
|
145
|
+
* <DSMenuLink to="/profile" icon={<User />}>Profile</DSMenuLink>
|
|
146
|
+
* <DSMenuLink to="/settings" icon={<Settings />}>Settings</DSMenuLink>
|
|
147
|
+
* </DSGroupContent>
|
|
148
|
+
* </DSGroup>
|
|
149
|
+
*
|
|
150
|
+
* <DSGroup variant="separated">
|
|
151
|
+
* <DSGroupLabel>Navigation</DSGroupLabel>
|
|
152
|
+
* <DSGroupContent>
|
|
153
|
+
* <DSMenuLink to="/dashboard" icon={<Home />}>Dashboard</DSMenuLink>
|
|
154
|
+
* <DSMenuLink to="/analytics" icon={<Chart />}>Analytics</DSMenuLink>
|
|
155
|
+
* </DSGroupContent>
|
|
156
|
+
* </DSGroup>
|
|
157
|
+
* ```
|
|
158
|
+
*
|
|
159
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━ Theme System ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
160
|
+
* ```jsx
|
|
161
|
+
* // Using the theme selector
|
|
162
|
+
* <DSThemeSelector size={28}>
|
|
163
|
+
* <Paintbrush className="size-4" />
|
|
164
|
+
* </DSThemeSelector>
|
|
165
|
+
*
|
|
166
|
+
* // Programmatic theme control
|
|
167
|
+
* const { theme, setTheme } = useDSTheme()
|
|
168
|
+
*
|
|
169
|
+
* // Changing theme
|
|
170
|
+
* <button onClick={() => setTheme('blue')}>
|
|
171
|
+
* Switch to Blue Theme
|
|
172
|
+
* </button>
|
|
173
|
+
* ```
|
|
174
|
+
*
|
|
175
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━ Drawer Components ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
176
|
+
* ```jsx
|
|
177
|
+
* // Top drawer
|
|
178
|
+
* <DSD drawerHeight="300px" variant="card">
|
|
179
|
+
* <DSTrigger>Open Drawer</DSTrigger>
|
|
180
|
+
* <DSDContent>
|
|
181
|
+
* <DSDHeader>
|
|
182
|
+
* <DSDTitle>Notifications</DSDTitle>
|
|
183
|
+
* <DSDDescription>You have 5 new notifications</DSDDescription>
|
|
184
|
+
* </DSDHeader>
|
|
185
|
+
* <div className="p-4">Drawer content</div>
|
|
186
|
+
* <DSDFooter>
|
|
187
|
+
* <Button>Close</Button>
|
|
188
|
+
* </DSDFooter>
|
|
189
|
+
* </DSDContent>
|
|
190
|
+
* </DSD>
|
|
191
|
+
*
|
|
192
|
+
* // Side drawer variants
|
|
193
|
+
* <DSD direction="right" variant="glass">
|
|
194
|
+
* <DSTrigger>Open Side Drawer</DSTrigger>
|
|
195
|
+
* <DSDContent>
|
|
196
|
+
* <DSDHeader>Side Panel</DSDHeader>
|
|
197
|
+
* <div className="p-4">Side content</div>
|
|
198
|
+
* </DSDContent>
|
|
199
|
+
* </DSD>
|
|
200
|
+
* ```
|
|
201
|
+
*
|
|
202
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━ Dropdown Menu ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
203
|
+
* ```jsx
|
|
204
|
+
* <DSDM>
|
|
205
|
+
* <DSDMTrigger asChild>
|
|
206
|
+
* <Button variant="ghost">Open Menu</Button>
|
|
207
|
+
* </DSDMTrigger>
|
|
208
|
+
* <DSDMContent>
|
|
209
|
+
* <DSDMGroup>
|
|
210
|
+
* <DSDMItem>
|
|
211
|
+
* <User className="mr-2" /> Profile
|
|
212
|
+
* </DSDMItem>
|
|
213
|
+
* <DSDMItem>
|
|
214
|
+
* <Settings className="mr-2" /> Settings
|
|
215
|
+
* </DSDMItem>
|
|
216
|
+
* </DSDMGroup>
|
|
217
|
+
* <DSDMSeparator />
|
|
218
|
+
* <DSDMItem variant="destructive">
|
|
219
|
+
* <LogOut className="mr-2" /> Logout
|
|
220
|
+
* </DSDMItem>
|
|
221
|
+
* </DSDMContent>
|
|
222
|
+
* </DSDM>
|
|
223
|
+
* ```
|
|
224
|
+
*
|
|
225
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━ Collapsible Sections ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
226
|
+
* ```jsx
|
|
227
|
+
* <DSC>
|
|
228
|
+
* <DSCTrigger asChild>
|
|
229
|
+
* <DSMenuButton icon={<ChevronRight />}>Settings</DSMenuButton>
|
|
230
|
+
* </DSCTrigger>
|
|
231
|
+
* <DSCContent>
|
|
232
|
+
* <DSMenuSub>
|
|
233
|
+
* <DSMenuSubButton>Appearance</DSMenuSubButton>
|
|
234
|
+
* <DSMenuSubButton>Notifications</DSMenuSubButton>
|
|
235
|
+
* <DSMenuSubButton>Privacy</DSMenuSubButton>
|
|
236
|
+
* </DSMenuSub>
|
|
237
|
+
* </DSCContent>
|
|
238
|
+
* </DSC>
|
|
239
|
+
* ```
|
|
240
|
+
*
|
|
241
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━ Props Reference ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
242
|
+
* - DSProvider Props:
|
|
243
|
+
* - `defaultOpenLeft`: boolean - Default left sidebar open state
|
|
244
|
+
* - `defaultOpenRight`: boolean - Default right sidebar open state
|
|
245
|
+
* - `defaultWidth`: string - Default sidebar width (default: "275px")
|
|
246
|
+
*
|
|
247
|
+
* - DSLeft/DSRight Props:
|
|
248
|
+
* - `variant`: SidebarVariant - Visual style of sidebar
|
|
249
|
+
* - `collapsible`: SidebarCollapsible - Collapse behavior
|
|
250
|
+
* - `loadingUI`: boolean - Show loading skeleton (default: true)
|
|
251
|
+
*
|
|
252
|
+
* - DSLeftIcon/DSRightIcon Props:
|
|
253
|
+
* - `iconWidth`: string - Width of icon sidebar (default: "48px")
|
|
254
|
+
* - `variant`: SidebarVariant - Visual style
|
|
255
|
+
*
|
|
256
|
+
* - DSInset Props:
|
|
257
|
+
* - `variant`: 'default' | 'inset' | 'card' | 'bordered' - Main content area style
|
|
258
|
+
*
|
|
259
|
+
* - DSMenuButton Props:
|
|
260
|
+
* - `variant`: 'default' | 'ghost' | 'outline' | 'soft' | 'solid' | 'minimal' | 'bordered' | 'pill'
|
|
261
|
+
* - `size`: 'default' | 'sm' | 'lg' | 'icon'
|
|
262
|
+
* - `isActive`: boolean - Active state styling
|
|
263
|
+
* - `tooltip`: string | TooltipContentProps - Tooltip content
|
|
264
|
+
* - `icon`: ReactNode - Icon element
|
|
265
|
+
*
|
|
266
|
+
* - DSMenuLink/DSMenuAnchor Props:
|
|
267
|
+
* - `to`: string - Navigation path or URL
|
|
268
|
+
* - `variant`: Menu button variant
|
|
269
|
+
* - `size`: Menu button size
|
|
270
|
+
* - `icon`: ReactNode - Icon element
|
|
271
|
+
* - `tooltip`: string - Tooltip text
|
|
272
|
+
* - `newTab`: boolean - Open in new tab (DSMenuAnchor only)
|
|
273
|
+
*
|
|
274
|
+
* - DSGroup Props:
|
|
275
|
+
* - `variant`: 'default' | 'separated' | 'card' | 'bordered' | 'subtle'
|
|
276
|
+
*
|
|
277
|
+
* - DSGroupLabel Props:
|
|
278
|
+
* - `variant`: 'default' | 'prominent' | 'subtle' | 'separated'
|
|
279
|
+
* - `asChild`: boolean - Merge with child element
|
|
280
|
+
*
|
|
281
|
+
* - DSD (Drawer) Props:
|
|
282
|
+
* - `drawerHeight`: string - Height when open
|
|
283
|
+
* - `variant`: 'default' | 'card' | 'glass' | 'elevated' | 'bordered' | 'macos'
|
|
284
|
+
* - `direction`: 'top' | 'bottom' | 'right' | 'left'
|
|
285
|
+
* - `size`: 'default' | 'sm' | 'md' | 'lg' | 'full'
|
|
286
|
+
*
|
|
287
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━ Hooks & Context ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
288
|
+
* ```typescript
|
|
289
|
+
* // Use sidebar state and controls
|
|
290
|
+
* const {
|
|
291
|
+
* leftState, // 'expanded' | 'collapsed'
|
|
292
|
+
* rightState, // 'expanded' | 'collapsed'
|
|
293
|
+
* toggleLeft, // () => void
|
|
294
|
+
* toggleRight, // () => void
|
|
295
|
+
* openLeft, // boolean
|
|
296
|
+
* openRight, // boolean
|
|
297
|
+
* setOpenLeft, // (open: boolean) => void
|
|
298
|
+
* setOpenRight, // (open: boolean) => void
|
|
299
|
+
* isMobile, // boolean
|
|
300
|
+
* sidebarWidth, // number
|
|
301
|
+
* leftVariant, // SidebarVariant
|
|
302
|
+
* rightVariant, // SidebarVariant
|
|
303
|
+
* setLeftVariant, // (variant: SidebarVariant) => void
|
|
304
|
+
* setRightVariant, // (variant: SidebarVariant) => void
|
|
305
|
+
* } = useDS()
|
|
306
|
+
*
|
|
307
|
+
* // Use theme controls
|
|
308
|
+
* const {
|
|
309
|
+
* theme, // DSTheme
|
|
310
|
+
* setTheme, // (theme: DSTheme) => void
|
|
311
|
+
* themeVars, // Record<string, string>
|
|
312
|
+
* } = useDSTheme()
|
|
313
|
+
* ```
|
|
314
|
+
*
|
|
315
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━ Keyboard Shortcuts ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
316
|
+
* - **Cmd/Ctrl + B**: Toggle left sidebar
|
|
317
|
+
* - **Cmd/Ctrl + G**: Toggle right sidebar
|
|
318
|
+
* - **Mobile**: Swipe gestures supported
|
|
319
|
+
* - **Accessibility**: Full keyboard navigation and ARIA labels
|
|
320
|
+
*
|
|
321
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━ Responsive Behavior ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
322
|
+
* - **Desktop**: Sidebars can be expanded/collapsed with icon mode
|
|
323
|
+
* - **Tablet**: Adaptive layouts with optimized spacing
|
|
324
|
+
* - **Mobile**: Sidebars become offcanvas drawers with swipe support
|
|
325
|
+
* - **Auto-adjust**: Content area automatically resizes based on sidebar states
|
|
326
|
+
*
|
|
327
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━ Theming System ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
328
|
+
* ```typescript
|
|
329
|
+
* // Available themes
|
|
330
|
+
* const themes = [
|
|
331
|
+
* 'neutral', // Default neutral colors
|
|
332
|
+
* 'red', // Red accent theme
|
|
333
|
+
* 'orange', // Orange accent theme
|
|
334
|
+
* 'green', // Green accent theme
|
|
335
|
+
* 'blue', // Blue accent theme (default)
|
|
336
|
+
* 'violet', // Purple accent theme
|
|
337
|
+
* 'default' // System default
|
|
338
|
+
* ]
|
|
339
|
+
*
|
|
340
|
+
* // Theme persistence
|
|
341
|
+
* // - Automatically saved to localStorage
|
|
342
|
+
* // - Survives page refreshes
|
|
343
|
+
* // - CSS custom properties updated in real-time
|
|
344
|
+
* ```
|
|
345
|
+
*
|
|
346
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━ Loading States ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
347
|
+
* ```jsx
|
|
348
|
+
* // Show loading skeleton during navigation
|
|
349
|
+
* <DSLeft loadingUI={true}>
|
|
350
|
+
* <DSContent>
|
|
351
|
+
* <DSMenuSkeleton showIcon />
|
|
352
|
+
* <DSMenuSkeleton showIcon />
|
|
353
|
+
* <DSMenuSkeleton />
|
|
354
|
+
* </DSContent>
|
|
355
|
+
* </DSLeft>
|
|
356
|
+
*
|
|
357
|
+
* // Or use the standalone loader
|
|
358
|
+
* <DSLoading variant="card" size="md" />
|
|
359
|
+
* ```
|
|
360
|
+
*
|
|
361
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━ Example: Complete Layout ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
362
|
+
* ```jsx
|
|
363
|
+
* <DSProvider defaultOpenLeft={true} defaultWidth="280px">
|
|
364
|
+
* <DSLeftIcon>
|
|
365
|
+
* <DSContent>
|
|
366
|
+
* <DSMenu>
|
|
367
|
+
* <DSMenuButton tooltip="Dashboard"><Home /></DSMenuButton>
|
|
368
|
+
* <DSMenuButton tooltip="Messages"><MessageCircle /></DSMenuButton>
|
|
369
|
+
* <DSMenuButton tooltip="Settings"><Settings /></DSMenuButton>
|
|
370
|
+
* </DSMenu>
|
|
371
|
+
* </DSContent>
|
|
372
|
+
* </DSLeftIcon>
|
|
373
|
+
*
|
|
374
|
+
* <DSLeft variant="frosted" collapsible="offcanvas">
|
|
375
|
+
* <DSHeader>
|
|
376
|
+
* <div className="flex items-center gap-3">
|
|
377
|
+
* <Avatar>
|
|
378
|
+
* <AvatarImage src="/avatar.jpg" />
|
|
379
|
+
* <AvatarFallback>JD</AvatarFallback>
|
|
380
|
+
* </Avatar>
|
|
381
|
+
* <div>
|
|
382
|
+
* <h3 className="font-semibold">John Doe</h3>
|
|
383
|
+
* <p className="text-sm text-muted-foreground">Admin</p>
|
|
384
|
+
* </div>
|
|
385
|
+
* </div>
|
|
386
|
+
* </DSHeader>
|
|
387
|
+
*
|
|
388
|
+
* <DSContent>
|
|
389
|
+
* <DSGroup variant="card">
|
|
390
|
+
* <DSGroupLabel>Navigation</DSGroupLabel>
|
|
391
|
+
* <DSMenu>
|
|
392
|
+
* <DSMenuLink to="/dashboard" icon={<Home />}>Dashboard</DSMenuLink>
|
|
393
|
+
* <DSMenuLink to="/analytics" icon={<ChartBar />}>Analytics</DSMenuLink>
|
|
394
|
+
* <DSMenuLink to="/users" icon={<Users />}>Users</DSMenuLink>
|
|
395
|
+
* </DSMenu>
|
|
396
|
+
* </DSGroup>
|
|
397
|
+
*
|
|
398
|
+
* <DSGroup variant="separated">
|
|
399
|
+
* <DSGroupLabel>Settings</DSGroupLabel>
|
|
400
|
+
* <DSMenu>
|
|
401
|
+
* <DSMenuLink to="/settings" icon={<Settings />}>General</DSMenuLink>
|
|
402
|
+
* <DSMenuLink to="/notifications" icon={<Bell />}>
|
|
403
|
+
* Notifications
|
|
404
|
+
* <DSMenuBadge variant="primary">3</DSMenuBadge>
|
|
405
|
+
* </DSMenuLink>
|
|
406
|
+
* </DSMenu>
|
|
407
|
+
* </DSGroup>
|
|
408
|
+
* </DSContent>
|
|
409
|
+
*
|
|
410
|
+
* <DSFooter>
|
|
411
|
+
* <div className="flex items-center justify-between">
|
|
412
|
+
* <DSThemeSelector size={24}>
|
|
413
|
+
* <Paintbrush className="size-3" />
|
|
414
|
+
* </DSThemeSelector>
|
|
415
|
+
* <Button variant="ghost" size="icon">
|
|
416
|
+
* <LogOut className="size-4" />
|
|
417
|
+
* </Button>
|
|
418
|
+
* </div>
|
|
419
|
+
* </DSFooter>
|
|
420
|
+
* </DSLeft>
|
|
421
|
+
*
|
|
422
|
+
* <DSRight variant="floating">
|
|
423
|
+
* <DSHeader>
|
|
424
|
+
* <h3 className="font-semibold">Quick Actions</h3>
|
|
425
|
+
* </DSHeader>
|
|
426
|
+
* <DSContent>
|
|
427
|
+
* <div className="p-4">Right panel content</div>
|
|
428
|
+
* </DSContent>
|
|
429
|
+
* </DSRight>
|
|
430
|
+
*
|
|
431
|
+
* <DSInset variant="inset">
|
|
432
|
+
* <div className="p-6">
|
|
433
|
+
* <h1 className="text-3xl font-bold">Dashboard</h1>
|
|
434
|
+
* <p className="mt-2 text-muted-foreground">Welcome to your workspace</p>
|
|
435
|
+
* </div>
|
|
436
|
+
* </DSInset>
|
|
437
|
+
*
|
|
438
|
+
* <DSD drawerHeight="400px" variant="macos">
|
|
439
|
+
* <DSDContent>
|
|
440
|
+
* <DSDHeader>
|
|
441
|
+
* <DSDTitle>Notifications</DSDTitle>
|
|
442
|
+
* </DSDHeader>
|
|
443
|
+
* <div className="p-4">Notification list</div>
|
|
444
|
+
* </DSDContent>
|
|
445
|
+
* </DSD>
|
|
446
|
+
* </DSProvider>
|
|
447
|
+
* ```
|
|
448
|
+
*
|
|
449
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━ Advanced Features ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
450
|
+
* 1. **Dual Sidebar Support**: Independent left and right sidebars
|
|
451
|
+
* 2. **Icon Mode**: Persistent icon-only sidebars
|
|
452
|
+
* 3. **Multiple Variants**: 10+ visual styles for sidebars
|
|
453
|
+
* 4. **Theme System**: 7 built-in color themes with persistence
|
|
454
|
+
* 5. **Responsive Design**: Mobile-optimized offcanvas drawers
|
|
455
|
+
* 6. **Loading States**: Built-in skeleton loaders
|
|
456
|
+
* 7. **Keyboard Navigation**: Full accessibility support
|
|
457
|
+
* 8. **Drawer System**: Slide-in panels from any direction
|
|
458
|
+
* 9. **Dropdown Menus**: Rich context menus
|
|
459
|
+
* 10. **Collapsible Sections**: Expandable/collapsible content areas
|
|
460
|
+
*
|
|
461
|
+
* ★ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━ Performance Notes ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ☆ ━━━━━━━━━━━━━━ ★
|
|
462
|
+
* - **Lazy Loading**: Components load only when needed
|
|
463
|
+
* - **CSS Variables**: Efficient theming with CSS custom properties
|
|
464
|
+
* - **Memoization**: Heavy use of React.memo and useMemo
|
|
465
|
+
* - **Bundle Splitting**: Code-split for better performance
|
|
466
|
+
* - **Optimized Renders**: Minimal re-renders with context optimization
|
|
467
|
+
*
|
|
468
|
+
*/
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
const DS_COOKIE_NAME = "ds_state";
|
|
472
|
+
const DS_COOKIE_NAME_RIGHT = "ds_state_right";
|
|
473
|
+
const DS_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
|
|
474
|
+
const DS_WIDTH = "275px";
|
|
475
|
+
const DS_WIDTH_MOBILE = "288px";
|
|
476
|
+
const DS_WIDTH_ICON = "48px";
|
|
477
|
+
const DS_KEYBOARD_SHORTCUT_LEFT = "b";
|
|
478
|
+
const DS_KEYBOARD_SHORTCUT_RIGHT = "g";
|
|
479
|
+
|
|
480
|
+
const THEME_VERSION = "v3";
|
|
481
|
+
const THEME_OPTIONS = ["neutral", "red", "orange", "green", "blue", "violet", "default"] as const;
|
|
482
|
+
const LOCAL_DS_STORAGE_KEY = "ds-theme-v3";
|
|
483
|
+
|
|
484
|
+
type DSTheme = (typeof THEME_OPTIONS)[number];
|
|
485
|
+
|
|
486
|
+
type SidebarVariant = "sidebar" | "inset" | "floating" | "frosted" | "floating-card" | "glass" | "compact-card" | "minimal" | "bordered" | "elevated";
|
|
487
|
+
type SidebarSide = 'left' | 'right'
|
|
488
|
+
type SidebarCollapsible = 'offcanvas' | 'icon' | 'none'
|
|
489
|
+
const dsVariants = cva('', {
|
|
490
|
+
variants: {
|
|
491
|
+
variant: {
|
|
492
|
+
sidebar: 'fixed inset-y-0 z-20 bg-sidebar flex flex-col transition-transform duration-300 h-full',
|
|
493
|
+
inset: 'fixed inset-y-0 z-20 bg-sidebar rounded-[15px] p-[15px] flex flex-col transition-transform duration-300 shadow-2xl h-full',
|
|
494
|
+
floating: 'fixed inset-y-0 z-20 bg-sidebar rounded-[15px] flex flex-col transition-transform duration-300 shadow-2xl h-full',
|
|
495
|
+
frosted: 'fixed inset-y-0 z-20 backdrop-blur-2xl bg-background/80 border border-white/10 shadow-xl flex flex-col transition-transform duration-300 h-full',
|
|
496
|
+
card: 'fixed z-20 bg-sidebar rounded-xl shadow-2xl flex flex-col transition-all duration-300 my-[5vh] max-h-[90vh] overflow-auto h-full',
|
|
497
|
+
glass: 'fixed inset-y-0 z-20 backdrop-blur-xl bg-white/10 border border-white/20 shadow-lg flex flex-col transition-transform duration-300 h-full',
|
|
498
|
+
'compact-card': 'fixed z-20 bg-sidebar rounded-lg shadow-lg flex flex-col transition-all duration-300 my-2 max-h-[95vh] overflow-auto',
|
|
499
|
+
bordered: 'fixed inset-y-0 z-20 bg-sidebar border-2 border-primary/20 rounded-lg shadow-sm flex flex-col transition-transform duration-300 h-full',
|
|
500
|
+
minimal: 'fixed inset-y-0 z-20 bg-sidebar flex flex-col transition-transform duration-300 h-full',
|
|
501
|
+
elevated: 'fixed inset-y-0 z-20 bg-sidebar shadow-2xl rounded-2xl border border-border/50 flex flex-col transition-transform duration-300 h-full',
|
|
502
|
+
},
|
|
503
|
+
},
|
|
504
|
+
defaultVariants: {
|
|
505
|
+
variant: 'sidebar',
|
|
506
|
+
},
|
|
507
|
+
})
|
|
508
|
+
const iconDSVariants = cva('fixed inset-y-0 z-20 hidden h-svh flex-col md:flex', {
|
|
509
|
+
variants: {
|
|
510
|
+
variant: {
|
|
511
|
+
sidebar: 'bg-background',
|
|
512
|
+
inset: 'bg-sidebar',
|
|
513
|
+
floating: 'bg-sidebar m-2 rounded-lg max-h-[calc(100vh-16px)]',
|
|
514
|
+
frosted: 'backdrop-blur-xl bg-background/70',
|
|
515
|
+
card: 'bg-sidebar rounded-lg my-[5vh] max-h-[90vh]',
|
|
516
|
+
glass: 'backdrop-blur-lg bg-white/5',
|
|
517
|
+
'compact-card': 'bg-sidebar rounded-md my-2 max-h-[95vh]',
|
|
518
|
+
bordered: 'bg-sidebar border-2 border-primary/10',
|
|
519
|
+
minimal: 'bg-background',
|
|
520
|
+
elevated: 'bg-sidebar shadow-xl rounded-lg border border-border/30',
|
|
521
|
+
},
|
|
522
|
+
side: {
|
|
523
|
+
left: 'left-0 border-r border-border',
|
|
524
|
+
right: 'right-0 border-l border-border',
|
|
525
|
+
},
|
|
526
|
+
},
|
|
527
|
+
defaultVariants: {
|
|
528
|
+
variant: 'sidebar',
|
|
529
|
+
side: 'left',
|
|
530
|
+
},
|
|
531
|
+
});
|
|
532
|
+
const DSMenuButtonVariants = cva(
|
|
533
|
+
"peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-none transition-all duration-200 disabled:pointer-events-none disabled:opacity-50 group-has-[[data-dual-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0", // ring-sidebar-ring
|
|
534
|
+
{
|
|
535
|
+
variants: {
|
|
536
|
+
variant: {
|
|
537
|
+
default: [
|
|
538
|
+
"data-[active=true]:text-sidebar-accent-foreground",
|
|
539
|
+
"text-sidebar-muted-foreground hover:text-sidebar-foreground border-l-2 border-transparent duration-300 hover:border-primary" // hover:text-primary
|
|
540
|
+
],
|
|
541
|
+
ghost: "hover:bg-sidebar-accent/50 hover:text-sidebar-accent-foreground data-[active=true]:bg-sidebar-accent/70",
|
|
542
|
+
outline: "bg-transparent border border-sidebar-border hover:bg-sidebar-accent hover:border-sidebar-accent data-[active=true]:bg-sidebar-accent data-[active=true]:border-sidebar-accent data-[active=true]:text-foreground",
|
|
543
|
+
soft: "hover:bg-sidebar-accent/30 hover:text-sidebar-accent-foreground data-[active=true]:bg-sidebar-accent/50",
|
|
544
|
+
solid: "bg-sidebar-accent/10 hover:bg-sidebar-accent data-[active=true]:bg-primary data-[active=true]:text-primary-foreground",
|
|
545
|
+
minimal: "hover:text-primary data-[active=true]:text-primary data-[active=true]:font-semibold",
|
|
546
|
+
bordered: "border-l-2 border-transparent hover:border-sidebar-accent hover:bg-sidebar-accent/20 data-[active=true]:border-primary data-[active=true]:bg-sidebar-accent",
|
|
547
|
+
pill: "rounded-full hover:bg-sidebar-accent data-[active=true]:bg-primary data-[active=true]:text-primary-foreground",
|
|
548
|
+
},
|
|
549
|
+
size: {
|
|
550
|
+
default: "h-9 text-sm px-3",
|
|
551
|
+
sm: "h-7 text-xs px-2",
|
|
552
|
+
lg: "h-11 text-base px-4 group-data-[collapsible=icon]:!p-0",
|
|
553
|
+
icon: "h-9 w-9 p-0 justify-center",
|
|
554
|
+
},
|
|
555
|
+
isActive: {
|
|
556
|
+
true: "font-medium text-sidebar-foreground border-primary",
|
|
557
|
+
false: "",
|
|
558
|
+
},
|
|
559
|
+
},
|
|
560
|
+
defaultVariants: {
|
|
561
|
+
variant: "default",
|
|
562
|
+
size: "default",
|
|
563
|
+
isActive: false,
|
|
564
|
+
},
|
|
565
|
+
}
|
|
566
|
+
);
|
|
567
|
+
const groupVariants = cva("relative flex w-full min-w-0 flex-col p-2", {
|
|
568
|
+
variants: {
|
|
569
|
+
variant: {
|
|
570
|
+
default: "",
|
|
571
|
+
separated: "border-t border-sidebar-border pt-4 mt-2",
|
|
572
|
+
card: "bg-sidebar-accent/5 rounded-lg p-3 m-1",
|
|
573
|
+
bordered: "border border-sidebar-border rounded-md p-3 m-1",
|
|
574
|
+
subtle: "bg-sidebar-accent/3 p-3",
|
|
575
|
+
},
|
|
576
|
+
},
|
|
577
|
+
defaultVariants: {
|
|
578
|
+
variant: "default",
|
|
579
|
+
},
|
|
580
|
+
});
|
|
581
|
+
const groupLabelVariants = cva(
|
|
582
|
+
"flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opa] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
|
|
583
|
+
{
|
|
584
|
+
variants: {
|
|
585
|
+
variant: {
|
|
586
|
+
default: "",
|
|
587
|
+
prominent: "font-semibold text-sidebar-foreground uppercase tracking-wider",
|
|
588
|
+
subtle: "text-xs text-muted-foreground",
|
|
589
|
+
separated: "border-b border-sidebar-border pb-2 mb-2",
|
|
590
|
+
},
|
|
591
|
+
},
|
|
592
|
+
defaultVariants: {
|
|
593
|
+
variant: "default",
|
|
594
|
+
},
|
|
595
|
+
}
|
|
596
|
+
);
|
|
597
|
+
const menuItemVariants = cva("group/menu-item relative", {
|
|
598
|
+
variants: {
|
|
599
|
+
variant: {
|
|
600
|
+
default: "",
|
|
601
|
+
spaced: "my-0.5",
|
|
602
|
+
compact: "my-0",
|
|
603
|
+
comfortable: "my-1",
|
|
604
|
+
},
|
|
605
|
+
},
|
|
606
|
+
defaultVariants: {
|
|
607
|
+
variant: "default",
|
|
608
|
+
},
|
|
609
|
+
});
|
|
610
|
+
const drawerVariants = cva(["group/drawer-content fixed z-50 flex flex-col",],
|
|
611
|
+
{
|
|
612
|
+
variants: {
|
|
613
|
+
variant: {
|
|
614
|
+
default: "",
|
|
615
|
+
card: [
|
|
616
|
+
"bg-card rounded-t-xl shadow-xl",
|
|
617
|
+
"data-[vaul-drawer-direction=bottom]:mb-5",
|
|
618
|
+
"data-[vaul-drawer-direction=top]:mt-5",
|
|
619
|
+
"data-[vaul-drawer-direction=left]:ml-5",
|
|
620
|
+
"data-[vaul-drawer-direction=right]:mr-5",
|
|
621
|
+
],
|
|
622
|
+
glass: [
|
|
623
|
+
"backdrop-blur-xl bg-background/80 border-t border-white/10 max-w-sm ",
|
|
624
|
+
"data-[vaul-drawer-direction=bottom]:mb-5",
|
|
625
|
+
"data-[vaul-drawer-direction=top]:mt-5",
|
|
626
|
+
"data-[vaul-drawer-direction=left]:ml-5",
|
|
627
|
+
"data-[vaul-drawer-direction=right]:mr-5",
|
|
628
|
+
],
|
|
629
|
+
elevated: [
|
|
630
|
+
"bg-background shadow-2xl max-w-sm ",
|
|
631
|
+
"data-[vaul-drawer-direction=bottom]:mb-5",
|
|
632
|
+
"data-[vaul-drawer-direction=top]:mt-5",
|
|
633
|
+
"data-[vaul-drawer-direction=left]:ml-5",
|
|
634
|
+
"data-[vaul-drawer-direction=right]:mr-5",
|
|
635
|
+
],
|
|
636
|
+
bordered: [
|
|
637
|
+
"bg-background border-t-2 border-primary/20 max-w-sm ",
|
|
638
|
+
"data-[vaul-drawer-direction=bottom]:mb-5",
|
|
639
|
+
"data-[vaul-drawer-direction=top]:mt-5",
|
|
640
|
+
"data-[vaul-drawer-direction=left]:ml-5",
|
|
641
|
+
"data-[vaul-drawer-direction=right]:mr-5",
|
|
642
|
+
],
|
|
643
|
+
macos: [
|
|
644
|
+
"backdrop-blur-xl bg-card/70 shadow-2xl border border-border/50 w-full max-w-sm rounded-3xl mx-auto ",
|
|
645
|
+
"data-[vaul-drawer-direction=bottom]:mb-5",
|
|
646
|
+
"data-[vaul-drawer-direction=top]:mt-5",
|
|
647
|
+
"data-[vaul-drawer-direction=left]:ml-5",
|
|
648
|
+
"data-[vaul-drawer-direction=right]:mr-5",
|
|
649
|
+
],
|
|
650
|
+
},
|
|
651
|
+
direction: {
|
|
652
|
+
top: "border-b rounded-b-lg max-h-[80vh] mb-24 top-0 inset-x-0 left-1/2 -translate-x-1/2",
|
|
653
|
+
bottom: "border-t rounded-t-lg max-h-[80vh] mt-24 bottom-0 inset-x-0 left-1/2 -translate-x-1/2",
|
|
654
|
+
right: "sm:max-w-sm border-l w-3/4 right-0 inset-y-0 top-1/2 -translate-y-1/2",
|
|
655
|
+
left: "inset-y-0 left-0 w-3/4 border-r sm:max-w-sm top-1/2 -translate-y-1/2",
|
|
656
|
+
},
|
|
657
|
+
size: {
|
|
658
|
+
default: "h-auto",
|
|
659
|
+
sm: "h-[50vh]",
|
|
660
|
+
md: "h-[70vh]",
|
|
661
|
+
lg: "h-[90vh]",
|
|
662
|
+
full: "h-screen",
|
|
663
|
+
},
|
|
664
|
+
},
|
|
665
|
+
defaultVariants: {
|
|
666
|
+
variant: "default",
|
|
667
|
+
size: "default",
|
|
668
|
+
},
|
|
669
|
+
}
|
|
670
|
+
);
|
|
671
|
+
const loadingVariants = cva(
|
|
672
|
+
"flex flex-col items-center justify-center text-center p-8 min-h-[400px] h-screen bg-gradient-to-b from-background to-muted/20",
|
|
673
|
+
{
|
|
674
|
+
variants: {
|
|
675
|
+
variant: {
|
|
676
|
+
default: "",
|
|
677
|
+
minimal: "bg-transparent from-transparent to-transparent",
|
|
678
|
+
card: "bg-card rounded-lg shadow-lg max-h-[600px]",
|
|
679
|
+
centered: "h-auto min-h-[300px]",
|
|
680
|
+
},
|
|
681
|
+
size: {
|
|
682
|
+
default: "w-[256px]",
|
|
683
|
+
sm: "w-[200px]",
|
|
684
|
+
md: "w-[280px]",
|
|
685
|
+
lg: "w-[320px]",
|
|
686
|
+
full: "w-full",
|
|
687
|
+
},
|
|
688
|
+
},
|
|
689
|
+
defaultVariants: {
|
|
690
|
+
variant: "default",
|
|
691
|
+
size: "default",
|
|
692
|
+
},
|
|
693
|
+
}
|
|
694
|
+
);
|
|
695
|
+
const insetVariants = cva(
|
|
696
|
+
"relative flex flex-1 flex-col mx-auto bg-background min-w-0 flex-grow transition-[margin] duration-300",
|
|
697
|
+
{
|
|
698
|
+
variants: {
|
|
699
|
+
variant: {
|
|
700
|
+
default: "bg-background w-full h-full",
|
|
701
|
+
inset: ``, // bg-background rounded-[8px] p-[8px] m-[8px] mt-[16px]! overflow-hidden h-[calc(100vh-16px)] w-full max-w-[calc(100vw-${DS_WIDTH}-32px)]
|
|
702
|
+
card: "bg-card rounded-xl shadow-lg m-4 h-[calc(100vh-32px)]",
|
|
703
|
+
bordered: "bg-background border-2 border-border rounded-lg m-2 h-[calc(100vh-16px)]",
|
|
704
|
+
},
|
|
705
|
+
},
|
|
706
|
+
defaultVariants: {
|
|
707
|
+
variant: "default",
|
|
708
|
+
},
|
|
709
|
+
}
|
|
710
|
+
);
|
|
711
|
+
const menuBadgeVariants = cva(
|
|
712
|
+
"pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums text-sidebar-foreground",
|
|
713
|
+
"peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground",
|
|
714
|
+
"peer-data-[size=sm]/menu-button:top-1",
|
|
715
|
+
"peer-data-[size=default]/menu-button:top-1.5",
|
|
716
|
+
"peer-data-[size=lg]/menu-button:top-2.5",
|
|
717
|
+
"group-data-[collapsible=icon]:hidden",
|
|
718
|
+
{
|
|
719
|
+
variants: {
|
|
720
|
+
variant: {
|
|
721
|
+
default: "bg-sidebar-accent text-sidebar-accent-foreground",
|
|
722
|
+
primary: "bg-primary text-primary-foreground",
|
|
723
|
+
secondary: "bg-secondary text-secondary-foreground",
|
|
724
|
+
success: "bg-green-500/10 text-green-600 dark:text-green-400",
|
|
725
|
+
warning: "bg-yellow-500/10 text-yellow-600 dark:text-yellow-400",
|
|
726
|
+
danger: "bg-red-500/10 text-red-600 dark:text-red-400",
|
|
727
|
+
outline: "border border-sidebar-border bg-transparent",
|
|
728
|
+
ghost: "bg-sidebar-accent/30 text-sidebar-accent-foreground",
|
|
729
|
+
dot: "min-w-2 w-2 h-2 rounded-full p-0 bg-primary",
|
|
730
|
+
},
|
|
731
|
+
},
|
|
732
|
+
defaultVariants: {
|
|
733
|
+
variant: "default",
|
|
734
|
+
},
|
|
735
|
+
}
|
|
736
|
+
);
|
|
737
|
+
const menuSubButtonVariants = cva(
|
|
738
|
+
"flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-none ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
|
|
739
|
+
"data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground",
|
|
740
|
+
"group-data-[collapsible=icon]:hidden",
|
|
741
|
+
{
|
|
742
|
+
variants: {
|
|
743
|
+
variant: {
|
|
744
|
+
default: "data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground",
|
|
745
|
+
ghost: "hover:bg-sidebar-accent/30 data-[active=true]:bg-sidebar-accent/50",
|
|
746
|
+
minimal: "hover:text-primary data-[active=true]:text-primary data-[active=true]:font-medium",
|
|
747
|
+
indent: "pl-6 hover:bg-sidebar-accent/30 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium",
|
|
748
|
+
},
|
|
749
|
+
size: {
|
|
750
|
+
default: "h-8 text-sm",
|
|
751
|
+
sm: "h-7 text-xs",
|
|
752
|
+
lg: "h-9 text-sm",
|
|
753
|
+
},
|
|
754
|
+
},
|
|
755
|
+
defaultVariants: {
|
|
756
|
+
variant: "default",
|
|
757
|
+
size: "default",
|
|
758
|
+
},
|
|
759
|
+
}
|
|
760
|
+
);
|
|
761
|
+
const separatorVariants = cva("mx-2 w-auto bg-sidebar-border", {
|
|
762
|
+
variants: {
|
|
763
|
+
variant: {
|
|
764
|
+
default: "h-px",
|
|
765
|
+
thick: "h-0.5",
|
|
766
|
+
dashed: "h-px border-t border-dashed border-sidebar-border bg-transparent",
|
|
767
|
+
gradient: "h-px bg-gradient-to-r from-transparent via-sidebar-border to-transparent",
|
|
768
|
+
},
|
|
769
|
+
spacing: {
|
|
770
|
+
default: "my-2",
|
|
771
|
+
sm: "my-1",
|
|
772
|
+
lg: "my-4",
|
|
773
|
+
none: "my-0",
|
|
774
|
+
},
|
|
775
|
+
},
|
|
776
|
+
defaultVariants: {
|
|
777
|
+
variant: "default",
|
|
778
|
+
spacing: "default",
|
|
779
|
+
},
|
|
780
|
+
});
|
|
781
|
+
const headerVariants = cva("flex flex-col gap-2 p-2 group-data-[variant=floating]:bg-sidebar group-data-[variant=floating]:text-sidebar-foreground group-data-[variant=sidebar]:bg-sidebar group-data-[variant=sidebar]:text-sidebar-foreground", {
|
|
782
|
+
variants: {
|
|
783
|
+
variant: {
|
|
784
|
+
default: "",
|
|
785
|
+
bordered: "border-b border-sidebar-border",
|
|
786
|
+
elevated: "shadow-sm",
|
|
787
|
+
compact: "p-1 gap-1",
|
|
788
|
+
},
|
|
789
|
+
},
|
|
790
|
+
defaultVariants: {
|
|
791
|
+
variant: "default",
|
|
792
|
+
},
|
|
793
|
+
});
|
|
794
|
+
const footerVariants = cva("flex flex-col gap-2 p-2 group-data-[variant=floating]:bg-sidebar group-data-[variant=floating]:text-sidebar-foreground group-data-[variant=sidebar]:bg-sidebar group-data-[variant=sidebar]:text-sidebar-foreground", {
|
|
795
|
+
variants: {
|
|
796
|
+
variant: {
|
|
797
|
+
default: "",
|
|
798
|
+
bordered: "border-t border-sidebar-border",
|
|
799
|
+
elevated: "shadow-sm",
|
|
800
|
+
compact: "p-1 gap-1",
|
|
801
|
+
},
|
|
802
|
+
},
|
|
803
|
+
defaultVariants: {
|
|
804
|
+
variant: "default",
|
|
805
|
+
},
|
|
806
|
+
});
|
|
807
|
+
const headerStyles = {
|
|
808
|
+
container: "flex flex-col gap-3 p-4 pb-2",
|
|
809
|
+
topBar: "flex justify-between max-md:hidden",
|
|
810
|
+
logo: "inline-flex items-center gap-2.5 font-medium",
|
|
811
|
+
logoIcon: "size-6.5 dark:invert",
|
|
812
|
+
logoText: "ms-2.5 text-lg font-semibold",
|
|
813
|
+
collapseButton: "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors duration-100 disabled:pointer-events-none disabled:opacity-50 focus-visible:outline-none hover:bg-fd-accent hover:text-fd-accent-foreground p-1.5 [&_svg]:size-4.5 mt-px mb-auto text-fd-muted-foreground",
|
|
814
|
+
};
|
|
815
|
+
// Search/Menu Button
|
|
816
|
+
const searchButtonStyles = {
|
|
817
|
+
base: "flex items-center gap-2 rounded-lg p-2 border bg-fd-secondary/50 text-start text-fd-secondary-foreground transition-colors hover:bg-fd-accent data-[state=open]:bg-fd-accent data-[state=open]:text-fd-accent-foreground lg:hidden",
|
|
818
|
+
icon: "size-9 md:size-5",
|
|
819
|
+
title: "text-sm font-medium",
|
|
820
|
+
subtitle: "text-[13px] text-fd-muted-foreground empty:hidden md:hidden",
|
|
821
|
+
chevron: "ms-auto size-4 text-fd-muted-foreground",
|
|
822
|
+
};
|
|
823
|
+
const navItemStyles = {
|
|
824
|
+
// Section Headers
|
|
825
|
+
sectionHeader: "inline-flex items-center gap-2 mb-1.5 px-2 empty:mb-0 [&_svg]:size-4 [&_svg]:shrink-0",
|
|
826
|
+
|
|
827
|
+
// Regular Links
|
|
828
|
+
link: "relative flex flex-row items-center gap-2 rounded-xl p-2 text-start text-fd-muted-foreground [overflow-wrap:anywhere] [&_svg]:size-4 [&_svg]:shrink-0 transition-colors hover:bg-fd-accent/50 hover:text-fd-accent-foreground/80 hover:transition-none",
|
|
829
|
+
|
|
830
|
+
// Active Link
|
|
831
|
+
activeLink: "relative flex flex-row items-center gap-2 rounded-xl p-2 text-start [overflow-wrap:anywhere] [&_svg]:size-4 [&_svg]:shrink-0 bg-fd-primary/10 text-fd-primary",
|
|
832
|
+
|
|
833
|
+
// Collapsible Button
|
|
834
|
+
collapsibleButton: "relative flex flex-row items-center gap-2 rounded-xl p-2 text-start text-fd-muted-foreground [overflow-wrap:anywhere] [&_svg]:size-4 [&_svg]:shrink-0 transition-colors hover:bg-fd-accent/50 hover:text-fd-accent-foreground/80 hover:transition-none w-full",
|
|
835
|
+
|
|
836
|
+
// Nested Items (with indent)
|
|
837
|
+
nestedLink: "relative flex flex-row items-center gap-2 rounded-xl p-2 text-start text-fd-muted-foreground [overflow-wrap:anywhere] [&_svg]:size-4 [&_svg]:shrink-0 transition-colors hover:bg-fd-accent/50 hover:text-fd-accent-foreground/80 hover:transition-none",
|
|
838
|
+
|
|
839
|
+
// Vertical line for nested items
|
|
840
|
+
verticalLine: "absolute w-px inset-y-1 bg-fd-border start-2.5",
|
|
841
|
+
activeVerticalLine: "absolute w-px inset-y-3 z-2 start-2.5 md:inset-y-2",
|
|
842
|
+
activeVerticalLineColor: "absolute w-px inset-y-3 z-2 start-2.5 md:inset-y-2 bg-fd-primary",
|
|
843
|
+
};
|
|
844
|
+
const footerStyles = {
|
|
845
|
+
container: "border-t px-4 py-3 flex flex-row items-center justify-end data-[empty=true]:hidden",
|
|
846
|
+
socialLink: "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors duration-100 disabled:pointer-events-none disabled:opacity-50 focus-visible:outline-none hover:bg-fd-accent hover:text-fd-accent-foreground p-1.5 [&_svg]:size-4.5 text-fd-muted-foreground",
|
|
847
|
+
};
|
|
848
|
+
type DSContextProps = {
|
|
849
|
+
leftState: "expanded" | "collapsed";
|
|
850
|
+
rightState: "expanded" | "collapsed";
|
|
851
|
+
openLeft: boolean;
|
|
852
|
+
openRight: boolean;
|
|
853
|
+
setOpenLeft: (open: boolean) => void;
|
|
854
|
+
setOpenRight: (open: boolean) => void;
|
|
855
|
+
openMobile: boolean;
|
|
856
|
+
openMobileRight: boolean;
|
|
857
|
+
setOpenMobile: (open: boolean) => void;
|
|
858
|
+
setOpenMobileRight: (open: boolean) => void;
|
|
859
|
+
isMobile: boolean;
|
|
860
|
+
sidebarWidth: number;
|
|
861
|
+
toggleLeft: () => void;
|
|
862
|
+
toggleRight: () => void;
|
|
863
|
+
|
|
864
|
+
leftVariant: SidebarVariant;
|
|
865
|
+
rightVariant: SidebarVariant;
|
|
866
|
+
setLeftVariant: (variant: SidebarVariant) => void;
|
|
867
|
+
setRightVariant: (variant: SidebarVariant) => void;
|
|
868
|
+
|
|
869
|
+
isIconLeftActive: boolean;
|
|
870
|
+
setIsIconLeftActive: (open: boolean) => void;
|
|
871
|
+
iconLeftWidth: number;
|
|
872
|
+
setIconLeftWidth: (width: number) => void;
|
|
873
|
+
|
|
874
|
+
isIconRightActive: boolean;
|
|
875
|
+
setIsIconRightActive: (open: boolean) => void;
|
|
876
|
+
iconRightWidth: number;
|
|
877
|
+
setIconRightWidth: (width: number) => void;
|
|
878
|
+
|
|
879
|
+
topHeight: string;
|
|
880
|
+
setTopHeight: (height: string) => void;
|
|
881
|
+
|
|
882
|
+
bottomHeight: string;
|
|
883
|
+
setBottomHeight: (height: string) => void;
|
|
884
|
+
};
|
|
885
|
+
|
|
886
|
+
interface DSThemeContextProps {
|
|
887
|
+
theme: DSTheme;
|
|
888
|
+
setTheme: (theme: DSTheme) => void;
|
|
889
|
+
themeVars: Record<string, string>;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
const DSContext = createContext<DSContextProps | null>(null);
|
|
893
|
+
const DSThemeContext = createContext<DSThemeContextProps | undefined>(undefined);
|
|
894
|
+
|
|
895
|
+
function useDS() {
|
|
896
|
+
const context = useContext(DSContext);
|
|
897
|
+
if (!context) throw new Error("useDS must be used within DSProvider");
|
|
898
|
+
return context;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
function useDSTheme() {
|
|
902
|
+
const ctx = useContext(DSThemeContext);
|
|
903
|
+
if (!ctx) throw new Error("useDSTheme must be used within DSProvider");
|
|
904
|
+
return ctx;
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
const DSThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
908
|
+
const storageKey = LOCAL_DS_STORAGE_KEY;
|
|
909
|
+
const Context = DSThemeContext;
|
|
910
|
+
|
|
911
|
+
const [theme, setTheme] = React.useState<DSTheme>(() => {
|
|
912
|
+
if (typeof window !== "undefined") {
|
|
913
|
+
const storedTheme = localStorage.getItem(storageKey);
|
|
914
|
+
if (storedTheme && THEME_OPTIONS.includes(storedTheme as DSTheme)) {
|
|
915
|
+
return storedTheme as DSTheme;
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
return "default";
|
|
919
|
+
});
|
|
920
|
+
|
|
921
|
+
const themeVars = React.useMemo(() => {
|
|
922
|
+
if (theme === "default") return {};
|
|
923
|
+
return (colorThemes as any)[theme]?.[THEME_VERSION]?.dark || {};
|
|
924
|
+
}, [theme]);
|
|
925
|
+
|
|
926
|
+
React.useEffect(() => {
|
|
927
|
+
if (typeof window !== "undefined") {
|
|
928
|
+
localStorage.setItem(storageKey, theme);
|
|
929
|
+
}
|
|
930
|
+
}, [theme, storageKey]);
|
|
931
|
+
|
|
932
|
+
React.useEffect(() => {
|
|
933
|
+
if (typeof document === "undefined") return;
|
|
934
|
+
const root = document.documentElement;
|
|
935
|
+
const prefix = "--dual";
|
|
936
|
+
|
|
937
|
+
if (Object.keys(themeVars).length > 0) {
|
|
938
|
+
Object.entries(themeVars).forEach(([key, value]) => {
|
|
939
|
+
const newKey = key.replace("--sidebar", prefix);
|
|
940
|
+
root.style.setProperty(newKey, String(value));
|
|
941
|
+
});
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
return () => {
|
|
945
|
+
Object.keys(themeVars).forEach((key) => {
|
|
946
|
+
const newKey = key.replace("--sidebar", prefix);
|
|
947
|
+
root.style.removeProperty(newKey);
|
|
948
|
+
});
|
|
949
|
+
};
|
|
950
|
+
}, [themeVars]);
|
|
951
|
+
|
|
952
|
+
return <Context.Provider value={{ theme, setTheme, themeVars }}>{children}</Context.Provider>;
|
|
953
|
+
};
|
|
954
|
+
|
|
955
|
+
function DSThemeSelector({ size = 28, className, children }: { size?: number; className?: string; children: React.ReactNode; }) {
|
|
956
|
+
const { theme, setTheme } = useDSTheme();
|
|
957
|
+
const [open, setOpen] = React.useState(false);
|
|
958
|
+
const [flyingTheme, setFlyingTheme] = React.useState<DSTheme | null>(null);
|
|
959
|
+
const [showOverlay, setShowOverlay] = React.useState(false);
|
|
960
|
+
const [flyingButtonPos, setFlyingButtonPos] = React.useState<{ left: number; top: number } | null>(null);
|
|
961
|
+
const [mainButtonOriginalPos, setMainButtonOriginalPos] = React.useState<{ left: number; top: number } | null>(null);
|
|
962
|
+
const mainButtonRef = React.useRef<HTMLButtonElement>(null);
|
|
963
|
+
|
|
964
|
+
const radius = size * 1.6;
|
|
965
|
+
const themeList = THEME_OPTIONS;
|
|
966
|
+
const mainButtonCenterOffset = size * 1.5;
|
|
967
|
+
const mainButtonSize = size;
|
|
968
|
+
|
|
969
|
+
function getThemeColor(t: string) {
|
|
970
|
+
const themeObj = colorThemes[t as DSTheme]?.[THEME_VERSION]?.dark;
|
|
971
|
+
const primaryColor = themeObj?.["--primary"];
|
|
972
|
+
if (primaryColor) {
|
|
973
|
+
if (primaryColor.startsWith("oklch")) {
|
|
974
|
+
return primaryColor;
|
|
975
|
+
} else {
|
|
976
|
+
return `hsl(${primaryColor})`;
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
return "#888";
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
const handleMainButtonClick = () => {
|
|
983
|
+
if (flyingTheme) return;
|
|
984
|
+
if (!open && mainButtonRef.current) {
|
|
985
|
+
const rect = mainButtonRef.current.getBoundingClientRect();
|
|
986
|
+
setMainButtonOriginalPos({
|
|
987
|
+
left: rect.left + rect.width / 2,
|
|
988
|
+
top: rect.top + rect.height / 2,
|
|
989
|
+
});
|
|
990
|
+
}
|
|
991
|
+
setOpen((v) => !v);
|
|
992
|
+
setShowOverlay(!open);
|
|
993
|
+
};
|
|
994
|
+
|
|
995
|
+
const handleThemeSelect = (t: DSTheme, event: React.MouseEvent<HTMLButtonElement>) => {
|
|
996
|
+
const button = event.currentTarget;
|
|
997
|
+
const rect = button.getBoundingClientRect();
|
|
998
|
+
|
|
999
|
+
setFlyingButtonPos({
|
|
1000
|
+
left: rect.left + rect.width / 2,
|
|
1001
|
+
top: rect.top + rect.height / 2,
|
|
1002
|
+
});
|
|
1003
|
+
|
|
1004
|
+
setFlyingTheme(t);
|
|
1005
|
+
setShowOverlay(true);
|
|
1006
|
+
setOpen(false);
|
|
1007
|
+
|
|
1008
|
+
setTimeout(() => {
|
|
1009
|
+
setTheme(t);
|
|
1010
|
+
}, 300);
|
|
1011
|
+
|
|
1012
|
+
setTimeout(() => {
|
|
1013
|
+
setShowOverlay(false);
|
|
1014
|
+
setFlyingTheme(null);
|
|
1015
|
+
setFlyingButtonPos(null);
|
|
1016
|
+
setMainButtonOriginalPos(null);
|
|
1017
|
+
}, 600);
|
|
1018
|
+
};
|
|
1019
|
+
|
|
1020
|
+
let mainButtonStyle: React.CSSProperties = {
|
|
1021
|
+
zIndex: 70,
|
|
1022
|
+
};
|
|
1023
|
+
|
|
1024
|
+
if (open || mainButtonOriginalPos) {
|
|
1025
|
+
const targetLeft = open ? window.innerWidth / 2 : mainButtonOriginalPos?.left || window.innerWidth / 2;
|
|
1026
|
+
const targetTop = open ? window.innerHeight / 2 : mainButtonOriginalPos?.top || window.innerHeight / 2;
|
|
1027
|
+
|
|
1028
|
+
mainButtonStyle = {
|
|
1029
|
+
...mainButtonStyle,
|
|
1030
|
+
position: "fixed",
|
|
1031
|
+
left: `${targetLeft}px`,
|
|
1032
|
+
top: `${targetTop}px`,
|
|
1033
|
+
transform: "translate(-50%, -50%)",
|
|
1034
|
+
};
|
|
1035
|
+
} else {
|
|
1036
|
+
mainButtonStyle = {
|
|
1037
|
+
...mainButtonStyle,
|
|
1038
|
+
position: "absolute",
|
|
1039
|
+
left: mainButtonCenterOffset - mainButtonSize / 2,
|
|
1040
|
+
top: mainButtonCenterOffset - mainButtonSize / 2,
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
return (
|
|
1045
|
+
<>
|
|
1046
|
+
{showOverlay && <div
|
|
1047
|
+
className="fixed inset-0 bg-black/60 transition-opacity duration-500 theme-overlay"
|
|
1048
|
+
// style={{ zIndex: Z_INDEX.OVERLAY, position: 'fixed', }}
|
|
1049
|
+
/>}
|
|
1050
|
+
|
|
1051
|
+
<div
|
|
1052
|
+
className={cn("flex items-center justify-center transition-all duration-1000 theme-container", className)}
|
|
1053
|
+
style={{
|
|
1054
|
+
width: size * 3,
|
|
1055
|
+
height: size * 3,
|
|
1056
|
+
// zIndex: Z_INDEX.CONTAINER,
|
|
1057
|
+
position: open ? 'static' : 'relative',
|
|
1058
|
+
isolation: 'isolate',
|
|
1059
|
+
}}
|
|
1060
|
+
>
|
|
1061
|
+
<button
|
|
1062
|
+
ref={mainButtonRef}
|
|
1063
|
+
onClick={handleMainButtonClick}
|
|
1064
|
+
className={cn(
|
|
1065
|
+
"flex items-center justify-center rounded-full bg-background shadow-lg transition-all duration-500 theme-main-button",
|
|
1066
|
+
`h-[${mainButtonSize}px] w-[${mainButtonSize}px]`,
|
|
1067
|
+
open ? "bg-sidebar-accent text-sidebar-accent-foreground" : "",
|
|
1068
|
+
open || mainButtonOriginalPos ? "!fixed" : ""
|
|
1069
|
+
)}
|
|
1070
|
+
style={{
|
|
1071
|
+
...mainButtonStyle,
|
|
1072
|
+
// zIndex: Z_INDEX.MAIN_BUTTON,
|
|
1073
|
+
}}
|
|
1074
|
+
>
|
|
1075
|
+
{children}
|
|
1076
|
+
</button>
|
|
1077
|
+
|
|
1078
|
+
{themeList.map((t, i) => {
|
|
1079
|
+
const angle = (360 / themeList.length) * i - 90;
|
|
1080
|
+
const rad = (angle * Math.PI) / 180;
|
|
1081
|
+
const radialX = Math.cos(rad) * radius;
|
|
1082
|
+
const radialY = Math.sin(rad) * radius;
|
|
1083
|
+
|
|
1084
|
+
let currentX = 0;
|
|
1085
|
+
let currentY = 0;
|
|
1086
|
+
let currentScale = 0;
|
|
1087
|
+
let currentOpacity = 0;
|
|
1088
|
+
let currentZIndex = 10;
|
|
1089
|
+
let currentDelay = open ? `${i * 90}ms` : "0ms";
|
|
1090
|
+
let isFixed = false;
|
|
1091
|
+
let fixedLeft = 0;
|
|
1092
|
+
let fixedTop = 0;
|
|
1093
|
+
|
|
1094
|
+
if (flyingTheme === t) {
|
|
1095
|
+
isFixed = true;
|
|
1096
|
+
currentScale = 1.2;
|
|
1097
|
+
currentOpacity = 1;
|
|
1098
|
+
currentZIndex = 10000;
|
|
1099
|
+
currentDelay = "0ms";
|
|
1100
|
+
fixedLeft = window.innerWidth / 2;
|
|
1101
|
+
fixedTop = window.innerHeight / 2;
|
|
1102
|
+
} else if (open) {
|
|
1103
|
+
isFixed = true;
|
|
1104
|
+
fixedLeft = window.innerWidth / 2 + radialX;
|
|
1105
|
+
fixedTop = window.innerHeight / 2 + radialY;
|
|
1106
|
+
currentScale = 1;
|
|
1107
|
+
currentOpacity = 1;
|
|
1108
|
+
currentZIndex = 10;
|
|
1109
|
+
} else if (!open && flyingTheme === null) {
|
|
1110
|
+
currentX = 0;
|
|
1111
|
+
currentY = 0;
|
|
1112
|
+
currentScale = 0;
|
|
1113
|
+
currentOpacity = 0;
|
|
1114
|
+
currentZIndex = 10;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
const buttonSize = size * 1;
|
|
1118
|
+
const buttonOffset = buttonSize / 2;
|
|
1119
|
+
|
|
1120
|
+
return (
|
|
1121
|
+
<button
|
|
1122
|
+
key={t}
|
|
1123
|
+
style={{
|
|
1124
|
+
width: buttonSize,
|
|
1125
|
+
height: buttonSize,
|
|
1126
|
+
...(isFixed
|
|
1127
|
+
? {
|
|
1128
|
+
left: `${fixedLeft}px`,
|
|
1129
|
+
top: `${fixedTop}px`,
|
|
1130
|
+
transform: `translate(-50%, -50%) scale(${currentScale})`,
|
|
1131
|
+
}
|
|
1132
|
+
: {
|
|
1133
|
+
left: mainButtonCenterOffset + currentX - buttonOffset,
|
|
1134
|
+
top: mainButtonCenterOffset + currentY - buttonOffset,
|
|
1135
|
+
transform: `scale(${currentScale})`,
|
|
1136
|
+
}),
|
|
1137
|
+
// zIndex: flyingTheme === t ? Z_INDEX.FLYING_THEME : Z_INDEX.MAIN_BUTTON,
|
|
1138
|
+
opacity: currentOpacity,
|
|
1139
|
+
transitionDelay: currentDelay,
|
|
1140
|
+
transitionTimingFunction: flyingTheme === t ? "cubic-bezier(0.8, -0.5, 0.2, 1.5)" : "ease-out"
|
|
1141
|
+
}}
|
|
1142
|
+
className={cn(
|
|
1143
|
+
`rounded-full border bg-background shadow transition-all duration-500 flex items-center justify-center`,
|
|
1144
|
+
theme === t ? "ring-2 ring-primary border-primary" : "border-muted hover:ring-2 hover:ring-primary",
|
|
1145
|
+
flyingTheme === t ? "ring-4 ring-primary !fixed" : open ? "!fixed" : "absolute",
|
|
1146
|
+
flyingTheme === t ? "theme-flying-theme" : "theme-buttons",
|
|
1147
|
+
)}
|
|
1148
|
+
aria-label={`Switch to ${t} theme`}
|
|
1149
|
+
onClick={(e) => handleThemeSelect(t as DSTheme, e)}
|
|
1150
|
+
disabled={!!flyingTheme}
|
|
1151
|
+
>
|
|
1152
|
+
<Circle style={{ color: getThemeColor(t), fill: getThemeColor(t) }} size={size * 0.3} />
|
|
1153
|
+
</button>
|
|
1154
|
+
);
|
|
1155
|
+
})}
|
|
1156
|
+
</div>
|
|
1157
|
+
</>
|
|
1158
|
+
);
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
const DSProvider = forwardRef<
|
|
1162
|
+
HTMLDivElement,
|
|
1163
|
+
React.ComponentProps<"div"> & {
|
|
1164
|
+
defaultOpenLeft?: boolean;
|
|
1165
|
+
defaultOpenRight?: boolean;
|
|
1166
|
+
defaultWidth?: string;
|
|
1167
|
+
}
|
|
1168
|
+
>(({ defaultOpenLeft = false, defaultOpenRight = false, defaultWidth = DS_WIDTH, className, style, children, ...props }, ref) => {
|
|
1169
|
+
const isMobile = useIsMobile();
|
|
1170
|
+
const [openMobile, setOpenMobile] = useState(false);
|
|
1171
|
+
const [openMobileRight, setOpenMobileRight] = useState(false);
|
|
1172
|
+
|
|
1173
|
+
const [openLeft, setOpenLeft] = useState(defaultOpenLeft);
|
|
1174
|
+
const [openRight, setOpenRight] = useState(defaultOpenRight);
|
|
1175
|
+
|
|
1176
|
+
const [leftVariant, setLeftVariant] = useState("sidebar");
|
|
1177
|
+
const [rightVariant, setRightVariant] = useState("sidebar");
|
|
1178
|
+
|
|
1179
|
+
const [isIconLeftActive, setIsIconLeftActive] = useState(false);
|
|
1180
|
+
const [iconLeftWidth, setIconLeftWidth] = useState("0px");
|
|
1181
|
+
|
|
1182
|
+
const [isIconRightActive, setIsIconRightActive] = useState(false);
|
|
1183
|
+
const [iconRightWidth, setIconRightWidth] = useState("0px");
|
|
1184
|
+
|
|
1185
|
+
const [topHeight, setTopHeight] = useState("0px");
|
|
1186
|
+
const [bottomHeight, setBottomHeight] = useState("0px");
|
|
1187
|
+
|
|
1188
|
+
const [dsdVariant, setDsdVariant] = useState("default");
|
|
1189
|
+
const [dsdDirection, setDsdDirection] = useState("bottom");
|
|
1190
|
+
const [dsdSize, setDsdSize] = useState("md");
|
|
1191
|
+
|
|
1192
|
+
const sidebarWidth = defaultWidth;
|
|
1193
|
+
const cookieName = DS_COOKIE_NAME;
|
|
1194
|
+
const cookieNameRight = DS_COOKIE_NAME_RIGHT;
|
|
1195
|
+
|
|
1196
|
+
const openL = openLeft;
|
|
1197
|
+
const openR = openRight;
|
|
1198
|
+
|
|
1199
|
+
const toggleLeft = useCallback(() => {
|
|
1200
|
+
isMobile ? setOpenMobile((p) => !p) : setOpenLeft((p) => !p);
|
|
1201
|
+
document.cookie = `${cookieName}=${openL}; path=/; max-age=${DS_COOKIE_MAX_AGE}`;
|
|
1202
|
+
}, [isMobile]);
|
|
1203
|
+
|
|
1204
|
+
const toggleRight = useCallback(() => {
|
|
1205
|
+
isMobile ? setOpenMobileRight((p) => !p) : setOpenRight((p) => !p);
|
|
1206
|
+
document.cookie = `${cookieNameRight}=${openR}; path=/; max-age=${DS_COOKIE_MAX_AGE}`;
|
|
1207
|
+
}, [isMobile]);
|
|
1208
|
+
|
|
1209
|
+
useEffect(() => {
|
|
1210
|
+
const shortcutLeft = DS_KEYBOARD_SHORTCUT_LEFT;
|
|
1211
|
+
const handleKeyDown = (event: KeyboardEvent) => {
|
|
1212
|
+
if (event.key === shortcutLeft && (event.metaKey || event.ctrlKey)) {
|
|
1213
|
+
event.preventDefault();
|
|
1214
|
+
// toggleLeft(prev => !prev);
|
|
1215
|
+
toggleLeft();
|
|
1216
|
+
}
|
|
1217
|
+
};
|
|
1218
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
1219
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
1220
|
+
}, [toggleLeft]);
|
|
1221
|
+
|
|
1222
|
+
useEffect(() => {
|
|
1223
|
+
const shortcutRight = DS_KEYBOARD_SHORTCUT_RIGHT;
|
|
1224
|
+
const handleKeyDown = (event: KeyboardEvent) => {
|
|
1225
|
+
if (event.key === shortcutRight && (event.metaKey || event.ctrlKey)) {
|
|
1226
|
+
event.preventDefault();
|
|
1227
|
+
// toggleRight(prev => !prev);
|
|
1228
|
+
toggleRight();
|
|
1229
|
+
}
|
|
1230
|
+
};
|
|
1231
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
1232
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
1233
|
+
}, [toggleRight]);
|
|
1234
|
+
|
|
1235
|
+
const leftState = openL ? "expanded" : "collapsed";
|
|
1236
|
+
const rightState = openR ? "expanded" : "collapsed";
|
|
1237
|
+
|
|
1238
|
+
const contextValue = React.useMemo<DSContextProps>(
|
|
1239
|
+
() => ({
|
|
1240
|
+
leftState,
|
|
1241
|
+
rightState,
|
|
1242
|
+
|
|
1243
|
+
openLeft,
|
|
1244
|
+
setOpenLeft,
|
|
1245
|
+
|
|
1246
|
+
openRight,
|
|
1247
|
+
setOpenRight,
|
|
1248
|
+
|
|
1249
|
+
toggleLeft,
|
|
1250
|
+
toggleRight,
|
|
1251
|
+
|
|
1252
|
+
isMobile,
|
|
1253
|
+
|
|
1254
|
+
openMobile,
|
|
1255
|
+
setOpenMobile,
|
|
1256
|
+
openMobileRight,
|
|
1257
|
+
setOpenMobileRight,
|
|
1258
|
+
|
|
1259
|
+
sidebarWidth,
|
|
1260
|
+
|
|
1261
|
+
leftVariant,
|
|
1262
|
+
setLeftVariant,
|
|
1263
|
+
rightVariant,
|
|
1264
|
+
setRightVariant,
|
|
1265
|
+
|
|
1266
|
+
isIconLeftActive,
|
|
1267
|
+
setIsIconLeftActive,
|
|
1268
|
+
iconLeftWidth,
|
|
1269
|
+
setIconLeftWidth,
|
|
1270
|
+
|
|
1271
|
+
isIconRightActive,
|
|
1272
|
+
setIsIconRightActive,
|
|
1273
|
+
iconRightWidth,
|
|
1274
|
+
setIconRightWidth,
|
|
1275
|
+
|
|
1276
|
+
topHeight,
|
|
1277
|
+
setTopHeight,
|
|
1278
|
+
bottomHeight,
|
|
1279
|
+
setBottomHeight,
|
|
1280
|
+
|
|
1281
|
+
dsdVariant,
|
|
1282
|
+
setDsdVariant,
|
|
1283
|
+
dsdDirection,
|
|
1284
|
+
setDsdDirection,
|
|
1285
|
+
dsdSize,
|
|
1286
|
+
setDsdSize
|
|
1287
|
+
}),
|
|
1288
|
+
[isMobile, openLeft, leftVariant, openRight, rightVariant, isIconLeftActive, iconLeftWidth, isIconRightActive, iconRightWidth, topHeight, bottomHeight, sidebarWidth]
|
|
1289
|
+
);
|
|
1290
|
+
|
|
1291
|
+
const Context = DSContext;
|
|
1292
|
+
|
|
1293
|
+
return (
|
|
1294
|
+
<DSThemeProvider>
|
|
1295
|
+
<Context.Provider value={contextValue}>
|
|
1296
|
+
<TooltipProvider delayDuration={0}>
|
|
1297
|
+
<div
|
|
1298
|
+
style={
|
|
1299
|
+
{
|
|
1300
|
+
"--dual-sidebar-width": sidebarWidth,
|
|
1301
|
+
"--dual-sidebar-width-icon": DS_WIDTH_ICON,
|
|
1302
|
+
...style,
|
|
1303
|
+
} as React.CSSProperties
|
|
1304
|
+
}
|
|
1305
|
+
className={cn(
|
|
1306
|
+
"group/dual-sidebar-wrapper flex min-h-svh w-full",
|
|
1307
|
+
leftVariant === 'inset' || rightVariant === 'inset' ? "bg-sidebar" : null,
|
|
1308
|
+
"w-[100vw] h-[100vh] overflow-hidden",
|
|
1309
|
+
//"bg-[#111827] ",
|
|
1310
|
+
className
|
|
1311
|
+
)}
|
|
1312
|
+
ref={ref}
|
|
1313
|
+
{...props}
|
|
1314
|
+
>
|
|
1315
|
+
{children}
|
|
1316
|
+
</div>
|
|
1317
|
+
</TooltipProvider>
|
|
1318
|
+
</Context.Provider>
|
|
1319
|
+
</DSThemeProvider>
|
|
1320
|
+
);
|
|
1321
|
+
});
|
|
1322
|
+
DSProvider.displayName = "DSProvider";
|
|
1323
|
+
|
|
1324
|
+
const DSInset = forwardRef<HTMLDivElement, React.ComponentProps<"main">>(({ children, variant = "default", className, ...props }, ref) => {
|
|
1325
|
+
const { openLeft, openRight, sidebarWidth, leftVariant, rightVariant, isIconLeftActive, iconLeftWidth, isIconRightActive, iconRightWidth, topHeight, bottomHeight } = useDS();
|
|
1326
|
+
let paddingTop = topHeight;
|
|
1327
|
+
let paddingBottom = bottomHeight;
|
|
1328
|
+
let marginLeft = "0px";
|
|
1329
|
+
let marginRight = "0px";
|
|
1330
|
+
let leftWidth = sidebarWidth;
|
|
1331
|
+
let rightWidth = sidebarWidth;
|
|
1332
|
+
const closedGap = "0px";
|
|
1333
|
+
const paddingLeft = '8px'
|
|
1334
|
+
const paddingRight = '8px'
|
|
1335
|
+
|
|
1336
|
+
if (isIconLeftActive) {
|
|
1337
|
+
leftWidth = `calc(${iconLeftWidth} + ${sidebarWidth})`;
|
|
1338
|
+
}
|
|
1339
|
+
if (isIconRightActive) {
|
|
1340
|
+
rightWidth = `calc(${iconRightWidth} + ${sidebarWidth})`;
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
if (isIconLeftActive) {
|
|
1344
|
+
marginLeft = iconLeftWidth;
|
|
1345
|
+
} else {
|
|
1346
|
+
marginLeft = closedGap;
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
if (isIconRightActive) {
|
|
1350
|
+
marginRight = iconRightWidth;
|
|
1351
|
+
} else {
|
|
1352
|
+
marginRight = closedGap;
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
if (openLeft && (leftVariant === "sidebar" || leftVariant === "inset")) {
|
|
1356
|
+
marginLeft = leftWidth;
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
if (openRight && (rightVariant === "sidebar" || rightVariant === "inset")) {
|
|
1360
|
+
marginRight = `calc(${rightWidth} + 17px)`;
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1363
|
+
let maxWidth = "none"; // Default value
|
|
1364
|
+
if (isIconLeftActive) marginLeft = `calc(${marginLeft} + 12px)`;
|
|
1365
|
+
if (isIconLeftActive && isIconRightActive && (leftVariant === "inset" || rightVariant === "inset")) {
|
|
1366
|
+
maxWidth = `calc(100vw - ${iconLeftWidth} - ${iconRightWidth} - 28px)`;
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
const insetClass = "bg-background rounded-[15px] mt-[7px] overflow-hidden h-[calc(100vh-20px)] w-[calc(100vw-130px)] relative flex flex-1 flex-col overflow-hidden";
|
|
1370
|
+
const defaultVisualClasses = "bg-background w-full h-full";
|
|
1371
|
+
const floatingClass = "";
|
|
1372
|
+
const sidebarClass = "";
|
|
1373
|
+
return (
|
|
1374
|
+
<main
|
|
1375
|
+
ref={ref}
|
|
1376
|
+
className={cn(
|
|
1377
|
+
insetVariants({ variant }),
|
|
1378
|
+
className
|
|
1379
|
+
)}
|
|
1380
|
+
style={{
|
|
1381
|
+
marginLeft,
|
|
1382
|
+
marginRight,
|
|
1383
|
+
paddingTop,
|
|
1384
|
+
paddingBottom,
|
|
1385
|
+
maxWidth,
|
|
1386
|
+
paddingLeft,
|
|
1387
|
+
paddingRight,
|
|
1388
|
+
}}
|
|
1389
|
+
{...props}
|
|
1390
|
+
>
|
|
1391
|
+
{children}
|
|
1392
|
+
</main>
|
|
1393
|
+
);
|
|
1394
|
+
});
|
|
1395
|
+
DSInset.displayName = "DSInset";
|
|
1396
|
+
|
|
1397
|
+
const DSLeft1 = forwardRef<
|
|
1398
|
+
HTMLDivElement,
|
|
1399
|
+
React.ComponentProps<"div"> & {
|
|
1400
|
+
variant?: SidebarVariant;
|
|
1401
|
+
collapsible?: SidebarCollapsible;
|
|
1402
|
+
loadingUI?: boolean;
|
|
1403
|
+
}
|
|
1404
|
+
>(({ variant = "sidebar", collapsible = "offcanvas", className, children, loadingUI = true, ...props }, ref) => {
|
|
1405
|
+
const { isMobile, leftState, openMobile, setOpenMobile, openLeft, sidebarWidth, setLeftVariant, isIconLeftActive, setIsIconLeftActive, iconLeftWidth, setIconLeftWidth } = useDS();
|
|
1406
|
+
|
|
1407
|
+
const navigation = useNavigation();
|
|
1408
|
+
const [hasInitialLoaded, setHasInitialLoaded] = useState(false);
|
|
1409
|
+
|
|
1410
|
+
useEffect(() => {
|
|
1411
|
+
setLeftVariant(variant);
|
|
1412
|
+
}, [variant, setLeftVariant]);
|
|
1413
|
+
|
|
1414
|
+
useEffect(() => {
|
|
1415
|
+
if (navigation.state === "idle" && !hasInitialLoaded) {
|
|
1416
|
+
setHasInitialLoaded(true);
|
|
1417
|
+
}
|
|
1418
|
+
}, [navigation.state, hasInitialLoaded]);
|
|
1419
|
+
|
|
1420
|
+
const showLoading = loadingUI && navigation.state === "loading" && !hasInitialLoaded;
|
|
1421
|
+
|
|
1422
|
+
if (collapsible === "none") {
|
|
1423
|
+
return (
|
|
1424
|
+
<div className={cn("flex h-full w-[--dual-sidebar-width] flex-col bg-sidebar text-sidebar-foreground", className)} ref={ref} {...props}>
|
|
1425
|
+
{showLoading ? <DSLoading /> : children}
|
|
1426
|
+
</div>
|
|
1427
|
+
);
|
|
1428
|
+
}
|
|
1429
|
+
if (isMobile) {
|
|
1430
|
+
return (
|
|
1431
|
+
<Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>
|
|
1432
|
+
<SheetContent data-dual-sidebar="sidebar" data-mobile="true" className="w-[--dual-sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden" style={{ "--dual-sidebar-width": DS_WIDTH_MOBILE } as React.CSSProperties} side="left">
|
|
1433
|
+
<SheetHeader className="sr-only">
|
|
1434
|
+
<SheetTitle>Sidebar</SheetTitle>
|
|
1435
|
+
<SheetDescription>Displays the mobile sidebar.</SheetDescription>
|
|
1436
|
+
</SheetHeader>
|
|
1437
|
+
<div className="flex h-full w-full flex-col">{showLoading ? <DSLoading /> : children}</div>
|
|
1438
|
+
</SheetContent>
|
|
1439
|
+
</Sheet>
|
|
1440
|
+
);
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
// const baseClasses = `fixed inset-y-0 left-1 z-20 w-72 bg-sidebar rounded-[15px] flex flex-col transitio
|
|
1444
|
+
// n-transform duration-300 shadow-2xl`;
|
|
1445
|
+
const closedOffset = "8px";
|
|
1446
|
+
const iconOffset = isIconLeftActive ? iconLeftWidth : "0px";
|
|
1447
|
+
const transformClass = openLeft ? "translate-x-0" : "translate-x-[calc(-100%-4px)]";
|
|
1448
|
+
return (
|
|
1449
|
+
<div
|
|
1450
|
+
className={cn(
|
|
1451
|
+
dsVariants({ variant, side: "left" }),
|
|
1452
|
+
transformClass,
|
|
1453
|
+
!isIconLeftActive && "left-0",
|
|
1454
|
+
className
|
|
1455
|
+
)}
|
|
1456
|
+
style={{
|
|
1457
|
+
width: sidebarWidth,
|
|
1458
|
+
"--dual-sidebar-width-icon": DS_WIDTH_ICON,
|
|
1459
|
+
left: isIconLeftActive ? iconOffset : undefined,
|
|
1460
|
+
transform: openLeft ? "translateX(0)" : `translateX(calc(-100% - ${closedOffset}))`,
|
|
1461
|
+
}}
|
|
1462
|
+
{...props}
|
|
1463
|
+
>
|
|
1464
|
+
{showLoading ? <DSLoading /> : children}
|
|
1465
|
+
</div>
|
|
1466
|
+
);
|
|
1467
|
+
});
|
|
1468
|
+
const DSLeft = forwardRef<
|
|
1469
|
+
HTMLDivElement,
|
|
1470
|
+
React.ComponentProps<"div"> & {
|
|
1471
|
+
variant?: SidebarVariant;
|
|
1472
|
+
collapsible?: SidebarCollapsible;
|
|
1473
|
+
loadingUI?: boolean;
|
|
1474
|
+
}
|
|
1475
|
+
>(({ variant = "sidebar", collapsible = "offcanvas", className, children, loadingUI = true, ...props }, ref) => {
|
|
1476
|
+
const { isMobile, leftState, openMobile, setOpenMobile, openLeft, sidebarWidth, setLeftVariant, isIconLeftActive, setIsIconLeftActive, iconLeftWidth, setIconLeftWidth } = useDS();
|
|
1477
|
+
|
|
1478
|
+
const navigation = useNavigation();
|
|
1479
|
+
const [hasInitialLoaded, setHasInitialLoaded] = useState(false);
|
|
1480
|
+
|
|
1481
|
+
useEffect(() => {
|
|
1482
|
+
setLeftVariant(variant);
|
|
1483
|
+
}, [variant, setLeftVariant]);
|
|
1484
|
+
|
|
1485
|
+
useEffect(() => {
|
|
1486
|
+
if (navigation.state === "idle" && !hasInitialLoaded) {
|
|
1487
|
+
setHasInitialLoaded(true);
|
|
1488
|
+
}
|
|
1489
|
+
}, [navigation.state, hasInitialLoaded]);
|
|
1490
|
+
|
|
1491
|
+
const showLoading = loadingUI && navigation.state === "loading" && !hasInitialLoaded;
|
|
1492
|
+
|
|
1493
|
+
if (collapsible === "none") {
|
|
1494
|
+
return (
|
|
1495
|
+
<div className={cn("flex h-full w-[--dual-sidebar-width] flex-col bg-sidebar text-sidebar-foreground", className)} ref={ref} {...props}>
|
|
1496
|
+
{showLoading ? <DSLoading /> : children}
|
|
1497
|
+
</div>
|
|
1498
|
+
);
|
|
1499
|
+
}
|
|
1500
|
+
if (isMobile) {
|
|
1501
|
+
return (
|
|
1502
|
+
<Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>
|
|
1503
|
+
<SheetContent data-dual-sidebar="sidebar" data-mobile="true" className="w-[--dual-sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden" style={{ "--dual-sidebar-width": DS_WIDTH_MOBILE } as React.CSSProperties} side="left">
|
|
1504
|
+
<SheetHeader className="sr-only">
|
|
1505
|
+
<SheetTitle>Sidebar</SheetTitle>
|
|
1506
|
+
<SheetDescription>Displays the mobile sidebar.</SheetDescription>
|
|
1507
|
+
</SheetHeader>
|
|
1508
|
+
<div className="flex h-full w-full flex-col">{showLoading ? <DSLoading /> : children}</div>
|
|
1509
|
+
</SheetContent>
|
|
1510
|
+
</Sheet>
|
|
1511
|
+
);
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
const closedOffset = "8px";
|
|
1515
|
+
const iconOffset = isIconLeftActive ? iconLeftWidth : "0px";
|
|
1516
|
+
const transformClass = openLeft ? "translate-x-0" : "translate-x-[calc(-100%-4px)]";
|
|
1517
|
+
const isInsetOrFloating = variant === "floating" || variant === "inset";
|
|
1518
|
+
|
|
1519
|
+
return (
|
|
1520
|
+
<div
|
|
1521
|
+
className={cn(
|
|
1522
|
+
dsVariants({ variant, side: "left" }),
|
|
1523
|
+
transformClass,
|
|
1524
|
+
!isIconLeftActive && "left-0",
|
|
1525
|
+
isInsetOrFloating && "p-2",
|
|
1526
|
+
className
|
|
1527
|
+
)}
|
|
1528
|
+
{...props}
|
|
1529
|
+
>
|
|
1530
|
+
<div
|
|
1531
|
+
data-slot="sidebar-gap"
|
|
1532
|
+
className={cn()}
|
|
1533
|
+
style={{
|
|
1534
|
+
width: isInsetOrFloating && !openLeft
|
|
1535
|
+
? `calc(${DS_WIDTH_ICON} + 1rem)`
|
|
1536
|
+
: sidebarWidth,
|
|
1537
|
+
"--dual-sidebar-width-icon": DS_WIDTH_ICON,
|
|
1538
|
+
left: isIconLeftActive ? iconOffset : undefined,
|
|
1539
|
+
transform: openLeft
|
|
1540
|
+
? "translateX(0)"
|
|
1541
|
+
: `translateX(calc(-${sidebarWidth} - ${closedOffset}))`,
|
|
1542
|
+
}}
|
|
1543
|
+
/>
|
|
1544
|
+
<div className={cn(
|
|
1545
|
+
"flex h-full w-full flex-col bg-sidebar",
|
|
1546
|
+
isInsetOrFloating && "rounded-lg border border-sidebar-border shadow-sm"
|
|
1547
|
+
)}>
|
|
1548
|
+
{showLoading ? <DSLoading /> : children}
|
|
1549
|
+
</div>
|
|
1550
|
+
</div>
|
|
1551
|
+
);
|
|
1552
|
+
});
|
|
1553
|
+
DSLeft.displayName = "DSLeft";
|
|
1554
|
+
|
|
1555
|
+
const DSLeftIcon = forwardRef<
|
|
1556
|
+
HTMLDivElement,
|
|
1557
|
+
React.ComponentProps<"div"> & {
|
|
1558
|
+
// We assume the desired width is DS_WIDTH_ICON or similar constant
|
|
1559
|
+
iconWidth?: string;
|
|
1560
|
+
variant?: SidebarVariant;
|
|
1561
|
+
|
|
1562
|
+
}
|
|
1563
|
+
>(({ iconWidth = DS_WIDTH_ICON, variant = "sidebar", className, children, ...props }, ref) => {
|
|
1564
|
+
// 1. Communicate its existence and width to the context (NEW STATE)
|
|
1565
|
+
const { setIsIconLeftActive, setIconLeftWidth, leftVariant } = useDS(); // Assumes new context setters
|
|
1566
|
+
|
|
1567
|
+
// Set context state on mount/unmount
|
|
1568
|
+
useEffect(() => {
|
|
1569
|
+
setIsIconLeftActive(true);
|
|
1570
|
+
setIconLeftWidth(iconWidth);
|
|
1571
|
+
return () => {
|
|
1572
|
+
setIsIconLeftActive(false);
|
|
1573
|
+
setIconLeftWidth("0px");
|
|
1574
|
+
};
|
|
1575
|
+
}, [iconWidth, setIsIconLeftActive, setIconLeftWidth]);
|
|
1576
|
+
|
|
1577
|
+
return (
|
|
1578
|
+
<div
|
|
1579
|
+
ref={ref}
|
|
1580
|
+
/** className={cn(
|
|
1581
|
+
leftVariant === "inset" ? "bg-sidebar" : "bg-background",
|
|
1582
|
+
"fixed inset-y-0 left-0 z-20 hidden h-svh flex-col md:flex",
|
|
1583
|
+
// Transition/width applied via style
|
|
1584
|
+
className
|
|
1585
|
+
)} */
|
|
1586
|
+
className={cn(
|
|
1587
|
+
iconDSVariants({ variant: leftVariant, side: "left" }),
|
|
1588
|
+
className
|
|
1589
|
+
)}
|
|
1590
|
+
style={
|
|
1591
|
+
{
|
|
1592
|
+
// Set the width for this specific component
|
|
1593
|
+
"--dual-sidebar-icon-width-fixed": iconWidth,
|
|
1594
|
+
width: iconWidth, // Apply width directly
|
|
1595
|
+
} as React.CSSProperties
|
|
1596
|
+
}
|
|
1597
|
+
data-side="left-icon"
|
|
1598
|
+
{...props}
|
|
1599
|
+
>
|
|
1600
|
+
<div
|
|
1601
|
+
className="flex h-full w-full flex-col bg-sidebar border-r border-border" // Add a right border
|
|
1602
|
+
>
|
|
1603
|
+
{children}
|
|
1604
|
+
</div>
|
|
1605
|
+
</div>
|
|
1606
|
+
);
|
|
1607
|
+
});
|
|
1608
|
+
DSLeftIcon.displayName = "DSLeftIcon";
|
|
1609
|
+
|
|
1610
|
+
const DSRight1 = forwardRef<
|
|
1611
|
+
HTMLDivElement,
|
|
1612
|
+
React.ComponentProps<"div"> & {
|
|
1613
|
+
variant?: SidebarVariant;
|
|
1614
|
+
collapsible?: SidebarCollapsible;
|
|
1615
|
+
loadingUI?: boolean;
|
|
1616
|
+
}
|
|
1617
|
+
>(({ variant = "sidebar", collapsible = "offcanvas", className, children, loadingUI = true, ...props }, ref) => {
|
|
1618
|
+
const { isMobile, rightState, openMobileRight, setOpenMobileRight, openRight, sidebarWidth, setRightVariant, isIconRightActive, setIsIconRightActive, iconRightWidth, setIconRightWidth } = useDS();
|
|
1619
|
+
const navigation = useNavigation();
|
|
1620
|
+
const [hasInitialLoaded, setHasInitialLoaded] = useState(false);
|
|
1621
|
+
|
|
1622
|
+
useEffect(() => {
|
|
1623
|
+
setRightVariant(variant);
|
|
1624
|
+
}, [variant, setRightVariant]);
|
|
1625
|
+
|
|
1626
|
+
React.useEffect(() => {
|
|
1627
|
+
if (navigation.state === "idle" && !hasInitialLoaded) {
|
|
1628
|
+
setHasInitialLoaded(true);
|
|
1629
|
+
}
|
|
1630
|
+
}, [navigation.state, hasInitialLoaded]);
|
|
1631
|
+
|
|
1632
|
+
// Show loading only during initial load if loadingUI is enabled
|
|
1633
|
+
const showLoading = loadingUI && navigation.state === "loading" && !hasInitialLoaded;
|
|
1634
|
+
|
|
1635
|
+
if (collapsible === "none") {
|
|
1636
|
+
return (
|
|
1637
|
+
<div className={cn("flex h-full w-[--dual-sidebar-width] flex-col bg-sidebar text-sidebar-foreground", className)} ref={ref} {...props}>
|
|
1638
|
+
{showLoading ? <DSLoading /> : children}
|
|
1639
|
+
</div>
|
|
1640
|
+
);
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
if (isMobile) {
|
|
1644
|
+
return (
|
|
1645
|
+
<Sheet open={openMobileRight} onOpenChange={setOpenMobileRight} {...props}>
|
|
1646
|
+
<SheetContent
|
|
1647
|
+
data-dual-sidebar="sidebar"
|
|
1648
|
+
data-mobile="true"
|
|
1649
|
+
className="w-[--dual-sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden"
|
|
1650
|
+
style={{ "--dual-sidebar-width": DS_WIDTH_MOBILE } as React.CSSProperties}
|
|
1651
|
+
side="right"
|
|
1652
|
+
>
|
|
1653
|
+
<SheetHeader className="sr-only">
|
|
1654
|
+
<SheetTitle>Sidebar</SheetTitle>
|
|
1655
|
+
<SheetDescription>Displays the mobile sidebar.</SheetDescription>
|
|
1656
|
+
</SheetHeader>
|
|
1657
|
+
<div className="flex h-full w-full flex-col">{showLoading ? <DSLoading /> : children}</div>
|
|
1658
|
+
</SheetContent>
|
|
1659
|
+
</Sheet>
|
|
1660
|
+
);
|
|
1661
|
+
}
|
|
1662
|
+
const closedOffset = "8px";
|
|
1663
|
+
const iconOffset = isIconRightActive ? iconRightWidth : "0px";
|
|
1664
|
+
const baseClasses = `fixed inset-y-0 right-1 z-20 w-72 bg-sidebar rounded-[15px] flex flex-col transition-transform duration-300 shadow-2xl`;
|
|
1665
|
+
const transformClass = openRight ? "translate-x-0" : "translte-x-[calc(100%+4px)]"; // Hide completely + offset for parent margin/bordera
|
|
1666
|
+
|
|
1667
|
+
return (
|
|
1668
|
+
<div
|
|
1669
|
+
//className={cn(baseClasses, transformClass, !isIconRightActive && "right-0", className)}
|
|
1670
|
+
className={cn(
|
|
1671
|
+
dsVariants({ variant, side: "right" }),
|
|
1672
|
+
transformClass,
|
|
1673
|
+
!isIconRightActive && "right-0",
|
|
1674
|
+
className
|
|
1675
|
+
)}
|
|
1676
|
+
style={{
|
|
1677
|
+
width: sidebarWidth,
|
|
1678
|
+
"--dual-sidebar-width-icon": DS_WIDTH_ICON,
|
|
1679
|
+
right: isIconRightActive ? iconOffset : undefined,
|
|
1680
|
+
transform: openRight ? "translateX(0)" : `translateX(calc(100% + ${closedOffset}))`,
|
|
1681
|
+
}}
|
|
1682
|
+
{...props}
|
|
1683
|
+
>
|
|
1684
|
+
{showLoading ? <DSLoading /> : children}
|
|
1685
|
+
</div>
|
|
1686
|
+
);
|
|
1687
|
+
});
|
|
1688
|
+
const DSRight = forwardRef<
|
|
1689
|
+
HTMLDivElement,
|
|
1690
|
+
React.ComponentProps<"div"> & {
|
|
1691
|
+
variant?: SidebarVariant;
|
|
1692
|
+
collapsible?: SidebarCollapsible;
|
|
1693
|
+
loadingUI?: boolean;
|
|
1694
|
+
}
|
|
1695
|
+
>(({ variant = "sidebar", collapsible = "offcanvas", className, children, loadingUI = true, ...props }, ref) => {
|
|
1696
|
+
const { isMobile, rightState, openMobileRight, setOpenMobileRight, openRight, sidebarWidth, setRightVariant, isIconRightActive, setIsIconRightActive, iconRightWidth, setIconRightWidth } = useDS();
|
|
1697
|
+
const navigation = useNavigation();
|
|
1698
|
+
const [hasInitialLoaded, setHasInitialLoaded] = useState(false);
|
|
1699
|
+
|
|
1700
|
+
useEffect(() => {
|
|
1701
|
+
setRightVariant(variant);
|
|
1702
|
+
}, [variant, setRightVariant]);
|
|
1703
|
+
|
|
1704
|
+
React.useEffect(() => {
|
|
1705
|
+
if (navigation.state === "idle" && !hasInitialLoaded) {
|
|
1706
|
+
setHasInitialLoaded(true);
|
|
1707
|
+
}
|
|
1708
|
+
}, [navigation.state, hasInitialLoaded]);
|
|
1709
|
+
|
|
1710
|
+
const showLoading = loadingUI && navigation.state === "loading" && !hasInitialLoaded;
|
|
1711
|
+
|
|
1712
|
+
if (collapsible === "none") {
|
|
1713
|
+
return (
|
|
1714
|
+
<div className={cn("flex h-full w-[--dual-sidebar-width] flex-col bg-sidebar text-sidebar-foreground", className)} ref={ref} {...props}>
|
|
1715
|
+
{showLoading ? <DSLoading /> : children}
|
|
1716
|
+
</div>
|
|
1717
|
+
);
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
if (isMobile) {
|
|
1721
|
+
return (
|
|
1722
|
+
<Sheet open={openMobileRight} onOpenChange={setOpenMobileRight} {...props}>
|
|
1723
|
+
<SheetContent
|
|
1724
|
+
data-dual-sidebar="sidebar"
|
|
1725
|
+
data-mobile="true"
|
|
1726
|
+
className="w-[--dual-sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden"
|
|
1727
|
+
style={{ "--dual-sidebar-width": DS_WIDTH_MOBILE } as React.CSSProperties}
|
|
1728
|
+
side="right"
|
|
1729
|
+
>
|
|
1730
|
+
<SheetHeader className="sr-only">
|
|
1731
|
+
<SheetTitle>Sidebar</SheetTitle>
|
|
1732
|
+
<SheetDescription>Displays the mobile sidebar.</SheetDescription>
|
|
1733
|
+
</SheetHeader>
|
|
1734
|
+
<div className="flex h-full w-full flex-col">{showLoading ? <DSLoading /> : children}</div>
|
|
1735
|
+
</SheetContent>
|
|
1736
|
+
</Sheet>
|
|
1737
|
+
);
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
const closedOffset = "8px";
|
|
1741
|
+
const iconOffset = isIconRightActive ? iconRightWidth : "0px";
|
|
1742
|
+
const transformClass = openRight ? "translate-x-0" : "translate-x-[calc(100%+4px)]";
|
|
1743
|
+
const isInsetOrFloating = variant === "floating" || variant === "inset";
|
|
1744
|
+
|
|
1745
|
+
return (
|
|
1746
|
+
<div
|
|
1747
|
+
className={cn(
|
|
1748
|
+
dsVariants({ variant, side: "right" }),
|
|
1749
|
+
transformClass,
|
|
1750
|
+
!isIconRightActive && "right-0",
|
|
1751
|
+
isInsetOrFloating && "p-2",
|
|
1752
|
+
className
|
|
1753
|
+
)}
|
|
1754
|
+
style={{
|
|
1755
|
+
width: isInsetOrFloating && !openRight
|
|
1756
|
+
? `calc(${DS_WIDTH_ICON} + 1rem)` // 1rem = spacing(4) = 16px
|
|
1757
|
+
: sidebarWidth,
|
|
1758
|
+
"--dual-sidebar-width-icon": DS_WIDTH_ICON,
|
|
1759
|
+
right: isIconRightActive ? iconOffset : undefined,
|
|
1760
|
+
transform: openRight ? "translateX(0)" : `translateX(calc(100% + ${closedOffset}))`,
|
|
1761
|
+
}}
|
|
1762
|
+
{...props}
|
|
1763
|
+
>
|
|
1764
|
+
<div className={cn(
|
|
1765
|
+
"flex h-full w-full flex-col bg-sidebar",
|
|
1766
|
+
isInsetOrFloating && "rounded-lg border border-sidebar-border shadow-sm"
|
|
1767
|
+
)}>
|
|
1768
|
+
{showLoading ? <DSLoading /> : children}
|
|
1769
|
+
</div>
|
|
1770
|
+
</div>
|
|
1771
|
+
);
|
|
1772
|
+
});
|
|
1773
|
+
DSRight.displayName = "DSRight";
|
|
1774
|
+
|
|
1775
|
+
const DSRightIcon = forwardRef<
|
|
1776
|
+
HTMLDivElement,
|
|
1777
|
+
React.ComponentProps<"div"> & {
|
|
1778
|
+
// We assume the desired width is DS_WIDTH_ICON or similar constant
|
|
1779
|
+
iconWidth?: string;
|
|
1780
|
+
variant?: SidebarVariant;
|
|
1781
|
+
}
|
|
1782
|
+
>(({ iconWidth = DS_WIDTH_ICON, variant = "sidebar", className, children, ...props }, ref) => {
|
|
1783
|
+
// 1. Communicate its existence and width to the context (NEW STATE)
|
|
1784
|
+
const { setIsIconRightActive, setIconRightWidth, rightVariant } = useDS(); // Assumes new context setters
|
|
1785
|
+
|
|
1786
|
+
// Set context state on mount/unmount
|
|
1787
|
+
useEffect(() => {
|
|
1788
|
+
setIsIconRightActive(true);
|
|
1789
|
+
setIconRightWidth(iconWidth);
|
|
1790
|
+
return () => {
|
|
1791
|
+
setIsIconRightActive(false);
|
|
1792
|
+
setIconRightWidth("0px");
|
|
1793
|
+
};
|
|
1794
|
+
}, [iconWidth, setIsIconRightActive, setIconRightWidth]);
|
|
1795
|
+
|
|
1796
|
+
return (
|
|
1797
|
+
<div
|
|
1798
|
+
ref={ref}
|
|
1799
|
+
/**className={cn(
|
|
1800
|
+
// rightVariant === 'inset' ? 'bg-sidebar' : 'bg-background',
|
|
1801
|
+
"fixed inset-y-0 right-0 z-20 hidden h-svh flex-col md:flex",
|
|
1802
|
+
// Transition/width applied via style
|
|
1803
|
+
className
|
|
1804
|
+
)} */
|
|
1805
|
+
className={cn(
|
|
1806
|
+
iconDSVariants({ variant: rightVariant, side: "right" }),
|
|
1807
|
+
className
|
|
1808
|
+
)}
|
|
1809
|
+
style={
|
|
1810
|
+
{
|
|
1811
|
+
// Set the width for this specific component
|
|
1812
|
+
"--dual-sidebar-icon-width-fixed": iconWidth,
|
|
1813
|
+
width: iconWidth, // Apply width directly
|
|
1814
|
+
} as React.CSSProperties
|
|
1815
|
+
}
|
|
1816
|
+
data-side="right-icon"
|
|
1817
|
+
{...props}
|
|
1818
|
+
>
|
|
1819
|
+
<div
|
|
1820
|
+
className="flex h-full w-full flex-col bg-sidebar border-l border-border" // Add a right border
|
|
1821
|
+
>
|
|
1822
|
+
{children}
|
|
1823
|
+
</div>
|
|
1824
|
+
</div>
|
|
1825
|
+
);
|
|
1826
|
+
});
|
|
1827
|
+
DSRightIcon.displayName = "DSRightIcon";
|
|
1828
|
+
|
|
1829
|
+
|
|
1830
|
+
|
|
1831
|
+
function DSBurger({ opened, size = "md", color = "currentColor", onClick }: any) {
|
|
1832
|
+
const [internalOpened, setInternalOpened] = React.useState(false);
|
|
1833
|
+
const isOpened = opened !== undefined ? opened : internalOpened;
|
|
1834
|
+
|
|
1835
|
+
const sizeClasses = {
|
|
1836
|
+
sm: "w-4 h-4",
|
|
1837
|
+
md: "w-6 h-6",
|
|
1838
|
+
lg: "w-8 h-8",
|
|
1839
|
+
xl: "w-10 h-10",
|
|
1840
|
+
};
|
|
1841
|
+
|
|
1842
|
+
const lineHeight = {
|
|
1843
|
+
sm: "2px",
|
|
1844
|
+
md: "2px",
|
|
1845
|
+
lg: "3px",
|
|
1846
|
+
xl: "3px",
|
|
1847
|
+
};
|
|
1848
|
+
|
|
1849
|
+
const handleClick = () => {
|
|
1850
|
+
if (opened === undefined) {
|
|
1851
|
+
setInternalOpened(!internalOpened);
|
|
1852
|
+
}
|
|
1853
|
+
onClick?.();
|
|
1854
|
+
};
|
|
1855
|
+
|
|
1856
|
+
return (
|
|
1857
|
+
<button
|
|
1858
|
+
className={cn("relative cursor-pointer bg-transparent border-none p-0", sizeClasses[size])}
|
|
1859
|
+
style={{ color }}
|
|
1860
|
+
onClick={handleClick}
|
|
1861
|
+
aria-label={isOpened ? "Close menu" : "Open menu"}
|
|
1862
|
+
>
|
|
1863
|
+
<motion.span
|
|
1864
|
+
className="absolute left-0 block rounded-full bg-current"
|
|
1865
|
+
style={{
|
|
1866
|
+
width: "100%",
|
|
1867
|
+
height: lineHeight[size],
|
|
1868
|
+
top: "50%",
|
|
1869
|
+
left: 0,
|
|
1870
|
+
}}
|
|
1871
|
+
animate={{
|
|
1872
|
+
rotate: isOpened ? 45 : 0,
|
|
1873
|
+
y: isOpened ? "-50%" : "calc(-50% - 6px)",
|
|
1874
|
+
}}
|
|
1875
|
+
transition={{ duration: 0.3 }}
|
|
1876
|
+
/>
|
|
1877
|
+
<motion.span
|
|
1878
|
+
className="absolute left-0 top-1/2 block rounded-full bg-current"
|
|
1879
|
+
style={{
|
|
1880
|
+
width: "100%",
|
|
1881
|
+
height: lineHeight[size],
|
|
1882
|
+
y: "-50%",
|
|
1883
|
+
}}
|
|
1884
|
+
animate={{
|
|
1885
|
+
opacity: isOpened ? 0 : 1,
|
|
1886
|
+
}}
|
|
1887
|
+
transition={{ duration: 0.3 }}
|
|
1888
|
+
/>
|
|
1889
|
+
<motion.span
|
|
1890
|
+
className="absolute left-0 block rounded-full bg-current"
|
|
1891
|
+
style={{
|
|
1892
|
+
width: "100%",
|
|
1893
|
+
height: lineHeight[size],
|
|
1894
|
+
top: "50%",
|
|
1895
|
+
left: 0,
|
|
1896
|
+
}}
|
|
1897
|
+
animate={{
|
|
1898
|
+
rotate: isOpened ? -45 : 0,
|
|
1899
|
+
y: isOpened ? "-50%" : "calc(-50% + 6px)",
|
|
1900
|
+
}}
|
|
1901
|
+
transition={{ duration: 0.3 }}
|
|
1902
|
+
/>
|
|
1903
|
+
</button>
|
|
1904
|
+
);
|
|
1905
|
+
}
|
|
1906
|
+
|
|
1907
|
+
const DSTrigger = forwardRef<React.ElementRef<typeof Button>, React.ComponentProps<typeof Button> & { side?: "left" | "right" }>(({ side = "left", className, onClick, ...props }, ref) => {
|
|
1908
|
+
const { toggleLeft, toggleRight, openLeft, openRight } = useDS();
|
|
1909
|
+
const open = side === "left" ? openLeft : openRight;
|
|
1910
|
+
const handleClick = () => {
|
|
1911
|
+
if (side === "left") {
|
|
1912
|
+
toggleLeft();
|
|
1913
|
+
} else {
|
|
1914
|
+
toggleRight();
|
|
1915
|
+
}
|
|
1916
|
+
};
|
|
1917
|
+
return (
|
|
1918
|
+
<Button
|
|
1919
|
+
ref={ref}
|
|
1920
|
+
data-dual-sidebar="trigger"
|
|
1921
|
+
variant="ghost"
|
|
1922
|
+
size="icon"
|
|
1923
|
+
className={cn("h-7 w-7", className)}
|
|
1924
|
+
onClick={(event) => {
|
|
1925
|
+
onClick?.(event);
|
|
1926
|
+
handleClick();
|
|
1927
|
+
}}
|
|
1928
|
+
{...props}
|
|
1929
|
+
>
|
|
1930
|
+
<DSBurger opened={open} />
|
|
1931
|
+
<span className="sr-only">Toggle Sidebar</span>
|
|
1932
|
+
</Button>
|
|
1933
|
+
);
|
|
1934
|
+
});
|
|
1935
|
+
DSTrigger.displayName = "DSTrigger";
|
|
1936
|
+
|
|
1937
|
+
const DSLeftRail = forwardRef<HTMLButtonElement, React.ComponentProps<"button"> & { side?: SidebarSide }>(({ side = "left", className, ...props }, ref) => {
|
|
1938
|
+
const { toggleLeft } = useDS();
|
|
1939
|
+
|
|
1940
|
+
return (
|
|
1941
|
+
<button
|
|
1942
|
+
ref={ref}
|
|
1943
|
+
data-dual-sidebar="rail"
|
|
1944
|
+
aria-label="Toggle Sidebar"
|
|
1945
|
+
tabIndex={-1}
|
|
1946
|
+
// onClick={toggleLeft}
|
|
1947
|
+
onMouseEnter={toggleLeft}
|
|
1948
|
+
title="Toggle Sidebar"
|
|
1949
|
+
className={cn(
|
|
1950
|
+
"absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border -right-4 ",
|
|
1951
|
+
"cursor-w-resize",
|
|
1952
|
+
"group-data-[state=collapsed]:cursor-e-resize",
|
|
1953
|
+
"group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full group-data-[collapsible=offcanvas]:hover:bg-sidebar",
|
|
1954
|
+
"group-data-[collapsible=offcanvas]:-right-2",
|
|
1955
|
+
className
|
|
1956
|
+
)}
|
|
1957
|
+
{...props}
|
|
1958
|
+
/>
|
|
1959
|
+
);
|
|
1960
|
+
});
|
|
1961
|
+
DSLeftRail.displayName = "DSLeftRail";
|
|
1962
|
+
|
|
1963
|
+
const DSRightRail = forwardRef<HTMLButtonElement, React.ComponentProps<"button"> & { side?: "left" | "right" }>(({ side = "right", className, ...props }, ref) => {
|
|
1964
|
+
const { toggleRight } = useDS();
|
|
1965
|
+
|
|
1966
|
+
return (
|
|
1967
|
+
<button
|
|
1968
|
+
ref={ref}
|
|
1969
|
+
data-dual-sidebar="rail"
|
|
1970
|
+
aria-label="Toggle Sidebar"
|
|
1971
|
+
tabIndex={-1}
|
|
1972
|
+
onMouseEnter={toggleRight}
|
|
1973
|
+
title="Toggle Sidebar"
|
|
1974
|
+
className={cn(
|
|
1975
|
+
"absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border left-0 sm:flex",
|
|
1976
|
+
"cursor-e-resize",
|
|
1977
|
+
"group-data-[state=collapsed]:cursor-w-resize",
|
|
1978
|
+
"group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full group-data-[collapsible=offcanvas]:hover:bg-sidebar",
|
|
1979
|
+
"group-data-[data-collapsible=offcanvas]:-left-2",
|
|
1980
|
+
className
|
|
1981
|
+
)}
|
|
1982
|
+
{...props}
|
|
1983
|
+
/>
|
|
1984
|
+
);
|
|
1985
|
+
});
|
|
1986
|
+
DSRightRail.displayName = "DSRightRail";
|
|
1987
|
+
|
|
1988
|
+
const DSHeader = forwardRef<HTMLDivElement, React.ComponentProps<"div">>(({ className, ...props }, ref) => {
|
|
1989
|
+
const { variant } = useDS();
|
|
1990
|
+
return (
|
|
1991
|
+
<div ref={ref} data-dual-sidebar="header" className={cn(headerVariants({ variant }), className)} {...props} />
|
|
1992
|
+
);
|
|
1993
|
+
});
|
|
1994
|
+
DSHeader.displayName = "DSHeader";
|
|
1995
|
+
|
|
1996
|
+
const DSFooter = forwardRef<HTMLDivElement, React.ComponentProps<"div">>(({ className, ...props }, ref) => {
|
|
1997
|
+
const { variant } = useDS();
|
|
1998
|
+
return (
|
|
1999
|
+
<div ref={ref} data-dual-sidebar="footer" className={cn(footerVariants({ variant }), className)} {...props} />
|
|
2000
|
+
);
|
|
2001
|
+
});
|
|
2002
|
+
DSFooter.displayName = "DSFooter";
|
|
2003
|
+
|
|
2004
|
+
const DSSeparator = forwardRef<React.ElementRef<typeof Separator>, React.ComponentProps<typeof Separator>>(({ className, ...props }, ref) => {
|
|
2005
|
+
const { variant } = useDS();
|
|
2006
|
+
return <Separator ref={ref} data-dual-sidebar="separator" className={cn(separatorVariants({ variant, spacing }), className)} {...props} />;
|
|
2007
|
+
});
|
|
2008
|
+
DSSeparator.displayName = "DSSeparator";
|
|
2009
|
+
|
|
2010
|
+
const DSContent = forwardRef<HTMLDivElement, React.ComponentProps<"div">>(({ className, ...props }, ref) => {
|
|
2011
|
+
return (
|
|
2012
|
+
<div
|
|
2013
|
+
ref={ref}
|
|
2014
|
+
data-dual-sidebar="content"
|
|
2015
|
+
className={cn(
|
|
2016
|
+
"flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto overflow-x-hidden group-data-[collapsible=icon]:overflow-hidden",
|
|
2017
|
+
"group-data-[variant=floating]:bg-sidebar group-data-[variant=floating]:text-sidebar-foreground",
|
|
2018
|
+
"group-data-[variant=sidebar]:bg-sidebar group-data-[variant=sidebar]:text-sidebar-foreground",
|
|
2019
|
+
className
|
|
2020
|
+
)}
|
|
2021
|
+
{...props}
|
|
2022
|
+
/>
|
|
2023
|
+
);
|
|
2024
|
+
});
|
|
2025
|
+
DSContent.displayName = "DSContent";
|
|
2026
|
+
|
|
2027
|
+
const DSInput = forwardRef<React.ElementRef<typeof Input>, React.ComponentProps<typeof Input>>(({ className, ...props }, ref) => {
|
|
2028
|
+
return <Input ref={ref} data-dual-sidebar="input" className={cn("h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring", className)} {...props} />;
|
|
2029
|
+
});
|
|
2030
|
+
DSInput.displayName = "DSInput";
|
|
2031
|
+
|
|
2032
|
+
const DSGroup = forwardRef<HTMLDivElement, React.ComponentProps<"div">>(({ className, ...props }, ref) => {
|
|
2033
|
+
const { variant } = useDS();
|
|
2034
|
+
return <div ref={ref} data-dual-sidebar="group" className={cn(groupVariants({ variant }), className)} {...props} />;
|
|
2035
|
+
});
|
|
2036
|
+
DSGroup.displayName = "DSGroup";
|
|
2037
|
+
|
|
2038
|
+
const DSGroupLabel = forwardRef<HTMLDivElement, React.ComponentProps<"div"> & { asChild?: boolean }>(({ className, asChild = false, ...props }, ref) => {
|
|
2039
|
+
const { variant } = useDS();
|
|
2040
|
+
const Comp = asChild ? Slot : "div";
|
|
2041
|
+
return (
|
|
2042
|
+
<Comp ref={ref} data-dual-sidebar="group-label" className={cn(groupLabelVariants({ variant }), "group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0", className)} {...props} />
|
|
2043
|
+
);
|
|
2044
|
+
});
|
|
2045
|
+
DSGroupLabel.displayName = "DSGroupLabel";
|
|
2046
|
+
|
|
2047
|
+
const DSGroupAction = forwardRef<HTMLButtonElement, React.ComponentProps<"button"> & { asChild?: boolean }>(({ className, asChild = false, ...props }, ref) => {
|
|
2048
|
+
const Comp = asChild ? Slot : "button";
|
|
2049
|
+
|
|
2050
|
+
return (
|
|
2051
|
+
<Comp
|
|
2052
|
+
ref={ref}
|
|
2053
|
+
data-dual-sidebar="group-action"
|
|
2054
|
+
className={cn(
|
|
2055
|
+
"absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
|
|
2056
|
+
"after:absolute after:-inset-2 after:md:hidden",
|
|
2057
|
+
"group-data-[collapsible=icon]:hidden",
|
|
2058
|
+
className
|
|
2059
|
+
)}
|
|
2060
|
+
{...props}
|
|
2061
|
+
/>
|
|
2062
|
+
);
|
|
2063
|
+
});
|
|
2064
|
+
DSGroupAction.displayName = "DSGroupAction";
|
|
2065
|
+
|
|
2066
|
+
const DSGroupContent = forwardRef<HTMLDivElement, React.ComponentProps<"div">>(({ className, ...props }, ref) => <div ref={ref} data-dual-sidebar="group-content" className={cn("w-full text-sm", className)} {...props} />);
|
|
2067
|
+
DSGroupContent.displayName = "DSGroupContent";
|
|
2068
|
+
|
|
2069
|
+
const DSMenu = forwardRef<HTMLUListElement, React.ComponentProps<"ul">>(({ className, ...props }, ref) => <ul ref={ref} data-dual-sidebar="menu" className={cn("flex w-full min-w-0 flex-col gap-1", className)} {...props} />);
|
|
2070
|
+
DSMenu.displayName = "DSMenu";
|
|
2071
|
+
|
|
2072
|
+
const DSMenuItem = React.forwardRef<
|
|
2073
|
+
HTMLLIElement,
|
|
2074
|
+
React.ComponentProps<"li">
|
|
2075
|
+
>(({ className, ...props }, ref) => {
|
|
2076
|
+
const { variant } = useDS();
|
|
2077
|
+
return (
|
|
2078
|
+
<li
|
|
2079
|
+
ref={ref}
|
|
2080
|
+
data-dual-sidebar="menu-item"
|
|
2081
|
+
className={cn(menuItemVariants({ variant }), className)}
|
|
2082
|
+
{...props}
|
|
2083
|
+
/>
|
|
2084
|
+
);
|
|
2085
|
+
});
|
|
2086
|
+
|
|
2087
|
+
DSMenuItem.displayName = "DSMenuItem";
|
|
2088
|
+
|
|
2089
|
+
const DSMenuButton = forwardRef<
|
|
2090
|
+
HTMLButtonElement,
|
|
2091
|
+
React.ComponentProps<"button"> & {
|
|
2092
|
+
asChild?: boolean;
|
|
2093
|
+
isActive?: boolean;
|
|
2094
|
+
tooltip?: string | React.ComponentProps<typeof TooltipContent>;
|
|
2095
|
+
side: "left" | "right";
|
|
2096
|
+
} & VariantProps<typeof DSMenuButtonVariants>
|
|
2097
|
+
>(({ asChild = false, isActive = false, variant = "default", size = "default", tooltip, className, side, ...props }, ref) => {
|
|
2098
|
+
const Comp = asChild ? Slot : "button";
|
|
2099
|
+
const { isMobile, leftState, rightState } = useDS();
|
|
2100
|
+
|
|
2101
|
+
const button = <Comp ref={ref} data-dual-sidebar="menu-button" data-size={size} data-active={isActive} className={cn(DSMenuButtonVariants({ variant, size }), className)} {...props} />;
|
|
2102
|
+
|
|
2103
|
+
if (!tooltip) {
|
|
2104
|
+
return button;
|
|
2105
|
+
}
|
|
2106
|
+
|
|
2107
|
+
if (typeof tooltip === "string") {
|
|
2108
|
+
tooltip = {
|
|
2109
|
+
children: tooltip,
|
|
2110
|
+
};
|
|
2111
|
+
}
|
|
2112
|
+
|
|
2113
|
+
return (
|
|
2114
|
+
<DSMenuItem>
|
|
2115
|
+
<Tooltip>
|
|
2116
|
+
<TooltipTrigger asChild>{button}</TooltipTrigger>
|
|
2117
|
+
<TooltipContent side={side === "left" ? "right" : "left"} align="center" hidden={(leftState || rightState) !== "collapsed" || isMobile} {...tooltip} />
|
|
2118
|
+
</Tooltip>
|
|
2119
|
+
</DSMenuItem>
|
|
2120
|
+
);
|
|
2121
|
+
});
|
|
2122
|
+
DSMenuButton.displayName = "DSMenuButton";
|
|
2123
|
+
|
|
2124
|
+
const DSMenuAction = forwardRef<
|
|
2125
|
+
HTMLButtonElement,
|
|
2126
|
+
React.ComponentProps<"button"> & {
|
|
2127
|
+
asChild?: boolean;
|
|
2128
|
+
showOnHover?: boolean;
|
|
2129
|
+
}
|
|
2130
|
+
>(({ className, asChild = false, showOnHover = false, ...props }, ref) => {
|
|
2131
|
+
const Comp = asChild ? Slot : "button";
|
|
2132
|
+
|
|
2133
|
+
return (
|
|
2134
|
+
<Comp
|
|
2135
|
+
ref={ref}
|
|
2136
|
+
data-dual-sidebar="menu-action"
|
|
2137
|
+
className={cn(
|
|
2138
|
+
"absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0",
|
|
2139
|
+
"after:absolute after:-inset-2 after:md:hidden",
|
|
2140
|
+
"peer-data-[size=sm]/menu-button:top-1",
|
|
2141
|
+
"peer-data-[size=default]/menu-button:top-1.5",
|
|
2142
|
+
"peer-data-[size=lg]/menu-button:top-2.5",
|
|
2143
|
+
"group-data-[collapsible=icon]:hidden",
|
|
2144
|
+
showOnHover && "group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0",
|
|
2145
|
+
className
|
|
2146
|
+
)}
|
|
2147
|
+
{...props}
|
|
2148
|
+
/>
|
|
2149
|
+
);
|
|
2150
|
+
});
|
|
2151
|
+
DSMenuAction.displayName = "DSMenuAction";
|
|
2152
|
+
|
|
2153
|
+
const DSMenuBadge = forwardRef<HTMLDivElement, React.ComponentProps<"div">>(({ className, ...props }, ref) => (<div ref={ref} data-dual-sidebar="menu-badge" className={cn(menuBadgeVariants({ variant }), className)} {...props} />));
|
|
2154
|
+
DSMenuBadge.displayName = "DSMenuBadge";
|
|
2155
|
+
|
|
2156
|
+
const DSMenuSkeleton = forwardRef<
|
|
2157
|
+
HTMLDivElement,
|
|
2158
|
+
React.ComponentProps<"div"> & {
|
|
2159
|
+
showIcon?: boolean;
|
|
2160
|
+
}
|
|
2161
|
+
>(({ className, showIcon = false, ...props }, ref) => {
|
|
2162
|
+
const width = React.useMemo(() => {
|
|
2163
|
+
return `${Math.floor(Math.random() * 40) + 50}%`;
|
|
2164
|
+
}, []);
|
|
2165
|
+
|
|
2166
|
+
return (
|
|
2167
|
+
<div ref={ref} data-dual-sidebar="menu-skeleton" className={cn("flex h-8 items-center gap-2 rounded-md px-2", className)} {...props}>
|
|
2168
|
+
{showIcon && <Skeleton className="size-4 rounded-md" data-dual-sidebar="menu-skeleton-icon" />}
|
|
2169
|
+
<Skeleton
|
|
2170
|
+
className="h-4 max-w-[--skeleton-width] flex-1"
|
|
2171
|
+
data-dual-sidebar="menu-skeleton-text"
|
|
2172
|
+
style={
|
|
2173
|
+
{
|
|
2174
|
+
"--skeleton-width": width,
|
|
2175
|
+
} as React.CSSProperties
|
|
2176
|
+
}
|
|
2177
|
+
/>
|
|
2178
|
+
</div>
|
|
2179
|
+
);
|
|
2180
|
+
});
|
|
2181
|
+
DSMenuSkeleton.displayName = "DSMenuSkeleton";
|
|
2182
|
+
|
|
2183
|
+
interface DSMenuAnchorProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
2184
|
+
icon?: React.ReactNode;
|
|
2185
|
+
tooltip?: string;
|
|
2186
|
+
to: string;
|
|
2187
|
+
newTab?: boolean;
|
|
2188
|
+
variant?: "default" | "ghost" | "outline" | "soft" | "solid" | "minimal" | "bordered" | "pill";
|
|
2189
|
+
size?: "default" | "sm" | "lg" | "icon";
|
|
2190
|
+
}
|
|
2191
|
+
|
|
2192
|
+
interface DSMenuAnchorProps extends React.ComponentProps<"a"> {
|
|
2193
|
+
icon?: React.ReactNode;
|
|
2194
|
+
tooltip?: string | React.ComponentProps<typeof TooltipContent>;
|
|
2195
|
+
variant?: "default" | "ghost" | "outline" | "soft" | "solid" | "minimal" | "bordered" | "pill";
|
|
2196
|
+
size?: "default" | "sm" | "lg" | "icon";
|
|
2197
|
+
newTab?: boolean;
|
|
2198
|
+
}
|
|
2199
|
+
|
|
2200
|
+
const DSMenuAnchor = forwardRef<HTMLAnchorElement, DSMenuAnchorProps>(({
|
|
2201
|
+
className,
|
|
2202
|
+
icon,
|
|
2203
|
+
tooltip,
|
|
2204
|
+
children,
|
|
2205
|
+
to,
|
|
2206
|
+
newTab = true,
|
|
2207
|
+
variant = "default",
|
|
2208
|
+
size = "default",
|
|
2209
|
+
onClick,
|
|
2210
|
+
...props
|
|
2211
|
+
}, ref) => {
|
|
2212
|
+
const navigation = useNavigation();
|
|
2213
|
+
const location = useLocation();
|
|
2214
|
+
const { isMobile, leftState, rightState } = useDS();
|
|
2215
|
+
|
|
2216
|
+
const isActive = location.pathname === to;
|
|
2217
|
+
const isNavigatingToThisLink = navigation.state === "loading" && navigation.location?.href === to;
|
|
2218
|
+
|
|
2219
|
+
const anchorProps = newTab
|
|
2220
|
+
? {
|
|
2221
|
+
target: "_blank",
|
|
2222
|
+
rel: "noopener noreferrer",
|
|
2223
|
+
}
|
|
2224
|
+
: {};
|
|
2225
|
+
|
|
2226
|
+
const anchorContent = (
|
|
2227
|
+
<>
|
|
2228
|
+
{icon &&
|
|
2229
|
+
React.isValidElement(icon) &&
|
|
2230
|
+
React.cloneElement(icon, {
|
|
2231
|
+
className: cn("size-4 shrink-0", icon.props.className),
|
|
2232
|
+
})}
|
|
2233
|
+
<span className="flex-1 truncate">{children}</span>
|
|
2234
|
+
|
|
2235
|
+
{isNavigatingToThisLink && (
|
|
2236
|
+
<div className="ml-auto flex items-center">
|
|
2237
|
+
<div className="animate-spin rounded-full h-5 w-5 border-t-3 border-primary border-solid"></div>
|
|
2238
|
+
</div>
|
|
2239
|
+
)}
|
|
2240
|
+
</>
|
|
2241
|
+
);
|
|
2242
|
+
|
|
2243
|
+
const anchor = (
|
|
2244
|
+
<a
|
|
2245
|
+
ref={ref}
|
|
2246
|
+
href={to}
|
|
2247
|
+
{...anchorProps}
|
|
2248
|
+
onClick={onClick}
|
|
2249
|
+
className={cn(
|
|
2250
|
+
DSMenuButtonVariants({ variant, size, isActive }),
|
|
2251
|
+
isActive && "text-primary bg-muted font-medium",
|
|
2252
|
+
className
|
|
2253
|
+
)}
|
|
2254
|
+
{...props}
|
|
2255
|
+
>
|
|
2256
|
+
{anchorContent}
|
|
2257
|
+
</a>
|
|
2258
|
+
);
|
|
2259
|
+
|
|
2260
|
+
// If tooltip exists, wrap with Tooltip
|
|
2261
|
+
if (tooltip) {
|
|
2262
|
+
const tooltipProps = typeof tooltip === 'string' ? { children: tooltip } : tooltip;
|
|
2263
|
+
|
|
2264
|
+
return (
|
|
2265
|
+
<DSMenuItem>
|
|
2266
|
+
<Tooltip>
|
|
2267
|
+
<TooltipTrigger asChild>
|
|
2268
|
+
{anchor}
|
|
2269
|
+
</TooltipTrigger>
|
|
2270
|
+
<TooltipContent
|
|
2271
|
+
side="right"
|
|
2272
|
+
align="center"
|
|
2273
|
+
hidden={(leftState || rightState) !== "collapsed" || isMobile}
|
|
2274
|
+
{...tooltipProps}
|
|
2275
|
+
/>
|
|
2276
|
+
</Tooltip>
|
|
2277
|
+
</DSMenuItem>
|
|
2278
|
+
);
|
|
2279
|
+
}
|
|
2280
|
+
|
|
2281
|
+
// No tooltip
|
|
2282
|
+
return (
|
|
2283
|
+
<DSMenuItem>
|
|
2284
|
+
{anchor}
|
|
2285
|
+
</DSMenuItem>
|
|
2286
|
+
);
|
|
2287
|
+
});
|
|
2288
|
+
|
|
2289
|
+
DSMenuAnchor.displayName = "DSMenuAnchor";
|
|
2290
|
+
|
|
2291
|
+
interface DSMenuLinkProps extends React.ComponentProps<typeof NavLink> {
|
|
2292
|
+
icon?: React.ReactNode;
|
|
2293
|
+
tooltip?: string;
|
|
2294
|
+
variant?: "default" | "ghost" | "outline" | "soft" | "solid" | "minimal" | "bordered" | "pill";
|
|
2295
|
+
size?: "default" | "sm" | "lg" | "icon";
|
|
2296
|
+
}
|
|
2297
|
+
|
|
2298
|
+
const DSMenuLink = forwardRef<HTMLAnchorElement, DSMenuLinkProps>(({ className, icon, tooltip, children, to, variant = "default", size = "default", ...props }, ref) => {
|
|
2299
|
+
const navigation = useNavigation();
|
|
2300
|
+
const location = useLocation();
|
|
2301
|
+
const { isMobile, leftState, rightState } = useDS();
|
|
2302
|
+
|
|
2303
|
+
const isNavigatingToThisLink = navigation.state === 'loading' && navigation.location?.pathname === to;
|
|
2304
|
+
const isActive = location.pathname === to;
|
|
2305
|
+
|
|
2306
|
+
const linkContent = (
|
|
2307
|
+
<>
|
|
2308
|
+
{icon &&
|
|
2309
|
+
React.isValidElement(icon) &&
|
|
2310
|
+
React.cloneElement(icon, {
|
|
2311
|
+
className: cn("size-4 shrink-0", icon.props.className),
|
|
2312
|
+
})}
|
|
2313
|
+
<span className="flex-1 truncate">{children}</span>
|
|
2314
|
+
|
|
2315
|
+
{isNavigatingToThisLink && (
|
|
2316
|
+
<div className="ml-auto flex items-center">
|
|
2317
|
+
<div className="animate-spin rounded-full h-5 w-5 border-t-3 border-primary border-solid"></div>
|
|
2318
|
+
</div>
|
|
2319
|
+
)}
|
|
2320
|
+
</>
|
|
2321
|
+
);
|
|
2322
|
+
|
|
2323
|
+
const link = (
|
|
2324
|
+
<NavLink
|
|
2325
|
+
ref={ref}
|
|
2326
|
+
to={to}
|
|
2327
|
+
className={cn(
|
|
2328
|
+
DSMenuButtonVariants({ variant, size, isActive }),
|
|
2329
|
+
isActive && "text-primary bg-muted font-medium",
|
|
2330
|
+
className
|
|
2331
|
+
)}
|
|
2332
|
+
{...props}
|
|
2333
|
+
>
|
|
2334
|
+
{linkContent}
|
|
2335
|
+
</NavLink>
|
|
2336
|
+
);
|
|
2337
|
+
|
|
2338
|
+
// If tooltip exists, wrap with Tooltip
|
|
2339
|
+
if (tooltip) {
|
|
2340
|
+
const tooltipProps = typeof tooltip === 'string' ? { children: tooltip } : tooltip;
|
|
2341
|
+
|
|
2342
|
+
return (
|
|
2343
|
+
<DSMenuItem>
|
|
2344
|
+
<Tooltip>
|
|
2345
|
+
<TooltipTrigger asChild>
|
|
2346
|
+
{link}
|
|
2347
|
+
</TooltipTrigger>
|
|
2348
|
+
<TooltipContent
|
|
2349
|
+
side="right"
|
|
2350
|
+
align="center"
|
|
2351
|
+
hidden={(leftState || rightState) !== "collapsed" || isMobile}
|
|
2352
|
+
{...tooltipProps}
|
|
2353
|
+
/>
|
|
2354
|
+
</Tooltip>
|
|
2355
|
+
</DSMenuItem>
|
|
2356
|
+
);
|
|
2357
|
+
}
|
|
2358
|
+
|
|
2359
|
+
// No tooltip
|
|
2360
|
+
return (
|
|
2361
|
+
<DSMenuItem>
|
|
2362
|
+
{link}
|
|
2363
|
+
</DSMenuItem>
|
|
2364
|
+
);
|
|
2365
|
+
});
|
|
2366
|
+
DSMenuLink.displayName = "DSMenuLink";
|
|
2367
|
+
|
|
2368
|
+
const DSMenuSub = forwardRef<HTMLUListElement, React.ComponentProps<"ul">>(({ className, ...props }, ref) => (<ul ref={ref} data-dual-sidebar="menu-sub" className={cn("mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-border px-2.5 py-0.5", "group-data-[collapsible=icon]:hidden", className)} {...props} />));
|
|
2369
|
+
DSMenuSub.displayName = "DSMenuSub";
|
|
2370
|
+
|
|
2371
|
+
const DSMenuSubItem = forwardRef<HTMLLIElement, React.ComponentProps<"li">>(({ ...props }, ref) => <li ref={ref} {...props} />);
|
|
2372
|
+
DSMenuSubItem.displayName = "DSMenuSubItem";
|
|
2373
|
+
|
|
2374
|
+
const DSMenuSubButton = forwardRef<
|
|
2375
|
+
HTMLAnchorElement,
|
|
2376
|
+
React.ComponentProps<"a"> & {
|
|
2377
|
+
asChild?: boolean;
|
|
2378
|
+
size?: "sm" | "md";
|
|
2379
|
+
isActive?: boolean;
|
|
2380
|
+
}
|
|
2381
|
+
>(({ asChild = false, size = "md", isActive, className, ...props }, ref) => {
|
|
2382
|
+
const Comp = asChild ? Slot : "a";
|
|
2383
|
+
const { variant } = useDS();
|
|
2384
|
+
return (
|
|
2385
|
+
<Comp ref={ref} data-dual-sidebar="menu-sub-button" data-size={size} data-active={isActive} className={cn(menuSubButtonVariants({ variant, size }), className)} {...props} />
|
|
2386
|
+
);
|
|
2387
|
+
});
|
|
2388
|
+
DSMenuSubButton.displayName = "DSMenuSubButton";
|
|
2389
|
+
|
|
2390
|
+
const DSD = forwardRef<
|
|
2391
|
+
HTMLDivElement,
|
|
2392
|
+
React.ComponentProps<typeof Drawer> & {
|
|
2393
|
+
drawerHeight: string;
|
|
2394
|
+
variant?: "default" | "card" | "glass" | "elevated" | "bordered";
|
|
2395
|
+
}
|
|
2396
|
+
>(({ drawerHeight = "80vh", variant = 'default', direction = 'bottom', size = 'md', children, ...props }, ref) => {
|
|
2397
|
+
const { setTopHeight, dsdVariant, setDsdVariant, dsdDirection, setDsdDirection, dsdSize,
|
|
2398
|
+
setDsdSize } = useDS();
|
|
2399
|
+
|
|
2400
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
2401
|
+
|
|
2402
|
+
React.useEffect(() => {
|
|
2403
|
+
setDsdVariant(variant)
|
|
2404
|
+
setDsdDirection(direction)
|
|
2405
|
+
setDsdSize(size)
|
|
2406
|
+
setTopHeight(isOpen ? drawerHeight : "0px");
|
|
2407
|
+
return () => setTopHeight("0px");
|
|
2408
|
+
}, [isOpen, drawerHeight, setTopHeight]);
|
|
2409
|
+
|
|
2410
|
+
return (
|
|
2411
|
+
<Drawer ref={ref} placement="top" onOpenChange={setIsOpen} {...props}>
|
|
2412
|
+
{children}
|
|
2413
|
+
</Drawer>
|
|
2414
|
+
);
|
|
2415
|
+
});
|
|
2416
|
+
DSD.displayName = "DSD";
|
|
2417
|
+
function DSDTrigger({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {
|
|
2418
|
+
return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />;
|
|
2419
|
+
}
|
|
2420
|
+
function DSDPortal({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Portal>) {
|
|
2421
|
+
return <DrawerPrimitive.Portal data-slot="drawer-portal" {...props} />;
|
|
2422
|
+
}
|
|
2423
|
+
function DSDClose({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Close>) {
|
|
2424
|
+
return <DrawerPrimitive.Close data-slot="drawer-close" {...props} />;
|
|
2425
|
+
}
|
|
2426
|
+
function DSDOverlay({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {
|
|
2427
|
+
return (
|
|
2428
|
+
<DrawerPrimitive.Overlay data-slot="drawer-overlay" className={cn("data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50", className)} {...props} />
|
|
2429
|
+
);
|
|
2430
|
+
}
|
|
2431
|
+
function DSDContent({ className, children, ...props }: React.ComponentProps<typeof DrawerPrimitive.Content>) {
|
|
2432
|
+
const { setTopHeight, dsdVariant, setDsdVariant, dsdDirection, setDsdDirection, dsdSize, setDsdSize } = useDS();
|
|
2433
|
+
const variant = dsdVariant
|
|
2434
|
+
const direction = dsdDirection
|
|
2435
|
+
const size = dsdSize
|
|
2436
|
+
return (
|
|
2437
|
+
<DSDPortal data-slot="drawer-portal">
|
|
2438
|
+
<DSDOverlay />
|
|
2439
|
+
<DrawerPrimitive.Content data-slot="drawer-content" className={cn(drawerVariants({ direction, size, variant }), className)} {...props} >
|
|
2440
|
+
<div className="bg-muted mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full group-data-[vaul-drawer-direction=bottom]/drawer-content:block" />
|
|
2441
|
+
{children}
|
|
2442
|
+
</DrawerPrimitive.Content>
|
|
2443
|
+
</DSDPortal>
|
|
2444
|
+
);
|
|
2445
|
+
}
|
|
2446
|
+
function DSDHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
2447
|
+
return (
|
|
2448
|
+
<div
|
|
2449
|
+
data-slot="drawer-header"
|
|
2450
|
+
className={cn("flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-1.5 md:text-left", className)}
|
|
2451
|
+
{...props}
|
|
2452
|
+
/>
|
|
2453
|
+
);
|
|
2454
|
+
}
|
|
2455
|
+
function DSDFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
2456
|
+
return <div data-slot="drawer-footer" className={cn("mt-auto flex flex-col gap-2 p-4", className)} {...props} />;
|
|
2457
|
+
}
|
|
2458
|
+
function DSDTitle({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Title>) {
|
|
2459
|
+
return <DrawerPrimitive.Title data-slot="drawer-title" className={cn("text-foreground font-semibold", className)} {...props} />;
|
|
2460
|
+
}
|
|
2461
|
+
function DSDDescription({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Description>) {
|
|
2462
|
+
return <DrawerPrimitive.Description data-slot="drawer-description" className={cn("text-muted-foreground text-sm", className)} {...props} />;
|
|
2463
|
+
}
|
|
2464
|
+
function DSLoading({
|
|
2465
|
+
variant = "default",
|
|
2466
|
+
size = "default"
|
|
2467
|
+
}: {
|
|
2468
|
+
variant?: "default" | "minimal" | "card" | "centered";
|
|
2469
|
+
size?: "default" | "sm" | "md" | "lg" | "full";
|
|
2470
|
+
}) {
|
|
2471
|
+
const isMobile = useIsMobile();
|
|
2472
|
+
const width = isMobile ? DS_WIDTH_MOBILE : DS_WIDTH;
|
|
2473
|
+
return (
|
|
2474
|
+
<div className={cn(loadingVariants({ variant, size }), width)}>
|
|
2475
|
+
{/**<div className={cn("flex flex-col items-center justify-center text-center p-8 w-[256px] min-h-[400px] h-screen bg-gradient-to-b from-background to-muted/20", width)}> */}
|
|
2476
|
+
<div className="space-y-3">
|
|
2477
|
+
<h3 className="text-lg font-semibold text-foreground animate-pulse">Loading Sidebar</h3>
|
|
2478
|
+
<p className="text-sm text-muted-foreground/80 animate-pulse delay-150">Please wait while the content loads...</p>
|
|
2479
|
+
</div>
|
|
2480
|
+
<div className="mb-6">
|
|
2481
|
+
<LoaderX variant='3' />
|
|
2482
|
+
</div>
|
|
2483
|
+
{/** <div className="w-full mt-8 space-y-3">
|
|
2484
|
+
<div className="h-3 bg-muted rounded-full animate-pulse"></div>
|
|
2485
|
+
<div className="h-3 bg-muted rounded-full animate-pulse delay-75 w-3/4"></div>
|
|
2486
|
+
<div className="h-3 bg-muted rounded-full animate-pulse delay-150 w-1/2"></div>
|
|
2487
|
+
</div>
|
|
2488
|
+
|
|
2489
|
+
<div className="flex space-x-1 mt-6">
|
|
2490
|
+
<div className="w-2 h-2 bg-primary/60 rounded-full animate-bounce"></div>
|
|
2491
|
+
<div className="w-2 h-2 bg-primary/60 rounded-full animate-bounce delay-100"></div>
|
|
2492
|
+
<div className="w-2 h-2 bg-primary/60 rounded-full animate-bounce delay-200"></div>
|
|
2493
|
+
</div> */}
|
|
2494
|
+
</div>
|
|
2495
|
+
);
|
|
2496
|
+
}
|
|
2497
|
+
const colorThemes = {
|
|
2498
|
+
neutral: {
|
|
2499
|
+
v4: {
|
|
2500
|
+
root: {
|
|
2501
|
+
"--radius": "0.65rem",
|
|
2502
|
+
"--background": "oklch(1 0 0)",
|
|
2503
|
+
"--foreground": "oklch(0.145 0 0)",
|
|
2504
|
+
"--card": "oklch(1 0 0)",
|
|
2505
|
+
"--card-foreground": "oklch(0.145 0 0)",
|
|
2506
|
+
"--popover": "oklch(1 0 0)",
|
|
2507
|
+
"--popover-foreground": "oklch(0.145 0 0)",
|
|
2508
|
+
"--primary": "oklch(0.205 0 0)",
|
|
2509
|
+
"--primary-foreground": "oklch(0.985 0 0)",
|
|
2510
|
+
"--secondary": "oklch(0.97 0 0)",
|
|
2511
|
+
"--secondary-foreground": "oklch(0.205 0 0)",
|
|
2512
|
+
"--muted": "oklch(0.97 0 0)",
|
|
2513
|
+
"--muted-foreground": "oklch(0.556 0 0)",
|
|
2514
|
+
"--accent": "oklch(0.97 0 0)",
|
|
2515
|
+
"--accent-foreground": "oklch(0.205 0 0)",
|
|
2516
|
+
"--destructive": "oklch(0.577 0.245 27.325)",
|
|
2517
|
+
"--border": "oklch(0.922 0 0)",
|
|
2518
|
+
"--input": "oklch(0.922 0 0)",
|
|
2519
|
+
"--ring": "oklch(0.708 0 0)",
|
|
2520
|
+
"--chart-1": "oklch(0.646 0.222 41.116)",
|
|
2521
|
+
"--chart-2": "oklch(0.6 0.118 184.704)",
|
|
2522
|
+
"--chart-3": "oklch(0.398 0.07 227.392)",
|
|
2523
|
+
"--chart-4": "oklch(0.828 0.189 84.429)",
|
|
2524
|
+
"--chart-5": "oklch(0.769 0.188 70.08)",
|
|
2525
|
+
"--sidebar": "oklch(0.985 0 0)",
|
|
2526
|
+
"--sidebar-foreground": "oklch(0.145 0 0)",
|
|
2527
|
+
"--sidebar-primary": "oklch(0.205 0 0)",
|
|
2528
|
+
"--sidebar-primary-foreground": "oklch(0.985 0 0)",
|
|
2529
|
+
"--sidebar-accent": "oklch(0.97 0 0)",
|
|
2530
|
+
"--sidebar-accent-foreground": "oklch(0.205 0 0)",
|
|
2531
|
+
"--sidebar-border": "oklch(0.922 0 0)",
|
|
2532
|
+
"--sidebar-ring": "oklch(0.708 0 0)",
|
|
2533
|
+
},
|
|
2534
|
+
dark: {
|
|
2535
|
+
"--background": "oklch(0.145 0 0)",
|
|
2536
|
+
"--foreground": "oklch(0.985 0 0)",
|
|
2537
|
+
"--card": "oklch(0.205 0 0)",
|
|
2538
|
+
"--card-foreground": "oklch(0.985 0 0)",
|
|
2539
|
+
"--popover": "oklch(0.205 0 0)",
|
|
2540
|
+
"--popover-foreground": "oklch(0.985 0 0)",
|
|
2541
|
+
"--primary": "oklch(0.922 0 0)",
|
|
2542
|
+
"--primary-foreground": "oklch(0.205 0 0)",
|
|
2543
|
+
"--secondary": "oklch(0.269 0 0)",
|
|
2544
|
+
"--secondary-foreground": "oklch(0.985 0 0)",
|
|
2545
|
+
"--muted": "oklch(0.269 0 0)",
|
|
2546
|
+
"--muted-foreground": "oklch(0.708 0 0)",
|
|
2547
|
+
"--accent": "oklch(0.269 0 0)",
|
|
2548
|
+
"--accent-foreground": "oklch(0.985 0 0)",
|
|
2549
|
+
"--destructive": "oklch(0.704 0.191 22.216)",
|
|
2550
|
+
"--border": "oklch(1 0 0 / 10%)",
|
|
2551
|
+
"--input": "oklch(1 0 0 / 15%)",
|
|
2552
|
+
"--ring": "oklch(0.556 0 0)",
|
|
2553
|
+
"--chart-1": "oklch(0.488 0.243 264.376)",
|
|
2554
|
+
"--chart-2": "oklch(0.696 0.17 162.48)",
|
|
2555
|
+
"--chart-3": "oklch(0.769 0.188 70.08)",
|
|
2556
|
+
"--chart-4": "oklch(0.627 0.265 303.9)",
|
|
2557
|
+
"--chart-5": "oklch(0.645 0.246 16.439)",
|
|
2558
|
+
"--sidebar": "oklch(0.205 0 0)",
|
|
2559
|
+
"--sidebar-foreground": "oklch(0.985 0 0)",
|
|
2560
|
+
"--sidebar-primary": "oklch(0.488 0.243 264.376)",
|
|
2561
|
+
"--sidebar-primary-foreground": "oklch(0.985 0 0)",
|
|
2562
|
+
"--sidebar-accent": "oklch(0.269 0 0)",
|
|
2563
|
+
"--sidebar-accent-foreground": "oklch(0.985 0 0)",
|
|
2564
|
+
"--sidebar-border": "oklch(1 0 0 / 10%)",
|
|
2565
|
+
"--sidebar-ring": "oklch(0.556 0 0)",
|
|
2566
|
+
},
|
|
2567
|
+
},
|
|
2568
|
+
v3: {
|
|
2569
|
+
root: {
|
|
2570
|
+
"--background": "0 0% 100%",
|
|
2571
|
+
"--foreground": "0 0% 3.9%",
|
|
2572
|
+
"--card": "0 0% 100%",
|
|
2573
|
+
"--card-foreground": "0 0% 3.9%",
|
|
2574
|
+
"--popover": "0 0% 100%",
|
|
2575
|
+
"--popover-foreground": "0 0% 3.9%",
|
|
2576
|
+
"--primary": "0 0% 9%",
|
|
2577
|
+
"--primary-foreground": "0 0% 98%",
|
|
2578
|
+
"--secondary": "0 0% 96.1%",
|
|
2579
|
+
"--secondary-foreground": "0 0% 9%",
|
|
2580
|
+
"--muted": "0 0% 96.1%",
|
|
2581
|
+
"--muted-foreground": "0 0% 45.1%",
|
|
2582
|
+
"--accent": "0 0% 96.1%",
|
|
2583
|
+
"--accent-foreground": "0 0% 9%",
|
|
2584
|
+
"--destructive": "0 84.2% 60.2%",
|
|
2585
|
+
"--destructive-foreground": "0 0% 98%",
|
|
2586
|
+
"--border": "0 0% 89.8%",
|
|
2587
|
+
"--input": "0 0% 89.8%",
|
|
2588
|
+
"--ring": "0 0% 3.9%",
|
|
2589
|
+
"--radius": "0.5rem",
|
|
2590
|
+
"--chart-1": "12 76% 61%",
|
|
2591
|
+
"--chart-2": "173 58% 39%",
|
|
2592
|
+
"--chart-3": "197 37% 24%",
|
|
2593
|
+
"--chart-4": "43 74% 66%",
|
|
2594
|
+
"--chart-5": "27 87% 67%",
|
|
2595
|
+
"--sidebar": "221 39% 11%",
|
|
2596
|
+
"--sidebar-foreground": "0 0% 98%",
|
|
2597
|
+
"--sidebar-primary": "217.2 91.2% 59.8%",
|
|
2598
|
+
"--special": "227 21% 8%",
|
|
2599
|
+
"--special-muted-background": "240 10% 4%",
|
|
2600
|
+
"--special-border": "240 4% 16%",
|
|
2601
|
+
"--special-foreground": "240 5% 84%",
|
|
2602
|
+
"--special-muted-foreground": "240 4% 46%",
|
|
2603
|
+
},
|
|
2604
|
+
dark: {
|
|
2605
|
+
"--background": "0 0% 3.9%",
|
|
2606
|
+
"--foreground": "0 0% 98%",
|
|
2607
|
+
"--card": "0 0% 3.9%",
|
|
2608
|
+
"--card-foreground": "0 0% 98%",
|
|
2609
|
+
"--popover": "0 0% 3.9%",
|
|
2610
|
+
"--popover-foreground": "0 0% 98%",
|
|
2611
|
+
"--primary": "0 0% 98%",
|
|
2612
|
+
"--primary-foreground": "0 0% 9%",
|
|
2613
|
+
"--secondary": "0 0% 14.9%",
|
|
2614
|
+
"--secondary-foreground": "0 0% 98%",
|
|
2615
|
+
"--muted": "0 0% 14.9%",
|
|
2616
|
+
"--muted-foreground": "0 0% 63.9%",
|
|
2617
|
+
"--accent": "0 0% 14.9%",
|
|
2618
|
+
"--accent-foreground": "0 0% 98%",
|
|
2619
|
+
"--destructive": "0 62.8% 30.6%",
|
|
2620
|
+
"--destructive-foreground": "0 0% 98%",
|
|
2621
|
+
"--border": "0 0% 14.9%",
|
|
2622
|
+
"--input": "0 0% 14.9%",
|
|
2623
|
+
"--ring": "0 0% 83.1%",
|
|
2624
|
+
"--chart-1": "220 70% 50%",
|
|
2625
|
+
"--chart-2": "160 60% 45%",
|
|
2626
|
+
"--chart-3": "30 80% 55%",
|
|
2627
|
+
"--chart-4": "280 65% 60%",
|
|
2628
|
+
"--chart-5": "340 75% 55%",
|
|
2629
|
+
"--sidebar": "221 39% 11%",
|
|
2630
|
+
"--sidebar-foreground": "0 0% 98%",
|
|
2631
|
+
"--sidebar-primary": "217.2 91.2% 59.8%",
|
|
2632
|
+
"--special": "227 21% 8%",
|
|
2633
|
+
"--special-muted-background": "240 10% 4%",
|
|
2634
|
+
"--special-border": "240 4% 16%",
|
|
2635
|
+
"--special-foreground": "240 5% 84%",
|
|
2636
|
+
"--special-muted-foreground": "240 4% 46%",
|
|
2637
|
+
},
|
|
2638
|
+
},
|
|
2639
|
+
},
|
|
2640
|
+
red: {
|
|
2641
|
+
v4: {
|
|
2642
|
+
root: {
|
|
2643
|
+
"--radius": "0.65rem",
|
|
2644
|
+
"--background": "oklch(1 0 0)",
|
|
2645
|
+
"--foreground": "oklch(0.141 0.005 285.823)",
|
|
2646
|
+
"--card": "oklch(1 0 0)",
|
|
2647
|
+
"--card-foreground": "oklch(0.141 0.005 285.823)",
|
|
2648
|
+
"--popover": "oklch(1 0 0)",
|
|
2649
|
+
"--popover-foreground": "oklch(0.141 0.005 285.823)",
|
|
2650
|
+
"--primary": "oklch(0.637 0.237 25.331)",
|
|
2651
|
+
"--primary-foreground": "oklch(0.971 0.013 17.38)",
|
|
2652
|
+
"--secondary": "oklch(0.967 0.001 286.375)",
|
|
2653
|
+
"--secondary-foreground": "oklch(0.21 0.006 285.885)",
|
|
2654
|
+
"--muted": "oklch(0.967 0.001 286.375)",
|
|
2655
|
+
"--muted-foreground": "oklch(0.552 0.016 285.938)",
|
|
2656
|
+
"--accent": "oklch(0.967 0.001 286.375)",
|
|
2657
|
+
"--accent-foreground": "oklch(0.21 0.006 285.885)",
|
|
2658
|
+
"--destructive": "oklch(0.577 0.245 27.325)",
|
|
2659
|
+
"--border": "oklch(0.92 0.004 286.32)",
|
|
2660
|
+
"--input": "oklch(0.92 0.004 286.32)",
|
|
2661
|
+
"--ring": "oklch(0.637 0.237 25.331)",
|
|
2662
|
+
"--chart-1": "oklch(0.646 0.222 41.116)",
|
|
2663
|
+
"--chart-2": "oklch(0.6 0.118 184.704)",
|
|
2664
|
+
"--chart-3": "oklch(0.398 0.07 227.392)",
|
|
2665
|
+
"--chart-4": "oklch(0.828 0.189 84.429)",
|
|
2666
|
+
"--chart-5": "oklch(0.769 0.188 70.08)",
|
|
2667
|
+
"--sidebar": "oklch(0.985 0 0)",
|
|
2668
|
+
"--sidebar-foreground": "oklch(0.141 0.005 285.823)",
|
|
2669
|
+
"--sidebar-primary": "oklch(0.637 0.237 25.331)",
|
|
2670
|
+
"--sidebar-primary-foreground": "oklch(0.971 0.013 17.38)",
|
|
2671
|
+
"--sidebar-accent": "oklch(0.967 0.001 286.375)",
|
|
2672
|
+
"--sidebar-accent-foreground": "oklch(0.21 0.006 285.885)",
|
|
2673
|
+
"--sidebar-border": "oklch(0.92 0.004 286.32)",
|
|
2674
|
+
"--sidebar-ring": "oklch(0.637 0.237 25.331)",
|
|
2675
|
+
},
|
|
2676
|
+
dark: {
|
|
2677
|
+
"--background": "oklch(0.141 0.005 285.823)",
|
|
2678
|
+
"--foreground": "oklch(0.985 0 0)",
|
|
2679
|
+
"--card": "oklch(0.21 0.006 285.885)",
|
|
2680
|
+
"--card-foreground": "oklch(0.985 0 0)",
|
|
2681
|
+
"--popover": "oklch(0.21 0.006 285.885)",
|
|
2682
|
+
"--popover-foreground": "oklch(0.985 0 0)",
|
|
2683
|
+
"--primary": "oklch(0.637 0.237 25.331)",
|
|
2684
|
+
"--primary-foreground": "oklch(0.971 0.013 17.38)",
|
|
2685
|
+
"--secondary": "oklch(0.274 0.006 286.033)",
|
|
2686
|
+
"--secondary-foreground": "oklch(0.985 0 0)",
|
|
2687
|
+
"--muted": "oklch(0.274 0.006 286.033)",
|
|
2688
|
+
"--muted-foreground": "oklch(0.705 0.015 286.067)",
|
|
2689
|
+
"--accent": "oklch(0.274 0.006 286.033)",
|
|
2690
|
+
"--accent-foreground": "oklch(0.985 0 0)",
|
|
2691
|
+
"--destructive": "oklch(0.704 0.191 22.216)",
|
|
2692
|
+
"--border": "oklch(1 0 0 / 10%)",
|
|
2693
|
+
"--input": "oklch(1 0 0 / 15%)",
|
|
2694
|
+
"--ring": "oklch(0.637 0.237 25.331)",
|
|
2695
|
+
"--chart-1": "oklch(0.488 0.243 264.376)",
|
|
2696
|
+
"--chart-2": "oklch(0.696 0.17 162.48)",
|
|
2697
|
+
"--chart-3": "oklch(0.769 0.188 70.08)",
|
|
2698
|
+
"--chart-4": "oklch(0.627 0.265 303.9)",
|
|
2699
|
+
"--chart-5": "oklch(0.645 0.246 16.439)",
|
|
2700
|
+
"--sidebar": "oklch(0.21 0.006 285.885)",
|
|
2701
|
+
"--sidebar-foreground": "oklch(0.985 0 0)",
|
|
2702
|
+
"--sidebar-primary": "oklch(0.637 0.237 25.331)",
|
|
2703
|
+
"--sidebar-primary-foreground": "oklch(0.971 0.013 17.38)",
|
|
2704
|
+
"--sidebar-accent": "oklch(0.274 0.006 286.033)",
|
|
2705
|
+
"--sidebar-accent-foreground": "oklch(0.985 0 0)",
|
|
2706
|
+
"--sidebar-border": "oklch(1 0 0 / 10%)",
|
|
2707
|
+
"--sidebar-ring": "oklch(0.637 0.237 25.331)",
|
|
2708
|
+
},
|
|
2709
|
+
},
|
|
2710
|
+
v3: {
|
|
2711
|
+
root: {
|
|
2712
|
+
"--background": "0 0% 100%",
|
|
2713
|
+
"--foreground": "0 0% 3.9%",
|
|
2714
|
+
"--card": "0 0% 100%",
|
|
2715
|
+
"--card-foreground": "0 0% 3.9%",
|
|
2716
|
+
"--popover": "0 0% 100%",
|
|
2717
|
+
"--popover-foreground": "0 0% 3.9%",
|
|
2718
|
+
"--primary": "0 72.2% 50.6%",
|
|
2719
|
+
"--primary-foreground": "0 85.7% 97.3%",
|
|
2720
|
+
"--secondary": "0 0% 96.1%",
|
|
2721
|
+
"--secondary-foreground": "0 0% 9%",
|
|
2722
|
+
"--muted": "0 0% 96.1%",
|
|
2723
|
+
"--muted-foreground": "0 0% 45.1%",
|
|
2724
|
+
"--accent": "0 0% 96.1%",
|
|
2725
|
+
"--accent-foreground": "0 0% 9%",
|
|
2726
|
+
"--destructive": "0 84.2% 60.2%",
|
|
2727
|
+
"--destructive-foreground": "0 0% 98%",
|
|
2728
|
+
"--border": "0 0% 89.8%",
|
|
2729
|
+
"--input": "0 0% 89.8%",
|
|
2730
|
+
"--ring": "0 72.2% 50.6%",
|
|
2731
|
+
"--radius": "0.5rem",
|
|
2732
|
+
"--chart-1": "12 76% 61%",
|
|
2733
|
+
"--chart-2": "173 58% 39%",
|
|
2734
|
+
"--chart-3": "197 37% 24%",
|
|
2735
|
+
"--chart-4": "43 74% 66%",
|
|
2736
|
+
"--chart-5": "27 87% 67%",
|
|
2737
|
+
"--sidebar": "221 39% 11%",
|
|
2738
|
+
"--sidebar-foreground": "0 0% 98%",
|
|
2739
|
+
"--sidebar-primary": "217.2 91.2% 59.8%",
|
|
2740
|
+
"--special": "227 21% 8%",
|
|
2741
|
+
"--special-muted-background": "240 10% 4%",
|
|
2742
|
+
"--special-border": "240 4% 16%",
|
|
2743
|
+
"--special-foreground": "240 5% 84%",
|
|
2744
|
+
"--special-muted-foreground": "240 4% 46%",
|
|
2745
|
+
},
|
|
2746
|
+
dark: {
|
|
2747
|
+
"--background": "0 0% 3.9%",
|
|
2748
|
+
"--foreground": "0 0% 98%",
|
|
2749
|
+
"--card": "0 0% 3.9%",
|
|
2750
|
+
"--card-foreground": "0 0% 98%",
|
|
2751
|
+
"--popover": "0 0% 3.9%",
|
|
2752
|
+
"--popover-foreground": "0 0% 98%",
|
|
2753
|
+
"--primary": "0 72.2% 50.6%",
|
|
2754
|
+
"--primary-foreground": "0 85.7% 97.3%",
|
|
2755
|
+
"--secondary": "0 0% 14.9%",
|
|
2756
|
+
"--secondary-foreground": "0 0% 98%",
|
|
2757
|
+
"--muted": "0 0% 14.9%",
|
|
2758
|
+
"--muted-foreground": "0 0% 63.9%",
|
|
2759
|
+
"--accent": "0 0% 14.9%",
|
|
2760
|
+
"--accent-foreground": "0 0% 98%",
|
|
2761
|
+
"--destructive": "0 62.8% 30.6%",
|
|
2762
|
+
"--destructive-foreground": "0 0% 98%",
|
|
2763
|
+
"--border": "0 0% 14.9%",
|
|
2764
|
+
"--input": "0 0% 14.9%",
|
|
2765
|
+
"--ring": "0 72.2% 50.6%",
|
|
2766
|
+
"--chart-1": "220 70% 50%",
|
|
2767
|
+
"--chart-2": "160 60% 45%",
|
|
2768
|
+
"--chart-3": "30 80% 55%",
|
|
2769
|
+
"--chart-4": "280 65% 60%",
|
|
2770
|
+
"--chart-5": "340 75% 55%",
|
|
2771
|
+
"--sidebar": "221 39% 11%",
|
|
2772
|
+
"--sidebar-foreground": "0 0% 98%",
|
|
2773
|
+
"--sidebar-primary": "217.2 91.2% 59.8%",
|
|
2774
|
+
"--special": "227 21% 8%",
|
|
2775
|
+
"--special-muted-background": "240 10% 4%",
|
|
2776
|
+
"--special-border": "240 4% 16%",
|
|
2777
|
+
"--special-foreground": "240 5% 84%",
|
|
2778
|
+
"--special-muted-foreground": "240 4% 46%",
|
|
2779
|
+
},
|
|
2780
|
+
},
|
|
2781
|
+
},
|
|
2782
|
+
rose: {
|
|
2783
|
+
v4: {
|
|
2784
|
+
root: {
|
|
2785
|
+
"--radius": "0.65rem",
|
|
2786
|
+
"--background": "oklch(1 0 0)",
|
|
2787
|
+
"--foreground": "oklch(0.141 0.005 285.823)",
|
|
2788
|
+
"--card": "oklch(1 0 0)",
|
|
2789
|
+
"--card-foreground": "oklch(0.141 0.005 285.823)",
|
|
2790
|
+
"--popover": "oklch(1 0 0)",
|
|
2791
|
+
"--popover-foreground": "oklch(0.141 0.005 285.823)",
|
|
2792
|
+
"--primary": "oklch(0.645 0.246 16.439)",
|
|
2793
|
+
"--primary-foreground": "oklch(0.969 0.015 12.422)",
|
|
2794
|
+
"--secondary": "oklch(0.967 0.001 286.375)",
|
|
2795
|
+
"--secondary-foreground": "oklch(0.21 0.006 285.885)",
|
|
2796
|
+
"--muted": "oklch(0.967 0.001 286.375)",
|
|
2797
|
+
"--muted-foreground": "oklch(0.552 0.016 285.938)",
|
|
2798
|
+
"--accent": "oklch(0.967 0.001 286.375)",
|
|
2799
|
+
"--accent-foreground": "oklch(0.21 0.006 285.885)",
|
|
2800
|
+
"--destructive": "oklch(0.577 0.245 27.325)",
|
|
2801
|
+
"--border": "oklch(0.92 0.004 286.32)",
|
|
2802
|
+
"--input": "oklch(0.92 0.004 286.32)",
|
|
2803
|
+
"--ring": "oklch(0.645 0.246 16.439)",
|
|
2804
|
+
"--chart-1": "oklch(0.646 0.222 41.116)",
|
|
2805
|
+
"--chart-2": "oklch(0.6 0.118 184.704)",
|
|
2806
|
+
"--chart-3": "oklch(0.398 0.07 227.392)",
|
|
2807
|
+
"--chart-4": "oklch(0.828 0.189 84.429)",
|
|
2808
|
+
"--chart-5": "oklch(0.769 0.188 70.08)",
|
|
2809
|
+
"--sidebar": "oklch(0.985 0 0)",
|
|
2810
|
+
"--sidebar-foreground": "oklch(0.141 0.005 285.823)",
|
|
2811
|
+
"--sidebar-primary": "oklch(0.645 0.246 16.439)",
|
|
2812
|
+
"--sidebar-primary-foreground": "oklch(0.969 0.015 12.422)",
|
|
2813
|
+
"--sidebar-accent": "oklch(0.967 0.001 286.375)",
|
|
2814
|
+
"--sidebar-accent-foreground": "oklch(0.21 0.006 285.885)",
|
|
2815
|
+
"--sidebar-border": "oklch(0.92 0.004 286.32)",
|
|
2816
|
+
"--sidebar-ring": "oklch(0.645 0.246 16.439)",
|
|
2817
|
+
},
|
|
2818
|
+
dark: {
|
|
2819
|
+
"--background": "oklch(0.141 0.005 285.823)",
|
|
2820
|
+
"--foreground": "oklch(0.985 0 0)",
|
|
2821
|
+
"--card": "oklch(0.21 0.006 285.885)",
|
|
2822
|
+
"--card-foreground": "oklch(0.985 0 0)",
|
|
2823
|
+
"--popover": "oklch(0.21 0.006 285.885)",
|
|
2824
|
+
"--popover-foreground": "oklch(0.985 0 0)",
|
|
2825
|
+
"--primary": "oklch(0.645 0.246 16.439)",
|
|
2826
|
+
"--primary-foreground": "oklch(0.969 0.015 12.422)",
|
|
2827
|
+
"--secondary": "oklch(0.274 0.006 286.033)",
|
|
2828
|
+
"--secondary-foreground": "oklch(0.985 0 0)",
|
|
2829
|
+
"--muted": "oklch(0.274 0.006 286.033)",
|
|
2830
|
+
"--muted-foreground": "oklch(0.705 0.015 286.067)",
|
|
2831
|
+
"--accent": "oklch(0.274 0.006 286.033)",
|
|
2832
|
+
"--accent-foreground": "oklch(0.985 0 0)",
|
|
2833
|
+
"--destructive": "oklch(0.704 0.191 22.216)",
|
|
2834
|
+
"--border": "oklch(1 0 0 / 10%)",
|
|
2835
|
+
"--input": "oklch(1 0 0 / 15%)",
|
|
2836
|
+
"--ring": "oklch(0.645 0.246 16.439)",
|
|
2837
|
+
"--chart-1": "oklch(0.488 0.243 264.376)",
|
|
2838
|
+
"--chart-2": "oklch(0.696 0.17 162.48)",
|
|
2839
|
+
"--chart-3": "oklch(0.769 0.188 70.08)",
|
|
2840
|
+
"--chart-4": "oklch(0.627 0.265 303.9)",
|
|
2841
|
+
"--chart-5": "oklch(0.645 0.246 16.439)",
|
|
2842
|
+
"--sidebar": "oklch(0.21 0.006 285.885)",
|
|
2843
|
+
"--sidebar-foreground": "oklch(0.985 0 0)",
|
|
2844
|
+
"--sidebar-primary": "oklch(0.645 0.246 16.439)",
|
|
2845
|
+
"--sidebar-primary-foreground": "oklch(0.969 0.015 12.422)",
|
|
2846
|
+
"--sidebar-accent": "oklch(0.274 0.006 286.033)",
|
|
2847
|
+
"--sidebar-accent-foreground": "oklch(0.985 0 0)",
|
|
2848
|
+
"--sidebar-border": "oklch(1 0 0 / 10%)",
|
|
2849
|
+
"--sidebar-ring": "oklch(0.645 0.246 16.439)",
|
|
2850
|
+
},
|
|
2851
|
+
},
|
|
2852
|
+
v3: {
|
|
2853
|
+
root: {
|
|
2854
|
+
"--background": "0 0% 100%",
|
|
2855
|
+
"--foreground": "240 10% 3.9%",
|
|
2856
|
+
"--card": "0 0% 100%",
|
|
2857
|
+
"--card-foreground": "240 10% 3.9%",
|
|
2858
|
+
"--popover": "0 0% 100%",
|
|
2859
|
+
"--popover-foreground": "240 10% 3.9%",
|
|
2860
|
+
"--primary": "346.8 77.2% 49.8%",
|
|
2861
|
+
"--primary-foreground": "355.7 100% 97.3%",
|
|
2862
|
+
"--secondary": "240 4.8% 95.9%",
|
|
2863
|
+
"--secondary-foreground": "240 5.9% 10%",
|
|
2864
|
+
"--muted": "240 4.8% 95.9%",
|
|
2865
|
+
"--muted-foreground": "240 3.8% 46.1%",
|
|
2866
|
+
"--accent": "240 4.8% 95.9%",
|
|
2867
|
+
"--accent-foreground": "240 5.9% 10%",
|
|
2868
|
+
"--destructive": "0 84.2% 60.2%",
|
|
2869
|
+
"--destructive-foreground": "0 0% 98%",
|
|
2870
|
+
"--border": "240 5.9% 90%",
|
|
2871
|
+
"--input": "240 5.9% 90%",
|
|
2872
|
+
"--ring": "346.8 77.2% 49.8%",
|
|
2873
|
+
"--radius": "0.5rem",
|
|
2874
|
+
"--chart-1": "12 76% 61%",
|
|
2875
|
+
"--chart-2": "173 58% 39%",
|
|
2876
|
+
"--chart-3": "197 37% 24%",
|
|
2877
|
+
"--chart-4": "43 74% 66%",
|
|
2878
|
+
"--chart-5": "27 87% 67%",
|
|
2879
|
+
"--sidebar": "221 39% 11%",
|
|
2880
|
+
"--sidebar-foreground": "0 0% 98%",
|
|
2881
|
+
"--sidebar-primary": "217.2 91.2% 59.8%",
|
|
2882
|
+
"--special": "227 21% 8%",
|
|
2883
|
+
"--special-muted-background": "240 10% 4%",
|
|
2884
|
+
"--special-border": "240 4% 16%",
|
|
2885
|
+
"--special-foreground": "240 5% 84%",
|
|
2886
|
+
"--special-muted-foreground": "240 4% 46%",
|
|
2887
|
+
},
|
|
2888
|
+
dark: {
|
|
2889
|
+
"--background": "20 14.3% 4.1%",
|
|
2890
|
+
"--foreground": "0 0% 95%",
|
|
2891
|
+
"--card": "24 9.8% 10%",
|
|
2892
|
+
"--card-foreground": "0 0% 95%",
|
|
2893
|
+
"--popover": "0 0% 9%",
|
|
2894
|
+
"--popover-foreground": "0 0% 95%",
|
|
2895
|
+
"--primary": "346.8 77.2% 49.8%",
|
|
2896
|
+
"--primary-foreground": "355.7 100% 97.3%",
|
|
2897
|
+
"--secondary": "240 3.7% 15.9%",
|
|
2898
|
+
"--secondary-foreground": "0 0% 98%",
|
|
2899
|
+
"--muted": "0 0% 15%",
|
|
2900
|
+
"--muted-foreground": "240 5% 64.9%",
|
|
2901
|
+
"--accent": "12 6.5% 15.1%",
|
|
2902
|
+
"--accent-foreground": "0 0% 98%",
|
|
2903
|
+
"--destructive": "0 62.8% 30.6%",
|
|
2904
|
+
"--destructive-foreground": "0 85.7% 97.3%",
|
|
2905
|
+
"--border": "240 3.7% 15.9%",
|
|
2906
|
+
"--input": "240 3.7% 15.9%",
|
|
2907
|
+
"--ring": "346.8 77.2% 49.8%",
|
|
2908
|
+
"--chart-1": "220 70% 50%",
|
|
2909
|
+
"--chart-2": "160 60% 45%",
|
|
2910
|
+
"--chart-3": "30 80% 55%",
|
|
2911
|
+
"--chart-4": "280 65% 60%",
|
|
2912
|
+
"--chart-5": "340 75% 55%",
|
|
2913
|
+
"--sidebar": "221 39% 11%",
|
|
2914
|
+
"--sidebar-foreground": "0 0% 98%",
|
|
2915
|
+
"--sidebar-primary": "217.2 91.2% 59.8%",
|
|
2916
|
+
"--special": "227 21% 8%",
|
|
2917
|
+
"--special-muted-background": "240 10% 4%",
|
|
2918
|
+
"--special-border": "240 4% 16%",
|
|
2919
|
+
"--special-foreground": "240 5% 84%",
|
|
2920
|
+
"--special-muted-foreground": "240 4% 46%",
|
|
2921
|
+
},
|
|
2922
|
+
},
|
|
2923
|
+
},
|
|
2924
|
+
orange: {
|
|
2925
|
+
v4: {
|
|
2926
|
+
root: {
|
|
2927
|
+
"--radius": "0.65rem",
|
|
2928
|
+
"--background": "oklch(1 0 0)",
|
|
2929
|
+
"--foreground": "oklch(0.141 0.005 285.823)",
|
|
2930
|
+
"--card": "oklch(1 0 0)",
|
|
2931
|
+
"--card-foreground": "oklch(0.141 0.005 285.823)",
|
|
2932
|
+
"--popover": "oklch(1 0 0)",
|
|
2933
|
+
"--popover-foreground": "oklch(0.141 0.005 285.823)",
|
|
2934
|
+
"--primary": "oklch(0.705 0.213 47.604)",
|
|
2935
|
+
"--primary-foreground": "oklch(0.98 0.016 73.684)",
|
|
2936
|
+
"--secondary": "oklch(0.967 0.001 286.375)",
|
|
2937
|
+
"--secondary-foreground": "oklch(0.21 0.006 285.885)",
|
|
2938
|
+
"--muted": "oklch(0.967 0.001 286.375)",
|
|
2939
|
+
"--muted-foreground": "oklch(0.552 0.016 285.938)",
|
|
2940
|
+
"--accent": "oklch(0.967 0.001 286.375)",
|
|
2941
|
+
"--accent-foreground": "oklch(0.21 0.006 285.885)",
|
|
2942
|
+
"--destructive": "oklch(0.577 0.245 27.325)",
|
|
2943
|
+
"--border": "oklch(0.92 0.004 286.32)",
|
|
2944
|
+
"--input": "oklch(0.92 0.004 286.32)",
|
|
2945
|
+
"--ring": "oklch(0.705 0.213 47.604)",
|
|
2946
|
+
"--chart-1": "oklch(0.646 0.222 41.116)",
|
|
2947
|
+
"--chart-2": "oklch(0.6 0.118 184.704)",
|
|
2948
|
+
"--chart-3": "oklch(0.398 0.07 227.392)",
|
|
2949
|
+
"--chart-4": "oklch(0.828 0.189 84.429)",
|
|
2950
|
+
"--chart-5": "oklch(0.769 0.188 70.08)",
|
|
2951
|
+
"--sidebar": "oklch(0.985 0 0)",
|
|
2952
|
+
"--sidebar-foreground": "oklch(0.141 0.005 285.823)",
|
|
2953
|
+
"--sidebar-primary": "oklch(0.705 0.213 47.604)",
|
|
2954
|
+
"--sidebar-primary-foreground": "oklch(0.98 0.016 73.684)",
|
|
2955
|
+
"--sidebar-accent": "oklch(0.967 0.001 286.375)",
|
|
2956
|
+
"--sidebar-accent-foreground": "oklch(0.21 0.006 285.885)",
|
|
2957
|
+
"--sidebar-border": "oklch(0.92 0.004 286.32)",
|
|
2958
|
+
"--sidebar-ring": "oklch(0.705 0.213 47.604)",
|
|
2959
|
+
},
|
|
2960
|
+
dark: {
|
|
2961
|
+
"--background": "oklch(0.141 0.005 285.823)",
|
|
2962
|
+
"--foreground": "oklch(0.985 0 0)",
|
|
2963
|
+
"--card": "oklch(0.21 0.006 285.885)",
|
|
2964
|
+
"--card-foreground": "oklch(0.985 0 0)",
|
|
2965
|
+
"--popover": "oklch(0.21 0.006 285.885)",
|
|
2966
|
+
"--popover-foreground": "oklch(0.985 0 0)",
|
|
2967
|
+
"--primary": "oklch(0.646 0.222 41.116)",
|
|
2968
|
+
"--primary-foreground": "oklch(0.98 0.016 73.684)",
|
|
2969
|
+
"--secondary": "oklch(0.274 0.006 286.033)",
|
|
2970
|
+
"--secondary-foreground": "oklch(0.985 0 0)",
|
|
2971
|
+
"--muted": "oklch(0.274 0.006 286.033)",
|
|
2972
|
+
"--muted-foreground": "oklch(0.705 0.015 286.067)",
|
|
2973
|
+
"--accent": "oklch(0.274 0.006 286.033)",
|
|
2974
|
+
"--accent-foreground": "oklch(0.985 0 0)",
|
|
2975
|
+
"--destructive": "oklch(0.704 0.191 22.216)",
|
|
2976
|
+
"--border": "oklch(1 0 0 / 10%)",
|
|
2977
|
+
"--input": "oklch(1 0 0 / 15%)",
|
|
2978
|
+
"--ring": "oklch(0.646 0.222 41.116)",
|
|
2979
|
+
"--chart-1": "oklch(0.488 0.243 264.376)",
|
|
2980
|
+
"--chart-2": "oklch(0.696 0.17 162.48)",
|
|
2981
|
+
"--chart-3": "oklch(0.769 0.188 70.08)",
|
|
2982
|
+
"--chart-4": "oklch(0.627 0.265 303.9)",
|
|
2983
|
+
"--chart-5": "oklch(0.645 0.246 16.439)",
|
|
2984
|
+
"--sidebar": "oklch(0.21 0.006 285.885)",
|
|
2985
|
+
"--sidebar-foreground": "oklch(0.985 0 0)",
|
|
2986
|
+
"--sidebar-primary": "oklch(0.646 0.222 41.116)",
|
|
2987
|
+
"--sidebar-primary-foreground": "oklch(0.98 0.016 73.684)",
|
|
2988
|
+
"--sidebar-accent": "oklch(0.274 0.006 286.033)",
|
|
2989
|
+
"--sidebar-accent-foreground": "oklch(0.985 0 0)",
|
|
2990
|
+
"--sidebar-border": "oklch(1 0 0 / 10%)",
|
|
2991
|
+
"--sidebar-ring": "oklch(0.646 0.222 41.116)",
|
|
2992
|
+
},
|
|
2993
|
+
},
|
|
2994
|
+
v3: {
|
|
2995
|
+
root: {
|
|
2996
|
+
"--background": "0 0% 100%",
|
|
2997
|
+
"--foreground": "20 14.3% 4.1%",
|
|
2998
|
+
"--card": "0 0% 100%",
|
|
2999
|
+
"--card-foreground": "20 14.3% 4.1%",
|
|
3000
|
+
"--popover": "0 0% 100%",
|
|
3001
|
+
"--popover-foreground": "20 14.3% 4.1%",
|
|
3002
|
+
"--primary": "24.6 95% 53.1%",
|
|
3003
|
+
"--primary-foreground": "60 9.1% 97.8%",
|
|
3004
|
+
"--secondary": "60 4.8% 95.9%",
|
|
3005
|
+
"--secondary-foreground": "24 9.8% 10%",
|
|
3006
|
+
"--muted": "60 4.8% 95.9%",
|
|
3007
|
+
"--muted-foreground": "25 5.3% 44.7%",
|
|
3008
|
+
"--accent": "60 4.8% 95.9%",
|
|
3009
|
+
"--accent-foreground": "24 9.8% 10%",
|
|
3010
|
+
"--destructive": "0 84.2% 60.2%",
|
|
3011
|
+
"--destructive-foreground": "60 9.1% 97.8%",
|
|
3012
|
+
"--border": "20 5.9% 90%",
|
|
3013
|
+
"--input": "20 5.9% 90%",
|
|
3014
|
+
"--ring": "24.6 95% 53.1%",
|
|
3015
|
+
"--radius": "0.5rem",
|
|
3016
|
+
"--chart-1": "12 76% 61%",
|
|
3017
|
+
"--chart-2": "173 58% 39%",
|
|
3018
|
+
"--chart-3": "197 37% 24%",
|
|
3019
|
+
"--chart-4": "43 74% 66%",
|
|
3020
|
+
"--chart-5": "27 87% 67%",
|
|
3021
|
+
"--sidebar": "221 39% 11%",
|
|
3022
|
+
"--sidebar-foreground": "0 0% 98%",
|
|
3023
|
+
"--sidebar-primary": "217.2 91.2% 59.8%",
|
|
3024
|
+
"--special": "227 21% 8%",
|
|
3025
|
+
"--special-muted-background": "240 10% 4%",
|
|
3026
|
+
"--special-border": "240 4% 16%",
|
|
3027
|
+
"--special-foreground": "240 5% 84%",
|
|
3028
|
+
"--special-muted-foreground": "240 4% 46%",
|
|
3029
|
+
},
|
|
3030
|
+
dark: {
|
|
3031
|
+
"--background": "20 14.3% 4.1%",
|
|
3032
|
+
"--foreground": "60 9.1% 97.8%",
|
|
3033
|
+
"--card": "20 14.3% 4.1%",
|
|
3034
|
+
"--card-foreground": "60 9.1% 97.8%",
|
|
3035
|
+
"--popover": "20 14.3% 4.1%",
|
|
3036
|
+
"--popover-foreground": "60 9.1% 97.8%",
|
|
3037
|
+
"--primary": "20.5 90.2% 48.2%",
|
|
3038
|
+
"--primary-foreground": "60 9.1% 97.8%",
|
|
3039
|
+
"--secondary": "12 6.5% 15.1%",
|
|
3040
|
+
"--secondary-foreground": "60 9.1% 97.8%",
|
|
3041
|
+
"--muted": "12 6.5% 15.1%",
|
|
3042
|
+
"--muted-foreground": "24 5.4% 63.9%",
|
|
3043
|
+
"--accent": "12 6.5% 15.1%",
|
|
3044
|
+
"--accent-foreground": "60 9.1% 97.8%",
|
|
3045
|
+
"--destructive": "0 72.2% 50.6%",
|
|
3046
|
+
"--destructive-foreground": "60 9.1% 97.8%",
|
|
3047
|
+
"--border": "12 6.5% 15.1%",
|
|
3048
|
+
"--input": "12 6.5% 15.1%",
|
|
3049
|
+
"--ring": "20.5 90.2% 48.2%",
|
|
3050
|
+
"--chart-1": "220 70% 50%",
|
|
3051
|
+
"--chart-2": "160 60% 45%",
|
|
3052
|
+
"--chart-3": "30 80% 55%",
|
|
3053
|
+
"--chart-4": "280 65% 60%",
|
|
3054
|
+
"--chart-5": "340 75% 55%",
|
|
3055
|
+
"--sidebar": "221 39% 11%",
|
|
3056
|
+
"--sidebar-foreground": "0 0% 98%",
|
|
3057
|
+
"--sidebar-primary": "217.2 91.2% 59.8%",
|
|
3058
|
+
"--special": "227 21% 8%",
|
|
3059
|
+
"--special-muted-background": "240 10% 4%",
|
|
3060
|
+
"--special-border": "240 4% 16%",
|
|
3061
|
+
"--special-foreground": "240 5% 84%",
|
|
3062
|
+
"--special-muted-foreground": "240 4% 46%",
|
|
3063
|
+
},
|
|
3064
|
+
},
|
|
3065
|
+
},
|
|
3066
|
+
green: {
|
|
3067
|
+
v4: {
|
|
3068
|
+
root: {
|
|
3069
|
+
"--radius": "0.65rem",
|
|
3070
|
+
"--background": "oklch(1 0 0)",
|
|
3071
|
+
"--foreground": "oklch(0.141 0.005 285.823)",
|
|
3072
|
+
"--card": "oklch(1 0 0)",
|
|
3073
|
+
"--card-foreground": "oklch(0.141 0.005 285.823)",
|
|
3074
|
+
"--popover": "oklch(1 0 0)",
|
|
3075
|
+
"--popover-foreground": "oklch(0.141 0.005 285.823)",
|
|
3076
|
+
"--primary": "oklch(0.723 0.219 149.579)",
|
|
3077
|
+
"--primary-foreground": "oklch(0.982 0.018 155.826)",
|
|
3078
|
+
"--secondary": "oklch(0.967 0.001 286.375)",
|
|
3079
|
+
"--secondary-foreground": "oklch(0.21 0.006 285.885)",
|
|
3080
|
+
"--muted": "oklch(0.967 0.001 286.375)",
|
|
3081
|
+
"--muted-foreground": "oklch(0.552 0.016 285.938)",
|
|
3082
|
+
"--accent": "oklch(0.967 0.001 286.375)",
|
|
3083
|
+
"--accent-foreground": "oklch(0.21 0.006 285.885)",
|
|
3084
|
+
"--destructive": "oklch(0.577 0.245 27.325)",
|
|
3085
|
+
"--border": "oklch(0.92 0.004 286.32)",
|
|
3086
|
+
"--input": "oklch(0.92 0.004 286.32)",
|
|
3087
|
+
"--ring": "oklch(0.723 0.219 149.579)",
|
|
3088
|
+
"--chart-1": "oklch(0.646 0.222 41.116)",
|
|
3089
|
+
"--chart-2": "oklch(0.6 0.118 184.704)",
|
|
3090
|
+
"--chart-3": "oklch(0.398 0.07 227.392)",
|
|
3091
|
+
"--chart-4": "oklch(0.828 0.189 84.429)",
|
|
3092
|
+
"--chart-5": "oklch(0.769 0.188 70.08)",
|
|
3093
|
+
"--sidebar": "oklch(0.985 0 0)",
|
|
3094
|
+
"--sidebar-foreground": "oklch(0.141 0.005 285.823)",
|
|
3095
|
+
"--sidebar-primary": "oklch(0.723 0.219 149.579)",
|
|
3096
|
+
"--sidebar-primary-foreground": "oklch(0.982 0.018 155.826)",
|
|
3097
|
+
"--sidebar-accent": "oklch(0.967 0.001 286.375)",
|
|
3098
|
+
"--sidebar-accent-foreground": "oklch(0.21 0.006 285.885)",
|
|
3099
|
+
"--sidebar-border": "oklch(0.92 0.004 286.32)",
|
|
3100
|
+
"--sidebar-ring": "oklch(0.723 0.219 149.579)",
|
|
3101
|
+
},
|
|
3102
|
+
dark: {
|
|
3103
|
+
"--background": "oklch(0.141 0.005 285.823)",
|
|
3104
|
+
"--foreground": "oklch(0.985 0 0)",
|
|
3105
|
+
"--card": "oklch(0.21 0.006 285.885)",
|
|
3106
|
+
"--card-foreground": "oklch(0.985 0 0)",
|
|
3107
|
+
"--popover": "oklch(0.21 0.006 285.885)",
|
|
3108
|
+
"--popover-foreground": "oklch(0.985 0 0)",
|
|
3109
|
+
"--primary": "oklch(0.696 0.17 162.48)",
|
|
3110
|
+
"--primary-foreground": "oklch(0.393 0.095 152.535)",
|
|
3111
|
+
"--secondary": "oklch(0.274 0.006 286.033)",
|
|
3112
|
+
"--secondary-foreground": "oklch(0.985 0 0)",
|
|
3113
|
+
"--muted": "oklch(0.274 0.006 286.033)",
|
|
3114
|
+
"--muted-foreground": "oklch(0.705 0.015 286.067)",
|
|
3115
|
+
"--accent": "oklch(0.274 0.006 286.033)",
|
|
3116
|
+
"--accent-foreground": "oklch(0.985 0 0)",
|
|
3117
|
+
"--destructive": "oklch(0.704 0.191 22.216)",
|
|
3118
|
+
"--border": "oklch(1 0 0 / 10%)",
|
|
3119
|
+
"--input": "oklch(1 0 0 / 15%)",
|
|
3120
|
+
"--ring": "oklch(0.527 0.154 150.069)",
|
|
3121
|
+
"--chart-1": "oklch(0.488 0.243 264.376)",
|
|
3122
|
+
"--chart-2": "oklch(0.696 0.17 162.48)",
|
|
3123
|
+
"--chart-3": "oklch(0.769 0.188 70.08)",
|
|
3124
|
+
"--chart-4": "oklch(0.627 0.265 303.9)",
|
|
3125
|
+
"--chart-5": "oklch(0.645 0.246 16.439)",
|
|
3126
|
+
"--sidebar": "oklch(0.21 0.006 285.885)",
|
|
3127
|
+
"--sidebar-foreground": "oklch(0.985 0 0)",
|
|
3128
|
+
"--sidebar-primary": "oklch(0.696 0.17 162.48)",
|
|
3129
|
+
"--sidebar-primary-foreground": "oklch(0.393 0.095 152.535)",
|
|
3130
|
+
"--sidebar-accent": "oklch(0.274 0.006 286.033)",
|
|
3131
|
+
"--sidebar-accent-foreground": "oklch(0.985 0 0)",
|
|
3132
|
+
"--sidebar-border": "oklch(1 0 0 / 10%)",
|
|
3133
|
+
"--sidebar-ring": "oklch(0.527 0.154 150.069)",
|
|
3134
|
+
},
|
|
3135
|
+
},
|
|
3136
|
+
v3: {
|
|
3137
|
+
root: {
|
|
3138
|
+
"--background": "0 0% 100%",
|
|
3139
|
+
"--foreground": "240 10% 3.9%",
|
|
3140
|
+
"--card": "0 0% 100%",
|
|
3141
|
+
"--card-foreground": "240 10% 3.9%",
|
|
3142
|
+
"--popover": "0 0% 100%",
|
|
3143
|
+
"--popover-foreground": "240 10% 3.9%",
|
|
3144
|
+
"--primary": "142.1 76.2% 36.3%",
|
|
3145
|
+
"--primary-foreground": "355.7 100% 97.3%",
|
|
3146
|
+
"--secondary": "240 4.8% 95.9%",
|
|
3147
|
+
"--secondary-foreground": "240 5.9% 10%",
|
|
3148
|
+
"--muted": "240 4.8% 95.9%",
|
|
3149
|
+
"--muted-foreground": "240 3.8% 46.1%",
|
|
3150
|
+
"--accent": "240 4.8% 95.9%",
|
|
3151
|
+
"--accent-foreground": "240 5.9% 10%",
|
|
3152
|
+
"--destructive": "0 84.2% 60.2%",
|
|
3153
|
+
"--destructive-foreground": "0 0% 98%",
|
|
3154
|
+
"--border": "240 5.9% 90%",
|
|
3155
|
+
"--input": "240 5.9% 90%",
|
|
3156
|
+
"--ring": "142.1 76.2% 36.3%",
|
|
3157
|
+
"--radius": "0.5rem",
|
|
3158
|
+
"--chart-1": "12 76% 61%",
|
|
3159
|
+
"--chart-2": "173 58% 39%",
|
|
3160
|
+
"--chart-3": "197 37% 24%",
|
|
3161
|
+
"--chart-4": "43 74% 66%",
|
|
3162
|
+
"--chart-5": "27 87% 67%",
|
|
3163
|
+
"--sidebar": "221 39% 11%",
|
|
3164
|
+
"--sidebar-foreground": "0 0% 98%",
|
|
3165
|
+
"--sidebar-primary": "217.2 91.2% 59.8%",
|
|
3166
|
+
"--special": "227 21% 8%",
|
|
3167
|
+
"--special-muted-background": "240 10% 4%",
|
|
3168
|
+
"--special-border": "240 4% 16%",
|
|
3169
|
+
"--special-foreground": "240 5% 84%",
|
|
3170
|
+
"--special-muted-foreground": "240 4% 46%",
|
|
3171
|
+
},
|
|
3172
|
+
dark: {
|
|
3173
|
+
"--background": "20 14.3% 4.1%",
|
|
3174
|
+
"--foreground": "0 0% 95%",
|
|
3175
|
+
"--card": "24 9.8% 10%",
|
|
3176
|
+
"--card-foreground": "0 0% 95%",
|
|
3177
|
+
"--popover": "0 0% 9%",
|
|
3178
|
+
"--popover-foreground": "0 0% 95%",
|
|
3179
|
+
"--primary": "142.1 70.6% 45.3%",
|
|
3180
|
+
"--primary-foreground": "144.9 80.4% 10%",
|
|
3181
|
+
"--secondary": "240 3.7% 15.9%",
|
|
3182
|
+
"--secondary-foreground": "0 0% 98%",
|
|
3183
|
+
"--muted": "0 0% 15%",
|
|
3184
|
+
"--muted-foreground": "240 5% 64.9%",
|
|
3185
|
+
"--accent": "12 6.5% 15.1%",
|
|
3186
|
+
"--accent-foreground": "0 0% 98%",
|
|
3187
|
+
"--destructive": "0 62.8% 30.6%",
|
|
3188
|
+
"--destructive-foreground": "0 85.7% 97.3%",
|
|
3189
|
+
"--border": "240 3.7% 15.9%",
|
|
3190
|
+
"--input": "240 3.7% 15.9%",
|
|
3191
|
+
"--ring": "142.4 71.8% 29.2%",
|
|
3192
|
+
"--chart-1": "220 70% 50%",
|
|
3193
|
+
"--chart-2": "160 60% 45%",
|
|
3194
|
+
"--chart-3": "30 80% 55%",
|
|
3195
|
+
"--chart-4": "280 65% 60%",
|
|
3196
|
+
"--chart-5": "340 75% 55%",
|
|
3197
|
+
"--sidebar": "221 39% 11%",
|
|
3198
|
+
"--sidebar-foreground": "0 0% 98%",
|
|
3199
|
+
"--sidebar-primary": "217.2 91.2% 59.8%",
|
|
3200
|
+
"--special": "227 21% 8%",
|
|
3201
|
+
"--special-muted-background": "240 10% 4%",
|
|
3202
|
+
"--special-border": "240 4% 16%",
|
|
3203
|
+
"--special-foreground": "240 5% 84%",
|
|
3204
|
+
"--special-muted-foreground": "240 4% 46%",
|
|
3205
|
+
},
|
|
3206
|
+
},
|
|
3207
|
+
},
|
|
3208
|
+
blue: {
|
|
3209
|
+
v4: {
|
|
3210
|
+
root: {
|
|
3211
|
+
"--radius": "0.65rem",
|
|
3212
|
+
"--background": "oklch(1 0 0)",
|
|
3213
|
+
"--foreground": "oklch(0.141 0.005 285.823)",
|
|
3214
|
+
"--card": "oklch(1 0 0)",
|
|
3215
|
+
"--card-foreground": "oklch(0.141 0.005 285.823)",
|
|
3216
|
+
"--popover": "oklch(1 0 0)",
|
|
3217
|
+
"--popover-foreground": "oklch(0.141 0.005 285.823)",
|
|
3218
|
+
"--primary": "oklch(0.623 0.214 259.815)",
|
|
3219
|
+
"--primary-foreground": "oklch(0.97 0.014 254.604)",
|
|
3220
|
+
"--secondary": "oklch(0.967 0.001 286.375)",
|
|
3221
|
+
"--secondary-foreground": "oklch(0.21 0.006 285.885)",
|
|
3222
|
+
"--muted": "oklch(0.967 0.001 286.375)",
|
|
3223
|
+
"--muted-foreground": "oklch(0.552 0.016 285.938)",
|
|
3224
|
+
"--accent": "oklch(0.967 0.001 286.375)",
|
|
3225
|
+
"--accent-foreground": "oklch(0.21 0.006 285.885)",
|
|
3226
|
+
"--destructive": "oklch(0.577 0.245 27.325)",
|
|
3227
|
+
"--border": "oklch(0.92 0.004 286.32)",
|
|
3228
|
+
"--input": "oklch(0.92 0.004 286.32)",
|
|
3229
|
+
"--ring": "oklch(0.623 0.214 259.815)",
|
|
3230
|
+
"--chart-1": "oklch(0.646 0.222 41.116)",
|
|
3231
|
+
"--chart-2": "oklch(0.6 0.118 184.704)",
|
|
3232
|
+
"--chart-3": "oklch(0.398 0.07 227.392)",
|
|
3233
|
+
"--chart-4": "oklch(0.828 0.189 84.429)",
|
|
3234
|
+
"--chart-5": "oklch(0.769 0.188 70.08)",
|
|
3235
|
+
"--sidebar": "oklch(0.985 0 0)",
|
|
3236
|
+
"--sidebar-foreground": "oklch(0.141 0.005 285.823)",
|
|
3237
|
+
"--sidebar-primary": "oklch(0.623 0.214 259.815)",
|
|
3238
|
+
"--sidebar-primary-foreground": "oklch(0.97 0.014 254.604)",
|
|
3239
|
+
"--sidebar-accent": "oklch(0.967 0.001 286.375)",
|
|
3240
|
+
"--sidebar-accent-foreground": "oklch(0.21 0.006 285.885)",
|
|
3241
|
+
"--sidebar-border": "oklch(0.92 0.004 286.32)",
|
|
3242
|
+
"--sidebar-ring": "oklch(0.623 0.214 259.815)",
|
|
3243
|
+
},
|
|
3244
|
+
dark: {
|
|
3245
|
+
"--background": "oklch(0.141 0.005 285.823)",
|
|
3246
|
+
"--foreground": "oklch(0.985 0 0)",
|
|
3247
|
+
"--card": "oklch(0.21 0.006 285.885)",
|
|
3248
|
+
"--card-foreground": "oklch(0.985 0 0)",
|
|
3249
|
+
"--popover": "oklch(0.21 0.006 285.885)",
|
|
3250
|
+
"--popover-foreground": "oklch(0.985 0 0)",
|
|
3251
|
+
"--primary": "oklch(0.546 0.245 262.881)",
|
|
3252
|
+
"--primary-foreground": "oklch(0.379 0.146 265.522)",
|
|
3253
|
+
"--secondary": "oklch(0.274 0.006 286.033)",
|
|
3254
|
+
"--secondary-foreground": "oklch(0.985 0 0)",
|
|
3255
|
+
"--muted": "oklch(0.274 0.006 286.033)",
|
|
3256
|
+
"--muted-foreground": "oklch(0.705 0.015 286.067)",
|
|
3257
|
+
"--accent": "oklch(0.274 0.006 286.033)",
|
|
3258
|
+
"--accent-foreground": "oklch(0.985 0 0)",
|
|
3259
|
+
"--destructive": "oklch(0.704 0.191 22.216)",
|
|
3260
|
+
"--border": "oklch(1 0 0 / 10%)",
|
|
3261
|
+
"--input": "oklch(1 0 0 / 15%)",
|
|
3262
|
+
"--ring": "oklch(0.488 0.243 264.376)",
|
|
3263
|
+
"--chart-1": "oklch(0.488 0.243 264.376)",
|
|
3264
|
+
"--chart-2": "oklch(0.696 0.17 162.48)",
|
|
3265
|
+
"--chart-3": "oklch(0.769 0.188 70.08)",
|
|
3266
|
+
"--chart-4": "oklch(0.627 0.265 303.9)",
|
|
3267
|
+
"--chart-5": "oklch(0.645 0.246 16.439)",
|
|
3268
|
+
"--sidebar": "oklch(0.21 0.006 285.885)",
|
|
3269
|
+
"--sidebar-foreground": "oklch(0.985 0 0)",
|
|
3270
|
+
"--sidebar-primary": "oklch(0.546 0.245 262.881)",
|
|
3271
|
+
"--sidebar-primary-foreground": "oklch(0.379 0.146 265.522)",
|
|
3272
|
+
"--sidebar-accent": "oklch(0.274 0.006 286.033)",
|
|
3273
|
+
"--sidebar-accent-foreground": "oklch(0.985 0 0)",
|
|
3274
|
+
"--sidebar-border": "oklch(1 0 0 / 10%)",
|
|
3275
|
+
"--sidebar-ring": "oklch(0.488 0.243 264.376)",
|
|
3276
|
+
},
|
|
3277
|
+
},
|
|
3278
|
+
v3: {
|
|
3279
|
+
root: {
|
|
3280
|
+
"--background": "0 0% 100%",
|
|
3281
|
+
"--foreground": "222.2 84% 4.9%",
|
|
3282
|
+
"--card": "0 0% 100%",
|
|
3283
|
+
"--card-foreground": "222.2 84% 4.9%",
|
|
3284
|
+
"--popover": "0 0% 100%",
|
|
3285
|
+
"--popover-foreground": "222.2 84% 4.9%",
|
|
3286
|
+
"--primary": "221.2 83.2% 53.3%",
|
|
3287
|
+
"--primary-foreground": "210 40% 98%",
|
|
3288
|
+
"--secondary": "210 40% 96.1%",
|
|
3289
|
+
"--secondary-foreground": "222.2 47.4% 11.2%",
|
|
3290
|
+
"--muted": "210 40% 96.1%",
|
|
3291
|
+
"--muted-foreground": "215.4 16.3% 46.9%",
|
|
3292
|
+
"--accent": "210 40% 96.1%",
|
|
3293
|
+
"--accent-foreground": "222.2 47.4% 11.2%",
|
|
3294
|
+
"--destructive": "0 84.2% 60.2%",
|
|
3295
|
+
"--destructive-foreground": "210 40% 98%",
|
|
3296
|
+
"--border": "214.3 31.8% 91.4%",
|
|
3297
|
+
"--input": "214.3 31.8% 91.4%",
|
|
3298
|
+
"--ring": "221.2 83.2% 53.3%",
|
|
3299
|
+
"--radius": "0.5rem",
|
|
3300
|
+
"--chart-1": "12 76% 61%",
|
|
3301
|
+
"--chart-2": "173 58% 39%",
|
|
3302
|
+
"--chart-3": "197 37% 24%",
|
|
3303
|
+
"--chart-4": "43 74% 66%",
|
|
3304
|
+
"--chart-5": "27 87% 67%",
|
|
3305
|
+
"--sidebar": "221 39% 11%",
|
|
3306
|
+
"--sidebar-foreground": "0 0% 98%",
|
|
3307
|
+
"--sidebar-primary": "221.2 83.2% 53.3%",
|
|
3308
|
+
"--special": "221 39% 11%",
|
|
3309
|
+
"--special-muted-background": "210 40% 96.1%",
|
|
3310
|
+
"--special-border": "214.3 31.8% 91.4%",
|
|
3311
|
+
"--special-foreground": "0 0% 98%",
|
|
3312
|
+
"--special-muted-foreground": "215.4 16.3% 46.9%",
|
|
3313
|
+
|
|
3314
|
+
},
|
|
3315
|
+
dark: {
|
|
3316
|
+
"--background": "222.2 84% 4.9%",
|
|
3317
|
+
"--foreground": "210 40% 98%",
|
|
3318
|
+
"--card": "222.2 84% 4.9%",
|
|
3319
|
+
"--card-foreground": "210 40% 98%",
|
|
3320
|
+
"--popover": "222.2 84% 4.9%",
|
|
3321
|
+
"--popover-foreground": "210 40% 98%",
|
|
3322
|
+
"--primary": "217.2 91.2% 59.8%",
|
|
3323
|
+
"--primary-foreground": "222.2 47.4% 11.2%",
|
|
3324
|
+
"--secondary": "217.2 32.6% 17.5%",
|
|
3325
|
+
"--secondary-foreground": "210 40% 98%",
|
|
3326
|
+
"--muted": "217.2 32.6% 17.5%",
|
|
3327
|
+
"--muted-foreground": "215 20.2% 65.1%",
|
|
3328
|
+
"--accent": "217.2 32.6% 17.5%",
|
|
3329
|
+
"--accent-foreground": "210 40% 98%",
|
|
3330
|
+
"--destructive": "0 62.8% 30.6%",
|
|
3331
|
+
"--destructive-foreground": "210 40% 98%",
|
|
3332
|
+
"--border": "217.2 32.6% 17.5%",
|
|
3333
|
+
"--input": "217.2 32.6% 17.5%",
|
|
3334
|
+
"--ring": "224.3 76.3% 48%",
|
|
3335
|
+
"--chart-1": "220 70% 50%",
|
|
3336
|
+
"--chart-2": "160 60% 45%",
|
|
3337
|
+
"--chart-3": "30 80% 55%",
|
|
3338
|
+
"--chart-4": "280 65% 60%",
|
|
3339
|
+
"--chart-5": "340 75% 55%",
|
|
3340
|
+
"--sidebar": "221 39% 11%",
|
|
3341
|
+
"--sidebar-foreground": "0 0% 98%",
|
|
3342
|
+
"--sidebar-primary": "221.2 83.2% 53.3%",
|
|
3343
|
+
"--special": "221 39% 11%",
|
|
3344
|
+
"--special-muted-background": "210 40% 96.1%",
|
|
3345
|
+
"--special-border": "214.3 31.8% 91.4%",
|
|
3346
|
+
"--special-foreground": "0 0% 98%",
|
|
3347
|
+
"--special-muted-foreground": "215.4 16.3% 46.9%",
|
|
3348
|
+
},
|
|
3349
|
+
},
|
|
3350
|
+
},
|
|
3351
|
+
yellow: {
|
|
3352
|
+
v4: {
|
|
3353
|
+
root: {
|
|
3354
|
+
"--radius": "0.65rem",
|
|
3355
|
+
"--background": "oklch(1 0 0)",
|
|
3356
|
+
"--foreground": "oklch(0.141 0.005 285.823)",
|
|
3357
|
+
"--card": "oklch(1 0 0)",
|
|
3358
|
+
"--card-foreground": "oklch(0.141 0.005 285.823)",
|
|
3359
|
+
"--popover": "oklch(1 0 0)",
|
|
3360
|
+
"--popover-foreground": "oklch(0.141 0.005 285.823)",
|
|
3361
|
+
"--primary": "oklch(0.795 0.184 86.047)",
|
|
3362
|
+
"--primary-foreground": "oklch(0.421 0.095 57.708)",
|
|
3363
|
+
"--secondary": "oklch(0.967 0.001 286.375)",
|
|
3364
|
+
"--secondary-foreground": "oklch(0.21 0.006 285.885)",
|
|
3365
|
+
"--muted": "oklch(0.967 0.001 286.375)",
|
|
3366
|
+
"--muted-foreground": "oklch(0.552 0.016 285.938)",
|
|
3367
|
+
"--accent": "oklch(0.967 0.001 286.375)",
|
|
3368
|
+
"--accent-foreground": "oklch(0.21 0.006 285.885)",
|
|
3369
|
+
"--destructive": "oklch(0.577 0.245 27.325)",
|
|
3370
|
+
"--border": "oklch(0.92 0.004 286.32)",
|
|
3371
|
+
"--input": "oklch(0.92 0.004 286.32)",
|
|
3372
|
+
"--ring": "oklch(0.795 0.184 86.047)",
|
|
3373
|
+
"--chart-1": "oklch(0.646 0.222 41.116)",
|
|
3374
|
+
"--chart-2": "oklch(0.6 0.118 184.704)",
|
|
3375
|
+
"--chart-3": "oklch(0.398 0.07 227.392)",
|
|
3376
|
+
"--chart-4": "oklch(0.828 0.189 84.429)",
|
|
3377
|
+
"--chart-5": "oklch(0.769 0.188 70.08)",
|
|
3378
|
+
"--sidebar": "oklch(0.985 0 0)",
|
|
3379
|
+
"--sidebar-foreground": "oklch(0.141 0.005 285.823)",
|
|
3380
|
+
"--sidebar-primary": "oklch(0.795 0.184 86.047)",
|
|
3381
|
+
"--sidebar-primary-foreground": "oklch(0.421 0.095 57.708)",
|
|
3382
|
+
"--sidebar-accent": "oklch(0.967 0.001 286.375)",
|
|
3383
|
+
"--sidebar-accent-foreground": "oklch(0.21 0.006 285.885)",
|
|
3384
|
+
"--sidebar-border": "oklch(0.92 0.004 286.32)",
|
|
3385
|
+
"--sidebar-ring": "oklch(0.795 0.184 86.047)",
|
|
3386
|
+
},
|
|
3387
|
+
dark: {
|
|
3388
|
+
"--background": "oklch(0.141 0.005 285.823)",
|
|
3389
|
+
"--foreground": "oklch(0.985 0 0)",
|
|
3390
|
+
"--card": "oklch(0.21 0.006 285.885)",
|
|
3391
|
+
"--card-foreground": "oklch(0.985 0 0)",
|
|
3392
|
+
"--popover": "oklch(0.21 0.006 285.885)",
|
|
3393
|
+
"--popover-foreground": "oklch(0.985 0 0)",
|
|
3394
|
+
"--primary": "oklch(0.795 0.184 86.047)",
|
|
3395
|
+
"--primary-foreground": "oklch(0.421 0.095 57.708)",
|
|
3396
|
+
"--secondary": "oklch(0.274 0.006 286.033)",
|
|
3397
|
+
"--secondary-foreground": "oklch(0.985 0 0)",
|
|
3398
|
+
"--muted": "oklch(0.274 0.006 286.033)",
|
|
3399
|
+
"--muted-foreground": "oklch(0.705 0.015 286.067)",
|
|
3400
|
+
"--accent": "oklch(0.274 0.006 286.033)",
|
|
3401
|
+
"--accent-foreground": "oklch(0.985 0 0)",
|
|
3402
|
+
"--destructive": "oklch(0.704 0.191 22.216)",
|
|
3403
|
+
"--border": "oklch(1 0 0 / 10%)",
|
|
3404
|
+
"--input": "oklch(1 0 0 / 15%)",
|
|
3405
|
+
"--ring": "oklch(0.554 0.135 66.442)",
|
|
3406
|
+
"--chart-1": "oklch(0.488 0.243 264.376)",
|
|
3407
|
+
"--chart-2": "oklch(0.696 0.17 162.48)",
|
|
3408
|
+
"--chart-3": "oklch(0.769 0.188 70.08)",
|
|
3409
|
+
"--chart-4": "oklch(0.627 0.265 303.9)",
|
|
3410
|
+
"--chart-5": "oklch(0.645 0.246 16.439)",
|
|
3411
|
+
"--sidebar": "oklch(0.21 0.006 285.885)",
|
|
3412
|
+
"--sidebar-foreground": "oklch(0.985 0 0)",
|
|
3413
|
+
"--sidebar-primary": "oklch(0.795 0.184 86.047)",
|
|
3414
|
+
"--sidebar-primary-foreground": "oklch(0.421 0.095 57.708)",
|
|
3415
|
+
"--sidebar-accent": "oklch(0.274 0.006 286.033)",
|
|
3416
|
+
"--sidebar-accent-foreground": "oklch(0.985 0 0)",
|
|
3417
|
+
"--sidebar-border": "oklch(1 0 0 / 10%)",
|
|
3418
|
+
"--sidebar-ring": "oklch(0.554 0.135 66.442)",
|
|
3419
|
+
},
|
|
3420
|
+
},
|
|
3421
|
+
v3: {
|
|
3422
|
+
root: {
|
|
3423
|
+
"--background": "0 0% 100%",
|
|
3424
|
+
"--foreground": "20 14.3% 4.1%",
|
|
3425
|
+
"--card": "0 0% 100%",
|
|
3426
|
+
"--card-foreground": "20 14.3% 4.1%",
|
|
3427
|
+
"--popover": "0 0% 100%",
|
|
3428
|
+
"--popover-foreground": "20 14.3% 4.1%",
|
|
3429
|
+
"--primary": "47.9 95.8% 53.1%",
|
|
3430
|
+
"--primary-foreground": "26 83.3% 14.1%",
|
|
3431
|
+
"--secondary": "60 4.8% 95.9%",
|
|
3432
|
+
"--secondary-foreground": "24 9.8% 10%",
|
|
3433
|
+
"--muted": "60 4.8% 95.9%",
|
|
3434
|
+
"--muted-foreground": "25 5.3% 44.7%",
|
|
3435
|
+
"--accent": "60 4.8% 95.9%",
|
|
3436
|
+
"--accent-foreground": "24 9.8% 10%",
|
|
3437
|
+
"--destructive": "0 84.2% 60.2%",
|
|
3438
|
+
"--destructive-foreground": "60 9.1% 97.8%",
|
|
3439
|
+
"--border": "20 5.9% 90%",
|
|
3440
|
+
"--input": "20 5.9% 90%",
|
|
3441
|
+
"--ring": "20 14.3% 4.1%",
|
|
3442
|
+
"--radius": "0.5rem",
|
|
3443
|
+
"--chart-1": "12 76% 61%",
|
|
3444
|
+
"--chart-2": "173 58% 39%",
|
|
3445
|
+
"--chart-3": "197 37% 24%",
|
|
3446
|
+
"--chart-4": "43 74% 66%",
|
|
3447
|
+
"--chart-5": "27 87% 67%",
|
|
3448
|
+
"--sidebar": "221 39% 11%",
|
|
3449
|
+
"--sidebar-foreground": "0 0% 98%",
|
|
3450
|
+
"--sidebar-primary": "217.2 91.2% 59.8%",
|
|
3451
|
+
"--special": "227 21% 8%",
|
|
3452
|
+
"--special-muted-background": "240 10% 4%",
|
|
3453
|
+
"--special-border": "240 4% 16%",
|
|
3454
|
+
"--special-foreground": "240 5% 84%",
|
|
3455
|
+
"--special-muted-foreground": "240 4% 46%",
|
|
3456
|
+
},
|
|
3457
|
+
dark: {
|
|
3458
|
+
"--background": "20 14.3% 4.1%",
|
|
3459
|
+
"--foreground": "60 9.1% 97.8%",
|
|
3460
|
+
"--card": "20 14.3% 4.1%",
|
|
3461
|
+
"--card-foreground": "60 9.1% 97.8%",
|
|
3462
|
+
"--popover": "20 14.3% 4.1%",
|
|
3463
|
+
"--popover-foreground": "60 9.1% 97.8%",
|
|
3464
|
+
"--primary": "47.9 95.8% 53.1%",
|
|
3465
|
+
"--primary-foreground": "26 83.3% 14.1%",
|
|
3466
|
+
"--secondary": "12 6.5% 15.1%",
|
|
3467
|
+
"--secondary-foreground": "60 9.1% 97.8%",
|
|
3468
|
+
"--muted": "12 6.5% 15.1%",
|
|
3469
|
+
"--muted-foreground": "24 5.4% 63.9%",
|
|
3470
|
+
"--accent": "12 6.5% 15.1%",
|
|
3471
|
+
"--accent-foreground": "60 9.1% 97.8%",
|
|
3472
|
+
"--destructive": "0 62.8% 30.6%",
|
|
3473
|
+
"--destructive-foreground": "60 9.1% 97.8%",
|
|
3474
|
+
"--border": "12 6.5% 15.1%",
|
|
3475
|
+
"--input": "12 6.5% 15.1%",
|
|
3476
|
+
"--ring": "35.5 91.7% 32.9%",
|
|
3477
|
+
"--chart-1": "220 70% 50%",
|
|
3478
|
+
"--chart-2": "160 60% 45%",
|
|
3479
|
+
"--chart-3": "30 80% 55%",
|
|
3480
|
+
"--chart-4": "280 65% 60%",
|
|
3481
|
+
"--chart-5": "340 75% 55%",
|
|
3482
|
+
"--sidebar": "221 39% 11%",
|
|
3483
|
+
"--sidebar-foreground": "0 0% 98%",
|
|
3484
|
+
"--sidebar-primary": "217.2 91.2% 59.8%",
|
|
3485
|
+
"--special": "227 21% 8%",
|
|
3486
|
+
"--special-muted-background": "240 10% 4%",
|
|
3487
|
+
"--special-border": "240 4% 16%",
|
|
3488
|
+
"--special-foreground": "240 5% 84%",
|
|
3489
|
+
"--special-muted-foreground": "240 4% 46%",
|
|
3490
|
+
},
|
|
3491
|
+
},
|
|
3492
|
+
},
|
|
3493
|
+
violet: {
|
|
3494
|
+
v4: {
|
|
3495
|
+
root: {
|
|
3496
|
+
"--radius": "0.65rem",
|
|
3497
|
+
"--background": "oklch(1 0 0)",
|
|
3498
|
+
"--foreground": "oklch(0.141 0.005 285.823)",
|
|
3499
|
+
"--card": "oklch(1 0 0)",
|
|
3500
|
+
"--card-foreground": "oklch(0.141 0.005 285.823)",
|
|
3501
|
+
"--popover": "oklch(1 0 0)",
|
|
3502
|
+
"--popover-foreground": "oklch(0.141 0.005 285.823)",
|
|
3503
|
+
"--primary": "oklch(0.637 0.237 25.331)",
|
|
3504
|
+
"--primary-foreground": "oklch(0.971 0.013 17.38)",
|
|
3505
|
+
"--secondary": "oklch(0.967 0.001 286.375)",
|
|
3506
|
+
"--secondary-foreground": "oklch(0.21 0.006 285.885)",
|
|
3507
|
+
"--muted": "oklch(0.967 0.001 286.375)",
|
|
3508
|
+
"--muted-foreground": "oklch(0.552 0.016 285.938)",
|
|
3509
|
+
"--accent": "oklch(0.967 0.001 286.375)",
|
|
3510
|
+
"--accent-foreground": "oklch(0.21 0.006 285.885)",
|
|
3511
|
+
"--destructive": "oklch(0.577 0.245 27.325)",
|
|
3512
|
+
"--border": "oklch(0.92 0.004 286.32)",
|
|
3513
|
+
"--input": "oklch(0.92 0.004 286.32)",
|
|
3514
|
+
"--ring": "oklch(0.637 0.237 25.331)",
|
|
3515
|
+
"--chart-1": "oklch(0.646 0.222 41.116)",
|
|
3516
|
+
"--chart-2": "oklch(0.6 0.118 184.704)",
|
|
3517
|
+
"--chart-3": "oklch(0.398 0.07 227.392)",
|
|
3518
|
+
"--chart-4": "oklch(0.828 0.189 84.429)",
|
|
3519
|
+
"--chart-5": "oklch(0.769 0.188 70.08)",
|
|
3520
|
+
"--sidebar": "oklch(0.985 0 0)",
|
|
3521
|
+
"--sidebar-foreground": "oklch(0.141 0.005 285.823)",
|
|
3522
|
+
"--sidebar-primary": "oklch(0.637 0.237 25.331)",
|
|
3523
|
+
"--sidebar-primary-foreground": "oklch(0.971 0.013 17.38)",
|
|
3524
|
+
"--sidebar-accent": "oklch(0.967 0.001 286.375)",
|
|
3525
|
+
"--sidebar-accent-foreground": "oklch(0.21 0.006 285.885)",
|
|
3526
|
+
"--sidebar-border": "oklch(0.92 0.004 286.32)",
|
|
3527
|
+
"--sidebar-ring": "oklch(0.637 0.237 25.331)",
|
|
3528
|
+
},
|
|
3529
|
+
dark: {
|
|
3530
|
+
"--background": "oklch(0.141 0.005 285.823)",
|
|
3531
|
+
"--foreground": "oklch(0.985 0 0)",
|
|
3532
|
+
"--card": "oklch(0.21 0.006 285.885)",
|
|
3533
|
+
"--card-foreground": "oklch(0.985 0 0)",
|
|
3534
|
+
"--popover": "oklch(0.21 0.006 285.885)",
|
|
3535
|
+
"--popover-foreground": "oklch(0.985 0 0)",
|
|
3536
|
+
"--primary": "oklch(0.637 0.237 25.331)",
|
|
3537
|
+
"--primary-foreground": "oklch(0.971 0.013 17.38)",
|
|
3538
|
+
"--secondary": "oklch(0.274 0.006 286.033)",
|
|
3539
|
+
"--secondary-foreground": "oklch(0.985 0 0)",
|
|
3540
|
+
"--muted": "oklch(0.274 0.006 286.033)",
|
|
3541
|
+
"--muted-foreground": "oklch(0.705 0.015 286.067)",
|
|
3542
|
+
"--accent": "oklch(0.274 0.006 286.033)",
|
|
3543
|
+
"--accent-foreground": "oklch(0.985 0 0)",
|
|
3544
|
+
"--destructive": "oklch(0.704 0.191 22.216)",
|
|
3545
|
+
"--border": "oklch(1 0 0 / 10%)",
|
|
3546
|
+
"--input": "oklch(1 0 0 / 15%)",
|
|
3547
|
+
"--ring": "oklch(0.637 0.237 25.331)",
|
|
3548
|
+
"--chart-1": "oklch(0.488 0.243 264.376)",
|
|
3549
|
+
"--chart-2": "oklch(0.696 0.17 162.48)",
|
|
3550
|
+
"--chart-3": "oklch(0.769 0.188 70.08)",
|
|
3551
|
+
"--chart-4": "oklch(0.627 0.265 303.9)",
|
|
3552
|
+
"--chart-5": "oklch(0.645 0.246 16.439)",
|
|
3553
|
+
"--sidebar": "oklch(0.21 0.006 285.885)",
|
|
3554
|
+
"--sidebar-foreground": "oklch(0.985 0 0)",
|
|
3555
|
+
"--sidebar-primary": "oklch(0.637 0.237 25.331)",
|
|
3556
|
+
"--sidebar-primary-foreground": "oklch(0.971 0.013 17.38)",
|
|
3557
|
+
"--sidebar-accent": "oklch(0.274 0.006 286.033)",
|
|
3558
|
+
"--sidebar-accent-foreground": "oklch(0.985 0 0)",
|
|
3559
|
+
"--sidebar-border": "oklch(1 0 0 / 10%)",
|
|
3560
|
+
"--sidebar-ring": "oklch(0.637 0.237 25.331)",
|
|
3561
|
+
},
|
|
3562
|
+
},
|
|
3563
|
+
v3: {
|
|
3564
|
+
root: {
|
|
3565
|
+
"--background": "0 0% 100%",
|
|
3566
|
+
"--foreground": "224 71.4% 4.1%",
|
|
3567
|
+
"--card": "0 0% 100%",
|
|
3568
|
+
"--card-foreground": "224 71.4% 4.1%",
|
|
3569
|
+
"--popover": "0 0% 100%",
|
|
3570
|
+
"--popover-foreground": "224 71.4% 4.1%",
|
|
3571
|
+
"--primary": "262.1 83.3% 57.8%",
|
|
3572
|
+
"--primary-foreground": "210 20% 98%",
|
|
3573
|
+
"--secondary": "220 14.3% 95.9%",
|
|
3574
|
+
"--secondary-foreground": "220.9 39.3% 11%",
|
|
3575
|
+
"--muted": "220 14.3% 95.9%",
|
|
3576
|
+
"--muted-foreground": "220 8.9% 46.1%",
|
|
3577
|
+
"--accent": "220 14.3% 95.9%",
|
|
3578
|
+
"--accent-foreground": "220.9 39.3% 11%",
|
|
3579
|
+
"--destructive": "0 84.2% 60.2%",
|
|
3580
|
+
"--destructive-foreground": "210 20% 98%",
|
|
3581
|
+
"--border": "220 13% 91%",
|
|
3582
|
+
"--input": "220 13% 91%",
|
|
3583
|
+
"--ring": "262.1 83.3% 57.8%",
|
|
3584
|
+
"--radius": "0.5rem",
|
|
3585
|
+
"--chart-1": "12 76% 61%",
|
|
3586
|
+
"--chart-2": "173 58% 39%",
|
|
3587
|
+
"--chart-3": "197 37% 24%",
|
|
3588
|
+
"--chart-4": "43 74% 66%",
|
|
3589
|
+
"--chart-5": "27 87% 67%",
|
|
3590
|
+
"--sidebar": "221 39% 11%",
|
|
3591
|
+
"--sidebar-foreground": "0 0% 98%",
|
|
3592
|
+
"--sidebar-primary": "217.2 91.2% 59.8%",
|
|
3593
|
+
"--special": "227 21% 8%",
|
|
3594
|
+
"--special-muted-background": "240 10% 4%",
|
|
3595
|
+
"--special-border": "240 4% 16%",
|
|
3596
|
+
"--special-foreground": "240 5% 84%",
|
|
3597
|
+
"--special-muted-foreground": "240 4% 46%",
|
|
3598
|
+
},
|
|
3599
|
+
dark: {
|
|
3600
|
+
"--background": "224 71.4% 4.1%",
|
|
3601
|
+
"--foreground": "210 20% 98%",
|
|
3602
|
+
"--card": "224 71.4% 4.1%",
|
|
3603
|
+
"--card-foreground": "210 20% 98%",
|
|
3604
|
+
"--popover": "224 71.4% 4.1%",
|
|
3605
|
+
"--popover-foreground": "210 20% 98%",
|
|
3606
|
+
"--primary": "263.4 70% 50.4%",
|
|
3607
|
+
"--primary-foreground": "210 20% 98%",
|
|
3608
|
+
"--secondary": "215 27.9% 16.9%",
|
|
3609
|
+
"--secondary-foreground": "210 20% 98%",
|
|
3610
|
+
"--muted": "215 27.9% 16.9%",
|
|
3611
|
+
"--muted-foreground": "217.9 10.6% 64.9%",
|
|
3612
|
+
"--accent": "215 27.9% 16.9%",
|
|
3613
|
+
"--accent-foreground": "210 20% 98%",
|
|
3614
|
+
"--destructive": "0 62.8% 30.6%",
|
|
3615
|
+
"--destructive-foreground": "210 20% 98%",
|
|
3616
|
+
"--border": "215 27.9% 16.9%",
|
|
3617
|
+
"--input": "215 27.9% 16.9%",
|
|
3618
|
+
"--ring": "263.4 70% 50.4%",
|
|
3619
|
+
"--chart-1": "220 70% 50%",
|
|
3620
|
+
"--chart-2": "160 60% 45%",
|
|
3621
|
+
"--chart-3": "30 80% 55%",
|
|
3622
|
+
"--chart-4": "280 65% 60%",
|
|
3623
|
+
"--chart-5": "340 75% 55%",
|
|
3624
|
+
"--sidebar": "221 39% 11%",
|
|
3625
|
+
"--sidebar-foreground": "0 0% 98%",
|
|
3626
|
+
"--sidebar-primary": "217.2 91.2% 59.8%",
|
|
3627
|
+
"--special": "227 21% 8%",
|
|
3628
|
+
"--special-muted-background": "240 10% 4%",
|
|
3629
|
+
"--special-border": "240 4% 16%",
|
|
3630
|
+
"--special-foreground": "240 5% 84%",
|
|
3631
|
+
"--special-muted-foreground": "240 4% 46%",
|
|
3632
|
+
},
|
|
3633
|
+
},
|
|
3634
|
+
},
|
|
3635
|
+
};
|
|
3636
|
+
const DSA = forwardRef<
|
|
3637
|
+
React.ElementRef<typeof AvatarPrimitive.Root>,
|
|
3638
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
|
|
3639
|
+
>(({ className, ...props }, ref) => (
|
|
3640
|
+
<AvatarPrimitive.Root
|
|
3641
|
+
ref={ref}
|
|
3642
|
+
className={cn(
|
|
3643
|
+
'relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full',
|
|
3644
|
+
className
|
|
3645
|
+
)}
|
|
3646
|
+
{...props}
|
|
3647
|
+
/>
|
|
3648
|
+
))
|
|
3649
|
+
DSA.displayName = AvatarPrimitive.Root.displayName
|
|
3650
|
+
|
|
3651
|
+
const DSAImage = forwardRef<
|
|
3652
|
+
React.ElementRef<typeof AvatarPrimitive.Image>,
|
|
3653
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
|
|
3654
|
+
>(({ className, ...props }, ref) => (
|
|
3655
|
+
<AvatarPrimitive.Image
|
|
3656
|
+
ref={ref}
|
|
3657
|
+
className={cn('aspect-square h-full w-full', className)}
|
|
3658
|
+
{...props}
|
|
3659
|
+
/>
|
|
3660
|
+
))
|
|
3661
|
+
DSAImage.displayName = AvatarPrimitive.Image.displayName
|
|
3662
|
+
|
|
3663
|
+
const DSAFallback = forwardRef<
|
|
3664
|
+
React.ElementRef<typeof AvatarPrimitive.Fallback>,
|
|
3665
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
|
|
3666
|
+
>(({ className, ...props }, ref) => (
|
|
3667
|
+
<AvatarPrimitive.Fallback
|
|
3668
|
+
ref={ref}
|
|
3669
|
+
className={cn(
|
|
3670
|
+
'flex h-full w-full items-center justify-center rounded-full bg-muted',
|
|
3671
|
+
className
|
|
3672
|
+
)}
|
|
3673
|
+
{...props}
|
|
3674
|
+
/>
|
|
3675
|
+
))
|
|
3676
|
+
DSAFallback.displayName = AvatarPrimitive.Fallback.displayName
|
|
3677
|
+
|
|
3678
|
+
function DSDM({
|
|
3679
|
+
...props
|
|
3680
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
|
|
3681
|
+
return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />
|
|
3682
|
+
}
|
|
3683
|
+
|
|
3684
|
+
function DSDMPortal({
|
|
3685
|
+
...props
|
|
3686
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
|
|
3687
|
+
return (
|
|
3688
|
+
<DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
|
|
3689
|
+
)
|
|
3690
|
+
}
|
|
3691
|
+
|
|
3692
|
+
function DSDMTrigger({
|
|
3693
|
+
...props
|
|
3694
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
|
|
3695
|
+
return (
|
|
3696
|
+
<DropdownMenuPrimitive.Trigger
|
|
3697
|
+
data-slot="dropdown-menu-trigger"
|
|
3698
|
+
{...props}
|
|
3699
|
+
/>
|
|
3700
|
+
)
|
|
3701
|
+
}
|
|
3702
|
+
|
|
3703
|
+
function DSDMContent({
|
|
3704
|
+
className,
|
|
3705
|
+
sideOffset = 4,
|
|
3706
|
+
...props
|
|
3707
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
|
|
3708
|
+
return (
|
|
3709
|
+
<DropdownMenuPrimitive.Portal>
|
|
3710
|
+
<DropdownMenuPrimitive.Content
|
|
3711
|
+
data-slot="dropdown-menu-content"
|
|
3712
|
+
sideOffset={sideOffset}
|
|
3713
|
+
className={cn(
|
|
3714
|
+
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
|
|
3715
|
+
className
|
|
3716
|
+
)}
|
|
3717
|
+
{...props}
|
|
3718
|
+
/>
|
|
3719
|
+
</DropdownMenuPrimitive.Portal>
|
|
3720
|
+
)
|
|
3721
|
+
}
|
|
3722
|
+
|
|
3723
|
+
function DSDMGroup({
|
|
3724
|
+
...props
|
|
3725
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
|
|
3726
|
+
return (
|
|
3727
|
+
<DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
|
|
3728
|
+
)
|
|
3729
|
+
}
|
|
3730
|
+
|
|
3731
|
+
function DSDMItem({
|
|
3732
|
+
className,
|
|
3733
|
+
inset,
|
|
3734
|
+
variant = "default",
|
|
3735
|
+
...props
|
|
3736
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
|
|
3737
|
+
inset?: boolean
|
|
3738
|
+
variant?: "default" | "destructive"
|
|
3739
|
+
}) {
|
|
3740
|
+
|
|
3741
|
+
return (
|
|
3742
|
+
<DropdownMenuPrimitive.Item
|
|
3743
|
+
data-slot="dropdown-menu-item"
|
|
3744
|
+
data-inset={inset}
|
|
3745
|
+
data-variant={variant}
|
|
3746
|
+
className={cn(
|
|
3747
|
+
"focus:bg-accent focus:text-accent-foreground cursor-pointer data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
3748
|
+
className
|
|
3749
|
+
)}
|
|
3750
|
+
{...props}
|
|
3751
|
+
/>
|
|
3752
|
+
)
|
|
3753
|
+
}
|
|
3754
|
+
|
|
3755
|
+
function DSDMAnchor({
|
|
3756
|
+
className,
|
|
3757
|
+
children,
|
|
3758
|
+
to,
|
|
3759
|
+
variant = "default",
|
|
3760
|
+
newTab = true,
|
|
3761
|
+
...props
|
|
3762
|
+
}: {
|
|
3763
|
+
className?: string
|
|
3764
|
+
children: React.ReactNode
|
|
3765
|
+
to: string
|
|
3766
|
+
newTab?: boolean
|
|
3767
|
+
}) {
|
|
3768
|
+
const anchorProps = newTab ? {
|
|
3769
|
+
target: "_blank",
|
|
3770
|
+
rel: "noopener noreferrer"
|
|
3771
|
+
} : {};
|
|
3772
|
+
return (
|
|
3773
|
+
<a
|
|
3774
|
+
href={to}
|
|
3775
|
+
{...anchorProps}
|
|
3776
|
+
className={cn(className)}
|
|
3777
|
+
{...props}
|
|
3778
|
+
>
|
|
3779
|
+
<DSDMItem variant={variant}>
|
|
3780
|
+
<span className="flex-1 truncate">{children}</span>
|
|
3781
|
+
</DSDMItem>
|
|
3782
|
+
</a>
|
|
3783
|
+
);
|
|
3784
|
+
}
|
|
3785
|
+
|
|
3786
|
+
function DSDMCheckboxItem({
|
|
3787
|
+
className,
|
|
3788
|
+
children,
|
|
3789
|
+
checked,
|
|
3790
|
+
...props
|
|
3791
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
|
|
3792
|
+
return (
|
|
3793
|
+
<DropdownMenuPrimitive.CheckboxItem
|
|
3794
|
+
data-slot="dropdown-menu-checkbox-item"
|
|
3795
|
+
className={cn(
|
|
3796
|
+
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
3797
|
+
className
|
|
3798
|
+
)}
|
|
3799
|
+
checked={checked}
|
|
3800
|
+
{...props}
|
|
3801
|
+
>
|
|
3802
|
+
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
|
|
3803
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
3804
|
+
<Check className="size-4" />
|
|
3805
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
3806
|
+
</span>
|
|
3807
|
+
{children}
|
|
3808
|
+
</DropdownMenuPrimitive.CheckboxItem>
|
|
3809
|
+
)
|
|
3810
|
+
}
|
|
3811
|
+
|
|
3812
|
+
function DSDMRadioGroup({
|
|
3813
|
+
...props
|
|
3814
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
|
|
3815
|
+
return (
|
|
3816
|
+
<DropdownMenuPrimitive.RadioGroup
|
|
3817
|
+
data-slot="dropdown-menu-radio-group"
|
|
3818
|
+
{...props}
|
|
3819
|
+
/>
|
|
3820
|
+
)
|
|
3821
|
+
}
|
|
3822
|
+
|
|
3823
|
+
function DSDMRadioItem({
|
|
3824
|
+
className,
|
|
3825
|
+
children,
|
|
3826
|
+
...props
|
|
3827
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
|
|
3828
|
+
return (
|
|
3829
|
+
<DropdownMenuPrimitive.RadioItem
|
|
3830
|
+
data-slot="dropdown-menu-radio-item"
|
|
3831
|
+
className={cn(
|
|
3832
|
+
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
3833
|
+
className
|
|
3834
|
+
)}
|
|
3835
|
+
{...props}
|
|
3836
|
+
>
|
|
3837
|
+
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
|
|
3838
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
3839
|
+
<Circle className="size-2 fill-current" />
|
|
3840
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
3841
|
+
</span>
|
|
3842
|
+
{children}
|
|
3843
|
+
</DropdownMenuPrimitive.RadioItem>
|
|
3844
|
+
)
|
|
3845
|
+
}
|
|
3846
|
+
|
|
3847
|
+
function DSDMLabel({
|
|
3848
|
+
className,
|
|
3849
|
+
inset,
|
|
3850
|
+
...props
|
|
3851
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
|
|
3852
|
+
inset?: boolean
|
|
3853
|
+
}) {
|
|
3854
|
+
return (
|
|
3855
|
+
<DropdownMenuPrimitive.Label
|
|
3856
|
+
data-slot="dropdown-menu-label"
|
|
3857
|
+
data-inset={inset}
|
|
3858
|
+
className={cn(
|
|
3859
|
+
"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
|
|
3860
|
+
className
|
|
3861
|
+
)}
|
|
3862
|
+
{...props}
|
|
3863
|
+
/>
|
|
3864
|
+
)
|
|
3865
|
+
}
|
|
3866
|
+
|
|
3867
|
+
function DSDMSeparator({
|
|
3868
|
+
className,
|
|
3869
|
+
...props
|
|
3870
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
|
|
3871
|
+
return (
|
|
3872
|
+
<DropdownMenuPrimitive.Separator
|
|
3873
|
+
data-slot="dropdown-menu-separator"
|
|
3874
|
+
className={cn("bg-border -mx-1 my-1 h-px", className)}
|
|
3875
|
+
{...props}
|
|
3876
|
+
/>
|
|
3877
|
+
)
|
|
3878
|
+
}
|
|
3879
|
+
|
|
3880
|
+
function DSDMShortcut({
|
|
3881
|
+
className,
|
|
3882
|
+
...props
|
|
3883
|
+
}: React.ComponentProps<"span">) {
|
|
3884
|
+
return (
|
|
3885
|
+
<span
|
|
3886
|
+
data-slot="dropdown-menu-shortcut"
|
|
3887
|
+
className={cn(
|
|
3888
|
+
"text-muted-foreground ml-auto text-xs tracking-widest",
|
|
3889
|
+
className
|
|
3890
|
+
)}
|
|
3891
|
+
{...props}
|
|
3892
|
+
/>
|
|
3893
|
+
)
|
|
3894
|
+
}
|
|
3895
|
+
|
|
3896
|
+
function DSDMSub({
|
|
3897
|
+
...props
|
|
3898
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
|
|
3899
|
+
return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />
|
|
3900
|
+
}
|
|
3901
|
+
|
|
3902
|
+
function DSDMSubTrigger({
|
|
3903
|
+
className,
|
|
3904
|
+
inset,
|
|
3905
|
+
children,
|
|
3906
|
+
...props
|
|
3907
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
|
|
3908
|
+
inset?: boolean
|
|
3909
|
+
}) {
|
|
3910
|
+
return (
|
|
3911
|
+
<DropdownMenuPrimitive.SubTrigger
|
|
3912
|
+
data-slot="dropdown-menu-sub-trigger"
|
|
3913
|
+
data-inset={inset}
|
|
3914
|
+
className={cn(
|
|
3915
|
+
"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8",
|
|
3916
|
+
className
|
|
3917
|
+
)}
|
|
3918
|
+
{...props}
|
|
3919
|
+
>
|
|
3920
|
+
{children}
|
|
3921
|
+
<ChevronRight className="ml-auto size-4" />
|
|
3922
|
+
</DropdownMenuPrimitive.SubTrigger>
|
|
3923
|
+
)
|
|
3924
|
+
}
|
|
3925
|
+
|
|
3926
|
+
function DSDMSubContent({
|
|
3927
|
+
className,
|
|
3928
|
+
...props
|
|
3929
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
|
|
3930
|
+
return (
|
|
3931
|
+
<DropdownMenuPrimitive.SubContent
|
|
3932
|
+
data-slot="dropdown-menu-sub-content"
|
|
3933
|
+
className={cn(
|
|
3934
|
+
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg",
|
|
3935
|
+
className
|
|
3936
|
+
)}
|
|
3937
|
+
{...props}
|
|
3938
|
+
/>
|
|
3939
|
+
)
|
|
3940
|
+
}
|
|
3941
|
+
const DSC = CollapsiblePrimitive.Root;
|
|
3942
|
+
const DSCTrigger = CollapsiblePrimitive.CollapsibleTrigger;
|
|
3943
|
+
|
|
3944
|
+
interface CollapsibleContentProps
|
|
3945
|
+
extends React.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.CollapsibleContent> { }
|
|
3946
|
+
|
|
3947
|
+
const DSCContent = forwardRef<
|
|
3948
|
+
React.ElementRef<typeof CollapsiblePrimitive.CollapsibleContent>,
|
|
3949
|
+
CollapsibleContentProps
|
|
3950
|
+
>(({ className, ...props }, ref) => {
|
|
3951
|
+
return (
|
|
3952
|
+
<CollapsiblePrimitive.CollapsibleContent
|
|
3953
|
+
ref={ref}
|
|
3954
|
+
className={cn(
|
|
3955
|
+
"text-border",
|
|
3956
|
+
className
|
|
3957
|
+
)}
|
|
3958
|
+
{...props}
|
|
3959
|
+
/>
|
|
3960
|
+
);
|
|
3961
|
+
});
|
|
3962
|
+
DSCContent.displayName = "DSCContent";
|
|
3963
|
+
const data = {
|
|
3964
|
+
nav: [
|
|
3965
|
+
{ name: "Notifications", icon: Bell },
|
|
3966
|
+
{ name: "Navigation", icon: Menu },
|
|
3967
|
+
{ name: "Home", icon: Home },
|
|
3968
|
+
{ name: "Appearance", icon: Paintbrush },
|
|
3969
|
+
{ name: "Messages & media", icon: MessageCircle },
|
|
3970
|
+
{ name: "Language & region", icon: Globe },
|
|
3971
|
+
{ name: "Accessibility", icon: Keyboard },
|
|
3972
|
+
{ name: "Mark as read", icon: Check },
|
|
3973
|
+
{ name: "Audio & video", icon: Video },
|
|
3974
|
+
{ name: "Connected accounts", icon: Link },
|
|
3975
|
+
{ name: "Privacy & visibility", icon: Lock },
|
|
3976
|
+
{ name: "Advanced", icon: Settings },
|
|
3977
|
+
],
|
|
3978
|
+
}
|
|
3979
|
+
export function DialogSidebar() {
|
|
3980
|
+
const [open, setOpen] = useState(false)
|
|
3981
|
+
|
|
3982
|
+
return (
|
|
3983
|
+
<Dialog open={open} onOpenChange={setOpen}>
|
|
3984
|
+
<DialogTrigger asChild>
|
|
3985
|
+
<DSMenuButton className="px-2.5 md:px-2"><Bot /></DSMenuButton>
|
|
3986
|
+
</DialogTrigger>
|
|
3987
|
+
<DialogContent className="overflow-hidden p-0 md:max-h-[500px] md:max-w-[700px] lg:max-w-[800px]">
|
|
3988
|
+
<DialogTitle className="sr-only">Settings</DialogTitle>
|
|
3989
|
+
<DialogDescription className="sr-only">
|
|
3990
|
+
Customize your settings here.
|
|
3991
|
+
</DialogDescription>
|
|
3992
|
+
<SidebarProvider className="items-start">
|
|
3993
|
+
<Sidebar collapsible="none" className="hidden md:flex">
|
|
3994
|
+
<SidebarContent>
|
|
3995
|
+
<SidebarGroup>
|
|
3996
|
+
<SidebarGroupContent>
|
|
3997
|
+
<SidebarMenu>
|
|
3998
|
+
{data.nav.map((item) => (
|
|
3999
|
+
<SidebarMenuItem key={item.name}>
|
|
4000
|
+
<SidebarMenuButton
|
|
4001
|
+
asChild
|
|
4002
|
+
isActive={item.name === "Messages & media"}
|
|
4003
|
+
>
|
|
4004
|
+
<a href="#">
|
|
4005
|
+
<item.icon />
|
|
4006
|
+
<span>{item.name}</span>
|
|
4007
|
+
</a>
|
|
4008
|
+
</SidebarMenuButton>
|
|
4009
|
+
</SidebarMenuItem>
|
|
4010
|
+
))}
|
|
4011
|
+
</SidebarMenu>
|
|
4012
|
+
</SidebarGroupContent>
|
|
4013
|
+
</SidebarGroup>
|
|
4014
|
+
</SidebarContent>
|
|
4015
|
+
</Sidebar>
|
|
4016
|
+
<main className="flex h-[480px] flex-1 flex-col overflow-hidden">
|
|
4017
|
+
<header className="flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-12">
|
|
4018
|
+
<div className="flex items-center gap-2 px-4">
|
|
4019
|
+
<Breadcrumb>
|
|
4020
|
+
<BreadcrumbList>
|
|
4021
|
+
<BreadcrumbItem className="hidden md:block">
|
|
4022
|
+
<BreadcrumbLink href="#">Settings</BreadcrumbLink>
|
|
4023
|
+
</BreadcrumbItem>
|
|
4024
|
+
<BreadcrumbSeparator className="hidden md:block" />
|
|
4025
|
+
<BreadcrumbItem>
|
|
4026
|
+
<BreadcrumbPage>Messages & media</BreadcrumbPage>
|
|
4027
|
+
</BreadcrumbItem>
|
|
4028
|
+
</BreadcrumbList>
|
|
4029
|
+
</Breadcrumb>
|
|
4030
|
+
</div>
|
|
4031
|
+
</header>
|
|
4032
|
+
<div className="flex flex-1 flex-col gap-4 overflow-y-auto p-4 pt-0">
|
|
4033
|
+
{Array.from({ length: 10 }).map((_, i) => (
|
|
4034
|
+
<div
|
|
4035
|
+
key={i}
|
|
4036
|
+
className="bg-muted/50 aspect-video max-w-3xl rounded-xl"
|
|
4037
|
+
/>
|
|
4038
|
+
))}
|
|
4039
|
+
</div>
|
|
4040
|
+
</main>
|
|
4041
|
+
</SidebarProvider>
|
|
4042
|
+
</DialogContent>
|
|
4043
|
+
</Dialog>
|
|
4044
|
+
)
|
|
4045
|
+
}
|
|
4046
|
+
|
|
4047
|
+
export {
|
|
4048
|
+
// DS stands for DualSidebar
|
|
4049
|
+
// use sidebar
|
|
4050
|
+
useDS,
|
|
4051
|
+
// sidebar rails
|
|
4052
|
+
DSLeftRail,
|
|
4053
|
+
DSRightRail,
|
|
4054
|
+
// sidebar layouts
|
|
4055
|
+
DSHeader,
|
|
4056
|
+
DSContent,
|
|
4057
|
+
DSFooter,
|
|
4058
|
+
// sidebar avatar
|
|
4059
|
+
DSA,
|
|
4060
|
+
DSAImage,
|
|
4061
|
+
DSAFallback,
|
|
4062
|
+
// sidebar menu items
|
|
4063
|
+
DSGroup,
|
|
4064
|
+
DSGroupAction,
|
|
4065
|
+
DSGroupContent,
|
|
4066
|
+
DSGroupLabel,
|
|
4067
|
+
DSInput,
|
|
4068
|
+
DSMenu,
|
|
4069
|
+
DSMenuAction,
|
|
4070
|
+
DSMenuBadge,
|
|
4071
|
+
DSMenuButton,
|
|
4072
|
+
DSMenuItem,
|
|
4073
|
+
DSMenuSkeleton,
|
|
4074
|
+
DSMenuSub,
|
|
4075
|
+
DSMenuSubButton,
|
|
4076
|
+
DSMenuSubItem,
|
|
4077
|
+
DSSeparator,
|
|
4078
|
+
// optimistic ui nav links and loading ui
|
|
4079
|
+
DSMenuAnchor,
|
|
4080
|
+
DSMenuLink,
|
|
4081
|
+
DSLoading,
|
|
4082
|
+
// theme selector
|
|
4083
|
+
useDSTheme,
|
|
4084
|
+
DSThemeSelector,
|
|
4085
|
+
type DSTheme,
|
|
4086
|
+
DSThemeProvider,
|
|
4087
|
+
// sidebar provider
|
|
4088
|
+
DSProvider,
|
|
4089
|
+
// sidebar inset
|
|
4090
|
+
DSInset,
|
|
4091
|
+
// left trigger
|
|
4092
|
+
DSTrigger,
|
|
4093
|
+
// left sidebar
|
|
4094
|
+
DSLeft,
|
|
4095
|
+
DSLeftIcon,
|
|
4096
|
+
// right sidebar
|
|
4097
|
+
DSRight,
|
|
4098
|
+
DSRightIcon,
|
|
4099
|
+
// DSD stands for DualSidebarDrawer
|
|
4100
|
+
DSD,
|
|
4101
|
+
DSDTrigger,
|
|
4102
|
+
DSDPortal,
|
|
4103
|
+
DSDClose,
|
|
4104
|
+
DSDOverlay,
|
|
4105
|
+
DSDContent,
|
|
4106
|
+
DSDHeader,
|
|
4107
|
+
DSDFooter,
|
|
4108
|
+
DSDTitle,
|
|
4109
|
+
DSDDescription,
|
|
4110
|
+
// DSDM
|
|
4111
|
+
DSDM,
|
|
4112
|
+
DSDMPortal,
|
|
4113
|
+
DSDMTrigger,
|
|
4114
|
+
DSDMContent,
|
|
4115
|
+
DSDMGroup,
|
|
4116
|
+
DSDMLabel,
|
|
4117
|
+
DSDMItem,
|
|
4118
|
+
DSDMCheckboxItem,
|
|
4119
|
+
DSDMRadioGroup,
|
|
4120
|
+
DSDMRadioItem,
|
|
4121
|
+
DSDMSeparator,
|
|
4122
|
+
DSDMShortcut,
|
|
4123
|
+
DSDMSub,
|
|
4124
|
+
DSDMSubTrigger,
|
|
4125
|
+
DSDMSubContent,
|
|
4126
|
+
DSDMAnchor,
|
|
4127
|
+
// Collapsible
|
|
4128
|
+
DSC,
|
|
4129
|
+
DSCTrigger,
|
|
4130
|
+
DSCContent,
|
|
4131
|
+
DS_COOKIE_NAME,
|
|
4132
|
+
DS_COOKIE_NAME_RIGHT,
|
|
4133
|
+
DS_COOKIE_MAX_AGE,
|
|
4134
|
+
DS_WIDTH,
|
|
4135
|
+
DS_WIDTH_MOBILE,
|
|
4136
|
+
DS_WIDTH_ICON,
|
|
4137
|
+
DS_KEYBOARD_SHORTCUT_LEFT,
|
|
4138
|
+
DS_KEYBOARD_SHORTCUT_RIGHT,
|
|
4139
|
+
THEME_VERSION,
|
|
4140
|
+
THEME_OPTIONS,
|
|
4141
|
+
LOCAL_DS_STORAGE_KEY,
|
|
4142
|
+
};
|