create-bluecopa-react-app 1.0.41 → 1.0.43
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/README.md +7 -5
- package/package.json +1 -1
- package/templates/latest/.claude/settings.local.json +56 -0
- package/templates/latest/.env.example +8 -0
- package/templates/latest/Agent.md +598 -775
- package/templates/latest/CLAUDE.md +759 -0
- package/templates/latest/README.md +11 -2
- package/templates/latest/app/app.css +292 -85
- package/templates/latest/app/app.tsx +48 -39
- package/templates/latest/app/components/bluecopa-logo.tsx +20 -0
- package/templates/latest/app/components/charts/bar-chart.tsx +132 -0
- package/templates/latest/app/components/charts/base-chart.tsx +149 -0
- package/templates/latest/app/components/charts/chart-provider.tsx +71 -0
- package/templates/latest/app/components/charts/chart-theme.ts +262 -0
- package/templates/latest/app/components/charts/chart-utils.ts +142 -0
- package/templates/latest/app/components/charts/donut-chart.tsx +110 -0
- package/templates/latest/app/components/charts/index.ts +5 -0
- package/templates/latest/app/components/layouts/app-layout.tsx +22 -0
- package/templates/latest/app/components/layouts/app-sidebar.tsx +88 -0
- package/templates/latest/app/components/layouts/nav-main.tsx +50 -0
- package/templates/latest/app/components/layouts/nav-user.tsx +38 -0
- package/templates/latest/app/components/layouts/site-header.tsx +93 -0
- package/templates/latest/app/components/loading-screen.tsx +41 -0
- package/templates/latest/app/components/ui/ag-grid-table.tsx +79 -0
- package/templates/latest/app/components/ui/button.tsx +23 -23
- package/templates/latest/app/components/ui/card.tsx +20 -20
- package/templates/latest/app/components/ui/dropdown-menu.tsx +54 -49
- package/templates/latest/app/components/ui/input.tsx +8 -8
- package/templates/latest/app/components/ui/label.tsx +8 -8
- package/templates/latest/app/components/ui/separator.tsx +7 -7
- package/templates/latest/app/components/ui/sheet.tsx +43 -32
- package/templates/latest/app/components/ui/sidebar.tsx +240 -235
- package/templates/latest/app/components/ui/skeleton.tsx +4 -4
- package/templates/latest/app/components/ui/sonner.tsx +6 -9
- package/templates/latest/app/components/ui/tabs.tsx +15 -15
- package/templates/latest/app/components/ui/tooltip.tsx +18 -12
- package/templates/latest/app/constants/index.ts +31 -0
- package/templates/latest/app/contexts/app-context.tsx +201 -0
- package/templates/latest/app/hooks/use-mobile.ts +13 -12
- package/templates/latest/app/main.tsx +1 -1
- package/templates/latest/app/pages/dashboard.tsx +246 -0
- package/templates/latest/app/pages/payments.tsx +182 -0
- package/templates/latest/app/pages/settings.tsx +128 -0
- package/templates/latest/app/routes/index.tsx +19 -0
- package/templates/latest/app/single-spa.tsx +69 -186
- package/templates/latest/app/types/index.ts +37 -0
- package/templates/latest/app/utils/ag-grid-datasource.ts +63 -0
- package/templates/latest/app/utils/ag-grid-license.ts +12 -0
- package/templates/latest/app/utils/ag-grid-theme.ts +9 -0
- package/templates/latest/app/utils/component-style.ts +7 -0
- package/templates/latest/app/utils/style-drivers.ts +24 -0
- package/templates/latest/app/utils/utils.ts +10 -0
- package/templates/latest/components.json +3 -3
- package/templates/latest/index.html +30 -2
- package/templates/latest/package-lock.json +2717 -955
- package/templates/latest/package.json +19 -21
- package/templates/latest/preview/index.html +125 -285
- package/templates/latest/public/favicon.svg +1 -0
- package/templates/latest/vite.config.ts +2 -8
- package/templates/latest/app/components/app-sidebar.tsx +0 -182
- package/templates/latest/app/components/chart-area-interactive.tsx +0 -290
- package/templates/latest/app/components/data-table.tsx +0 -807
- package/templates/latest/app/components/nav-documents.tsx +0 -92
- package/templates/latest/app/components/nav-main.tsx +0 -40
- package/templates/latest/app/components/nav-secondary.tsx +0 -42
- package/templates/latest/app/components/nav-user.tsx +0 -111
- package/templates/latest/app/components/section-cards.tsx +0 -102
- package/templates/latest/app/components/site-header.tsx +0 -28
- package/templates/latest/app/components/ui/avatar.tsx +0 -53
- package/templates/latest/app/components/ui/badge.tsx +0 -46
- package/templates/latest/app/components/ui/breadcrumb.tsx +0 -109
- package/templates/latest/app/components/ui/chart.tsx +0 -352
- package/templates/latest/app/components/ui/checkbox.tsx +0 -30
- package/templates/latest/app/components/ui/drawer.tsx +0 -139
- package/templates/latest/app/components/ui/select.tsx +0 -183
- package/templates/latest/app/components/ui/table.tsx +0 -117
- package/templates/latest/app/components/ui/toggle-group.tsx +0 -73
- package/templates/latest/app/components/ui/toggle.tsx +0 -47
- package/templates/latest/app/data/data.json +0 -614
- package/templates/latest/app/data/mock-payments.json +0 -122
- package/templates/latest/app/data/mock-transactions.json +0 -128
- package/templates/latest/app/hooks/use-bluecopa-user.ts +0 -37
- package/templates/latest/app/lib/utils.ts +0 -6
- package/templates/latest/app/routes/apitest.tsx +0 -2118
- package/templates/latest/app/routes/comments.tsx +0 -588
- package/templates/latest/app/routes/dashboard.tsx +0 -36
- package/templates/latest/app/routes/payments.tsx +0 -342
- package/templates/latest/app/routes/statements.tsx +0 -493
- package/templates/latest/app/routes/websocket.tsx +0 -450
- package/templates/latest/app/routes.tsx +0 -22
- package/templates/latest/dist/assets/__federation_expose_App-D-lv9y21.js +0 -161
- package/templates/latest/dist/assets/__federation_fn_import-CzfA7kmP.js +0 -438
- package/templates/latest/dist/assets/__federation_shared_react-Bp6HVBS4.js +0 -16
- package/templates/latest/dist/assets/__federation_shared_react-dom-BCcRGiYp.js +0 -17
- package/templates/latest/dist/assets/client-Dms8K6Dw.js +0 -78879
- package/templates/latest/dist/assets/index-BrhXrqF7.js +0 -60
- package/templates/latest/dist/assets/index-BzNimew1.js +0 -69
- package/templates/latest/dist/assets/index-DMFtQdNS.js +0 -412
- package/templates/latest/dist/assets/remoteEntry.css +0 -3996
- package/templates/latest/dist/assets/remoteEntry.js +0 -88
- package/templates/latest/dist/favicon.ico +0 -0
- package/templates/latest/dist/index.html +0 -19
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import * as React from "react"
|
|
4
|
-
import { Slot } from "@radix-ui/react-slot"
|
|
5
|
-
import { cva, type VariantProps } from "class-variance-authority"
|
|
6
|
-
import { PanelLeftIcon } from "lucide-react"
|
|
7
|
-
|
|
8
|
-
import { useIsMobile } from "~/hooks/use-mobile"
|
|
9
|
-
import { cn } from "~/
|
|
10
|
-
import { Button } from "~/components/ui/button"
|
|
11
|
-
import { Input } from "~/components/ui/input"
|
|
12
|
-
import { Separator } from "~/components/ui/separator"
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
5
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
6
|
+
import { PanelLeftIcon } from "lucide-react";
|
|
7
|
+
|
|
8
|
+
import { useIsMobile } from "~/hooks/use-mobile";
|
|
9
|
+
import { cn } from "~/utils/utils";
|
|
10
|
+
import { Button } from "~/components/ui/button";
|
|
11
|
+
import { Input } from "~/components/ui/input";
|
|
12
|
+
import { Separator } from "~/components/ui/separator";
|
|
13
13
|
import {
|
|
14
14
|
Sheet,
|
|
15
15
|
SheetContent,
|
|
16
16
|
SheetDescription,
|
|
17
17
|
SheetHeader,
|
|
18
18
|
SheetTitle,
|
|
19
|
-
} from "~/components/ui/sheet"
|
|
20
|
-
import { Skeleton } from "~/components/ui/skeleton"
|
|
19
|
+
} from "~/components/ui/sheet";
|
|
20
|
+
import { Skeleton } from "~/components/ui/skeleton";
|
|
21
21
|
import {
|
|
22
22
|
Tooltip,
|
|
23
23
|
TooltipContent,
|
|
24
24
|
TooltipProvider,
|
|
25
25
|
TooltipTrigger,
|
|
26
|
-
} from "~/components/ui/tooltip"
|
|
26
|
+
} from "~/components/ui/tooltip";
|
|
27
27
|
|
|
28
|
-
const SIDEBAR_COOKIE_NAME = "sidebar_state"
|
|
29
|
-
const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7
|
|
30
|
-
const SIDEBAR_WIDTH = "16rem"
|
|
31
|
-
const SIDEBAR_WIDTH_MOBILE = "18rem"
|
|
32
|
-
const SIDEBAR_WIDTH_ICON = "3rem"
|
|
33
|
-
const SIDEBAR_KEYBOARD_SHORTCUT = "b"
|
|
28
|
+
const SIDEBAR_COOKIE_NAME = "sidebar_state";
|
|
29
|
+
const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
|
|
30
|
+
const SIDEBAR_WIDTH = "16rem";
|
|
31
|
+
const SIDEBAR_WIDTH_MOBILE = "18rem";
|
|
32
|
+
const SIDEBAR_WIDTH_ICON = "3rem";
|
|
33
|
+
const SIDEBAR_KEYBOARD_SHORTCUT = "b";
|
|
34
34
|
|
|
35
35
|
type SidebarContextProps = {
|
|
36
|
-
state: "expanded" | "collapsed"
|
|
37
|
-
open: boolean
|
|
38
|
-
setOpen: (open: boolean) => void
|
|
39
|
-
openMobile: boolean
|
|
40
|
-
setOpenMobile: (open: boolean) => void
|
|
41
|
-
isMobile: boolean
|
|
42
|
-
toggleSidebar: () => void
|
|
43
|
-
}
|
|
36
|
+
state: "expanded" | "collapsed";
|
|
37
|
+
open: boolean;
|
|
38
|
+
setOpen: (open: boolean) => void;
|
|
39
|
+
openMobile: boolean;
|
|
40
|
+
setOpenMobile: (open: boolean) => void;
|
|
41
|
+
isMobile: boolean;
|
|
42
|
+
toggleSidebar: () => void;
|
|
43
|
+
};
|
|
44
44
|
|
|
45
|
-
const SidebarContext = React.createContext<SidebarContextProps | null>(null)
|
|
45
|
+
const SidebarContext = React.createContext<SidebarContextProps | null>(null);
|
|
46
46
|
|
|
47
47
|
function useSidebar() {
|
|
48
|
-
const context = React.useContext(SidebarContext)
|
|
48
|
+
const context = React.useContext(SidebarContext);
|
|
49
49
|
if (!context) {
|
|
50
|
-
throw new Error("useSidebar must be used within a SidebarProvider.")
|
|
50
|
+
throw new Error("useSidebar must be used within a SidebarProvider.");
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
return context
|
|
53
|
+
return context;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
function SidebarProvider({
|
|
@@ -62,36 +62,36 @@ function SidebarProvider({
|
|
|
62
62
|
children,
|
|
63
63
|
...props
|
|
64
64
|
}: React.ComponentProps<"div"> & {
|
|
65
|
-
defaultOpen?: boolean
|
|
66
|
-
open?: boolean
|
|
67
|
-
onOpenChange?: (open: boolean) => void
|
|
65
|
+
defaultOpen?: boolean;
|
|
66
|
+
open?: boolean;
|
|
67
|
+
onOpenChange?: (open: boolean) => void;
|
|
68
68
|
}) {
|
|
69
|
-
const isMobile = useIsMobile()
|
|
70
|
-
const [openMobile, setOpenMobile] = React.useState(false)
|
|
69
|
+
const isMobile = useIsMobile();
|
|
70
|
+
const [openMobile, setOpenMobile] = React.useState(false);
|
|
71
71
|
|
|
72
72
|
// This is the internal state of the sidebar.
|
|
73
73
|
// We use openProp and setOpenProp for control from outside the component.
|
|
74
|
-
const [_open, _setOpen] = React.useState(defaultOpen)
|
|
75
|
-
const open = openProp ?? _open
|
|
74
|
+
const [_open, _setOpen] = React.useState(defaultOpen);
|
|
75
|
+
const open = openProp ?? _open;
|
|
76
76
|
const setOpen = React.useCallback(
|
|
77
77
|
(value: boolean | ((value: boolean) => boolean)) => {
|
|
78
|
-
const openState = typeof value === "function" ? value(open) : value
|
|
78
|
+
const openState = typeof value === "function" ? value(open) : value;
|
|
79
79
|
if (setOpenProp) {
|
|
80
|
-
setOpenProp(openState)
|
|
80
|
+
setOpenProp(openState);
|
|
81
81
|
} else {
|
|
82
|
-
_setOpen(openState)
|
|
82
|
+
_setOpen(openState);
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
// This sets the cookie to keep the sidebar state.
|
|
86
|
-
document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}
|
|
86
|
+
document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
|
|
87
87
|
},
|
|
88
|
-
[setOpenProp, open]
|
|
89
|
-
)
|
|
88
|
+
[setOpenProp, open],
|
|
89
|
+
);
|
|
90
90
|
|
|
91
91
|
// Helper to toggle the sidebar.
|
|
92
92
|
const toggleSidebar = React.useCallback(() => {
|
|
93
|
-
return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)
|
|
94
|
-
}, [isMobile, setOpen, setOpenMobile])
|
|
93
|
+
return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);
|
|
94
|
+
}, [isMobile, setOpen, setOpenMobile]);
|
|
95
95
|
|
|
96
96
|
// Adds a keyboard shortcut to toggle the sidebar.
|
|
97
97
|
React.useEffect(() => {
|
|
@@ -100,18 +100,18 @@ function SidebarProvider({
|
|
|
100
100
|
event.key === SIDEBAR_KEYBOARD_SHORTCUT &&
|
|
101
101
|
(event.metaKey || event.ctrlKey)
|
|
102
102
|
) {
|
|
103
|
-
event.preventDefault()
|
|
104
|
-
toggleSidebar()
|
|
103
|
+
event.preventDefault();
|
|
104
|
+
toggleSidebar();
|
|
105
105
|
}
|
|
106
|
-
}
|
|
106
|
+
};
|
|
107
107
|
|
|
108
|
-
window.addEventListener("keydown", handleKeyDown)
|
|
109
|
-
return () => window.removeEventListener("keydown", handleKeyDown)
|
|
110
|
-
}, [toggleSidebar])
|
|
108
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
109
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
110
|
+
}, [toggleSidebar]);
|
|
111
111
|
|
|
112
112
|
// We add a state so that we can do data-state="expanded" or "collapsed".
|
|
113
113
|
// This makes it easier to style the sidebar with Tailwind classes.
|
|
114
|
-
const state = open ? "expanded" : "collapsed"
|
|
114
|
+
const state = open ? "expanded" : "collapsed";
|
|
115
115
|
|
|
116
116
|
const contextValue = React.useMemo<SidebarContextProps>(
|
|
117
117
|
() => ({
|
|
@@ -123,8 +123,8 @@ function SidebarProvider({
|
|
|
123
123
|
setOpenMobile,
|
|
124
124
|
toggleSidebar,
|
|
125
125
|
}),
|
|
126
|
-
[state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
|
|
127
|
-
)
|
|
126
|
+
[state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar],
|
|
127
|
+
);
|
|
128
128
|
|
|
129
129
|
return (
|
|
130
130
|
<SidebarContext.Provider value={contextValue}>
|
|
@@ -139,8 +139,8 @@ function SidebarProvider({
|
|
|
139
139
|
} as React.CSSProperties
|
|
140
140
|
}
|
|
141
141
|
className={cn(
|
|
142
|
-
"group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full",
|
|
143
|
-
className
|
|
142
|
+
"copa:group/sidebar-wrapper copa:has-data-[variant=inset]:bg-sidebar copa:flex copa:min-h-svh copa:w-full",
|
|
143
|
+
className,
|
|
144
144
|
)}
|
|
145
145
|
{...props}
|
|
146
146
|
>
|
|
@@ -148,7 +148,7 @@ function SidebarProvider({
|
|
|
148
148
|
</div>
|
|
149
149
|
</TooltipProvider>
|
|
150
150
|
</SidebarContext.Provider>
|
|
151
|
-
)
|
|
151
|
+
);
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
function Sidebar({
|
|
@@ -159,25 +159,25 @@ function Sidebar({
|
|
|
159
159
|
children,
|
|
160
160
|
...props
|
|
161
161
|
}: React.ComponentProps<"div"> & {
|
|
162
|
-
side?: "left" | "right"
|
|
163
|
-
variant?: "sidebar" | "floating" | "inset"
|
|
164
|
-
collapsible?: "offcanvas" | "icon" | "none"
|
|
162
|
+
side?: "left" | "right";
|
|
163
|
+
variant?: "sidebar" | "floating" | "inset";
|
|
164
|
+
collapsible?: "offcanvas" | "icon" | "none";
|
|
165
165
|
}) {
|
|
166
|
-
const { isMobile, state, openMobile, setOpenMobile } = useSidebar()
|
|
166
|
+
const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
|
|
167
167
|
|
|
168
168
|
if (collapsible === "none") {
|
|
169
169
|
return (
|
|
170
170
|
<div
|
|
171
171
|
data-slot="sidebar"
|
|
172
172
|
className={cn(
|
|
173
|
-
"bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col",
|
|
174
|
-
className
|
|
173
|
+
"copa:bg-sidebar copa:text-sidebar-foreground copa:flex copa:h-full copa:w-(--sidebar-width) copa:flex-col",
|
|
174
|
+
className,
|
|
175
175
|
)}
|
|
176
176
|
{...props}
|
|
177
177
|
>
|
|
178
178
|
{children}
|
|
179
179
|
</div>
|
|
180
|
-
)
|
|
180
|
+
);
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
if (isMobile) {
|
|
@@ -187,7 +187,7 @@ function Sidebar({
|
|
|
187
187
|
data-sidebar="sidebar"
|
|
188
188
|
data-slot="sidebar"
|
|
189
189
|
data-mobile="true"
|
|
190
|
-
className="bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden"
|
|
190
|
+
className="copa:bg-sidebar copa:text-sidebar-foreground copa:w-(--sidebar-width) copa:p-0 copa:[&>button]:hidden"
|
|
191
191
|
style={
|
|
192
192
|
{
|
|
193
193
|
"--sidebar-width": SIDEBAR_WIDTH_MOBILE,
|
|
@@ -195,19 +195,19 @@ function Sidebar({
|
|
|
195
195
|
}
|
|
196
196
|
side={side}
|
|
197
197
|
>
|
|
198
|
-
<SheetHeader className="sr-only">
|
|
198
|
+
<SheetHeader className="copa:sr-only">
|
|
199
199
|
<SheetTitle>Sidebar</SheetTitle>
|
|
200
200
|
<SheetDescription>Displays the mobile sidebar.</SheetDescription>
|
|
201
201
|
</SheetHeader>
|
|
202
|
-
<div className="flex h-full w-full flex-col">{children}</div>
|
|
202
|
+
<div className="copa:flex copa:h-full copa:w-full copa:flex-col">{children}</div>
|
|
203
203
|
</SheetContent>
|
|
204
204
|
</Sheet>
|
|
205
|
-
)
|
|
205
|
+
);
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
return (
|
|
209
209
|
<div
|
|
210
|
-
className="group peer text-sidebar-foreground hidden md:block"
|
|
210
|
+
className="copa:group copa:peer copa:text-sidebar-foreground copa:hidden copa:md:block"
|
|
211
211
|
data-state={state}
|
|
212
212
|
data-collapsible={state === "collapsed" ? collapsible : ""}
|
|
213
213
|
data-variant={variant}
|
|
@@ -218,39 +218,39 @@ function Sidebar({
|
|
|
218
218
|
<div
|
|
219
219
|
data-slot="sidebar-gap"
|
|
220
220
|
className={cn(
|
|
221
|
-
"relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear",
|
|
222
|
-
"group-data-[collapsible=offcanvas]:w-0",
|
|
223
|
-
"group-data-[side=right]:rotate-180",
|
|
221
|
+
"copa:relative copa:w-(--sidebar-width) copa:bg-transparent copa:transition-[width] copa:duration-200 copa:ease-linear",
|
|
222
|
+
"copa:group-data-[collapsible=offcanvas]:w-0",
|
|
223
|
+
"copa:group-data-[side=right]:rotate-180",
|
|
224
224
|
variant === "floating" || variant === "inset"
|
|
225
|
-
? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]"
|
|
226
|
-
: "group-data-[collapsible=icon]:w-(--sidebar-width-icon)"
|
|
225
|
+
? "copa:group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]"
|
|
226
|
+
: "copa:group-data-[collapsible=icon]:w-(--sidebar-width-icon)",
|
|
227
227
|
)}
|
|
228
228
|
/>
|
|
229
229
|
<div
|
|
230
230
|
data-slot="sidebar-container"
|
|
231
231
|
className={cn(
|
|
232
|
-
"fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex",
|
|
232
|
+
"copa:fixed copa:inset-y-0 copa:z-10 copa:hidden copa:h-svh copa:w-(--sidebar-width) copa:transition-[left,right,width] copa:duration-200 copa:ease-linear copa:md:flex",
|
|
233
233
|
side === "left"
|
|
234
|
-
? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]"
|
|
235
|
-
: "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]",
|
|
234
|
+
? "copa:left-0 copa:group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]"
|
|
235
|
+
: "copa:right-0 copa:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]",
|
|
236
236
|
// Adjust the padding for floating and inset variants.
|
|
237
237
|
variant === "floating" || variant === "inset"
|
|
238
|
-
? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]"
|
|
239
|
-
: "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",
|
|
240
|
-
className
|
|
238
|
+
? "copa:p-2 copa:group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]"
|
|
239
|
+
: "copa:group-data-[collapsible=icon]:w-(--sidebar-width-icon) copa:group-data-[side=left]:border-r copa:group-data-[side=right]:border-l",
|
|
240
|
+
className,
|
|
241
241
|
)}
|
|
242
242
|
{...props}
|
|
243
243
|
>
|
|
244
244
|
<div
|
|
245
245
|
data-sidebar="sidebar"
|
|
246
246
|
data-slot="sidebar-inner"
|
|
247
|
-
className="bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm"
|
|
247
|
+
className="copa:bg-sidebar copa:group-data-[variant=floating]:border-sidebar-border copa:flex copa:h-full copa:w-full copa:flex-col copa:group-data-[variant=floating]:rounded-lg copa:group-data-[variant=floating]:border copa:group-data-[variant=floating]:shadow-sm"
|
|
248
248
|
>
|
|
249
249
|
{children}
|
|
250
250
|
</div>
|
|
251
251
|
</div>
|
|
252
252
|
</div>
|
|
253
|
-
)
|
|
253
|
+
);
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
function SidebarTrigger({
|
|
@@ -258,7 +258,7 @@ function SidebarTrigger({
|
|
|
258
258
|
onClick,
|
|
259
259
|
...props
|
|
260
260
|
}: React.ComponentProps<typeof Button>) {
|
|
261
|
-
const { toggleSidebar } = useSidebar()
|
|
261
|
+
const { toggleSidebar } = useSidebar();
|
|
262
262
|
|
|
263
263
|
return (
|
|
264
264
|
<Button
|
|
@@ -266,21 +266,21 @@ function SidebarTrigger({
|
|
|
266
266
|
data-slot="sidebar-trigger"
|
|
267
267
|
variant="ghost"
|
|
268
268
|
size="icon"
|
|
269
|
-
className={cn("size-7", className)}
|
|
269
|
+
className={cn("copa:size-7", className)}
|
|
270
270
|
onClick={(event) => {
|
|
271
|
-
onClick?.(event)
|
|
272
|
-
toggleSidebar()
|
|
271
|
+
onClick?.(event);
|
|
272
|
+
toggleSidebar();
|
|
273
273
|
}}
|
|
274
274
|
{...props}
|
|
275
275
|
>
|
|
276
276
|
<PanelLeftIcon />
|
|
277
|
-
<span className="sr-only">Toggle Sidebar</span>
|
|
277
|
+
<span className="copa:sr-only">Toggle Sidebar</span>
|
|
278
278
|
</Button>
|
|
279
|
-
)
|
|
279
|
+
);
|
|
280
280
|
}
|
|
281
281
|
|
|
282
282
|
function SidebarRail({ className, ...props }: React.ComponentProps<"button">) {
|
|
283
|
-
const { toggleSidebar } = useSidebar()
|
|
283
|
+
const { toggleSidebar } = useSidebar();
|
|
284
284
|
|
|
285
285
|
return (
|
|
286
286
|
<button
|
|
@@ -291,17 +291,17 @@ function SidebarRail({ className, ...props }: React.ComponentProps<"button">) {
|
|
|
291
291
|
onClick={toggleSidebar}
|
|
292
292
|
title="Toggle Sidebar"
|
|
293
293
|
className={cn(
|
|
294
|
-
"hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4
|
|
295
|
-
"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize",
|
|
296
|
-
"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize",
|
|
297
|
-
"hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full",
|
|
298
|
-
"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2",
|
|
299
|
-
"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2",
|
|
300
|
-
className
|
|
294
|
+
"copa:hover:after:bg-sidebar-border copa:absolute copa:inset-y-0 copa:z-20 copa:hidden copa:w-4 copa:-translate-x-1/2 copa:transition-all copa:ease-linear copa:group-data-[side=left]:-right-4 copa:group-data-[side=right]:left-0 copa:after:absolute copa:after:inset-y-0 copa:after:left-1/2 copa:after:w-[2px] copa:sm:flex",
|
|
295
|
+
"copa:in-data-[side=left]:cursor-w-resize copa:in-data-[side=right]:cursor-e-resize",
|
|
296
|
+
"copa:[[data-side=left][data-state=collapsed]_&]:cursor-e-resize copa:[[data-side=right][data-state=collapsed]_&]:cursor-w-resize",
|
|
297
|
+
"copa:hover:group-data-[collapsible=offcanvas]:bg-sidebar copa:group-data-[collapsible=offcanvas]:translate-x-0 copa:group-data-[collapsible=offcanvas]:after:left-full",
|
|
298
|
+
"copa:[[data-side=left][data-collapsible=offcanvas]_&]:-right-2",
|
|
299
|
+
"copa:[[data-side=right][data-collapsible=offcanvas]_&]:-left-2",
|
|
300
|
+
className,
|
|
301
301
|
)}
|
|
302
302
|
{...props}
|
|
303
303
|
/>
|
|
304
|
-
)
|
|
304
|
+
);
|
|
305
305
|
}
|
|
306
306
|
|
|
307
307
|
function SidebarInset({ className, ...props }: React.ComponentProps<"main">) {
|
|
@@ -309,13 +309,13 @@ function SidebarInset({ className, ...props }: React.ComponentProps<"main">) {
|
|
|
309
309
|
<main
|
|
310
310
|
data-slot="sidebar-inset"
|
|
311
311
|
className={cn(
|
|
312
|
-
"bg-background relative flex w-full flex-1 flex-col",
|
|
313
|
-
"md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2",
|
|
314
|
-
className
|
|
312
|
+
"copa:bg-background copa:relative copa:flex copa:w-full copa:flex-1 copa:flex-col",
|
|
313
|
+
"copa:md:peer-data-[variant=inset]:m-2 copa:md:peer-data-[variant=inset]:ml-0 copa:md:peer-data-[variant=inset]:rounded-xl copa:md:peer-data-[variant=inset]:shadow-sm copa:md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2",
|
|
314
|
+
className,
|
|
315
315
|
)}
|
|
316
316
|
{...props}
|
|
317
317
|
/>
|
|
318
|
-
)
|
|
318
|
+
);
|
|
319
319
|
}
|
|
320
320
|
|
|
321
321
|
function SidebarInput({
|
|
@@ -326,10 +326,10 @@ function SidebarInput({
|
|
|
326
326
|
<Input
|
|
327
327
|
data-slot="sidebar-input"
|
|
328
328
|
data-sidebar="input"
|
|
329
|
-
className={cn("bg-background h-8 w-full shadow-none", className)}
|
|
329
|
+
className={cn("copa:bg-background copa:h-8 copa:w-full copa:shadow-none", className)}
|
|
330
330
|
{...props}
|
|
331
331
|
/>
|
|
332
|
-
)
|
|
332
|
+
);
|
|
333
333
|
}
|
|
334
334
|
|
|
335
335
|
function SidebarHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
@@ -337,10 +337,10 @@ function SidebarHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
337
337
|
<div
|
|
338
338
|
data-slot="sidebar-header"
|
|
339
339
|
data-sidebar="header"
|
|
340
|
-
className={cn("flex flex-col gap-2 p-2", className)}
|
|
340
|
+
className={cn("copa:flex copa:flex-col copa:gap-2 copa:p-2", className)}
|
|
341
341
|
{...props}
|
|
342
342
|
/>
|
|
343
|
-
)
|
|
343
|
+
);
|
|
344
344
|
}
|
|
345
345
|
|
|
346
346
|
function SidebarFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
@@ -348,10 +348,10 @@ function SidebarFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
348
348
|
<div
|
|
349
349
|
data-slot="sidebar-footer"
|
|
350
350
|
data-sidebar="footer"
|
|
351
|
-
className={cn("flex flex-col gap-2 p-2", className)}
|
|
351
|
+
className={cn("copa:flex copa:flex-col copa:gap-2 copa:p-2", className)}
|
|
352
352
|
{...props}
|
|
353
353
|
/>
|
|
354
|
-
)
|
|
354
|
+
);
|
|
355
355
|
}
|
|
356
356
|
|
|
357
357
|
function SidebarSeparator({
|
|
@@ -362,10 +362,10 @@ function SidebarSeparator({
|
|
|
362
362
|
<Separator
|
|
363
363
|
data-slot="sidebar-separator"
|
|
364
364
|
data-sidebar="separator"
|
|
365
|
-
className={cn("bg-sidebar-border mx-2 w-auto", className)}
|
|
365
|
+
className={cn("copa:bg-sidebar-border copa:mx-2 copa:w-auto", className)}
|
|
366
366
|
{...props}
|
|
367
367
|
/>
|
|
368
|
-
)
|
|
368
|
+
);
|
|
369
369
|
}
|
|
370
370
|
|
|
371
371
|
function SidebarContent({ className, ...props }: React.ComponentProps<"div">) {
|
|
@@ -374,12 +374,12 @@ function SidebarContent({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
374
374
|
data-slot="sidebar-content"
|
|
375
375
|
data-sidebar="content"
|
|
376
376
|
className={cn(
|
|
377
|
-
"flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden",
|
|
378
|
-
className
|
|
377
|
+
"copa:flex copa:min-h-0 copa:flex-1 copa:flex-col copa:gap-2 copa:overflow-auto copa:group-data-[collapsible=icon]:overflow-hidden",
|
|
378
|
+
className,
|
|
379
379
|
)}
|
|
380
380
|
{...props}
|
|
381
381
|
/>
|
|
382
|
-
)
|
|
382
|
+
);
|
|
383
383
|
}
|
|
384
384
|
|
|
385
385
|
function SidebarGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
@@ -387,10 +387,10 @@ function SidebarGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
387
387
|
<div
|
|
388
388
|
data-slot="sidebar-group"
|
|
389
389
|
data-sidebar="group"
|
|
390
|
-
className={cn("relative flex w-full min-w-0 flex-col p-2", className)}
|
|
390
|
+
className={cn("copa:relative copa:flex copa:w-full copa:min-w-0 copa:flex-col copa:p-2", className)}
|
|
391
391
|
{...props}
|
|
392
392
|
/>
|
|
393
|
-
)
|
|
393
|
+
);
|
|
394
394
|
}
|
|
395
395
|
|
|
396
396
|
function SidebarGroupLabel({
|
|
@@ -398,20 +398,20 @@ function SidebarGroupLabel({
|
|
|
398
398
|
asChild = false,
|
|
399
399
|
...props
|
|
400
400
|
}: React.ComponentProps<"div"> & { asChild?: boolean }) {
|
|
401
|
-
const Comp = asChild ? Slot : "div"
|
|
401
|
+
const Comp = asChild ? Slot : "div";
|
|
402
402
|
|
|
403
403
|
return (
|
|
404
404
|
<Comp
|
|
405
405
|
data-slot="sidebar-group-label"
|
|
406
406
|
data-sidebar="group-label"
|
|
407
407
|
className={cn(
|
|
408
|
-
"text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
|
|
409
|
-
"group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0",
|
|
410
|
-
className
|
|
408
|
+
"copa:text-sidebar-foreground/70 copa:ring-sidebar-ring copa:flex copa:h-8 copa:shrink-0 copa:items-center copa:rounded-md copa:px-2 copa:text-xs copa:font-medium copa:outline-hidden copa:transition-[margin,opacity] copa:duration-200 copa:ease-linear copa:focus-visible:ring-2 copa:[&>svg]:size-4 copa:[&>svg]:shrink-0",
|
|
409
|
+
"copa:group-data-[collapsible=icon]:-mt-8 copa:group-data-[collapsible=icon]:opacity-0",
|
|
410
|
+
className,
|
|
411
411
|
)}
|
|
412
412
|
{...props}
|
|
413
413
|
/>
|
|
414
|
-
)
|
|
414
|
+
);
|
|
415
415
|
}
|
|
416
416
|
|
|
417
417
|
function SidebarGroupAction({
|
|
@@ -419,22 +419,22 @@ function SidebarGroupAction({
|
|
|
419
419
|
asChild = false,
|
|
420
420
|
...props
|
|
421
421
|
}: React.ComponentProps<"button"> & { asChild?: boolean }) {
|
|
422
|
-
const Comp = asChild ? Slot : "button"
|
|
422
|
+
const Comp = asChild ? Slot : "button";
|
|
423
423
|
|
|
424
424
|
return (
|
|
425
425
|
<Comp
|
|
426
426
|
data-slot="sidebar-group-action"
|
|
427
427
|
data-sidebar="group-action"
|
|
428
428
|
className={cn(
|
|
429
|
-
"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
|
|
429
|
+
"copa:text-sidebar-foreground copa:ring-sidebar-ring copa:hover:bg-sidebar-accent copa:hover:text-sidebar-accent-foreground copa:absolute copa:top-3.5 copa:right-3 copa:flex copa:aspect-square copa:w-5 copa:items-center copa:justify-center copa:rounded-md copa:p-0 copa:outline-hidden copa:transition-transform copa:focus-visible:ring-2 copa:[&>svg]:size-4 copa:[&>svg]:shrink-0",
|
|
430
430
|
// Increases the hit area of the button on mobile.
|
|
431
|
-
"after:absolute after:-inset-2 md:after:hidden",
|
|
432
|
-
"group-data-[collapsible=icon]:hidden",
|
|
433
|
-
className
|
|
431
|
+
"copa:after:absolute copa:after:-inset-2 copa:md:after:hidden",
|
|
432
|
+
"copa:group-data-[collapsible=icon]:hidden",
|
|
433
|
+
className,
|
|
434
434
|
)}
|
|
435
435
|
{...props}
|
|
436
436
|
/>
|
|
437
|
-
)
|
|
437
|
+
);
|
|
438
438
|
}
|
|
439
439
|
|
|
440
440
|
function SidebarGroupContent({
|
|
@@ -445,10 +445,10 @@ function SidebarGroupContent({
|
|
|
445
445
|
<div
|
|
446
446
|
data-slot="sidebar-group-content"
|
|
447
447
|
data-sidebar="group-content"
|
|
448
|
-
className={cn("w-full text-sm", className)}
|
|
448
|
+
className={cn("copa:w-full copa:text-sm", className)}
|
|
449
449
|
{...props}
|
|
450
450
|
/>
|
|
451
|
-
)
|
|
451
|
+
);
|
|
452
452
|
}
|
|
453
453
|
|
|
454
454
|
function SidebarMenu({ className, ...props }: React.ComponentProps<"ul">) {
|
|
@@ -456,10 +456,10 @@ function SidebarMenu({ className, ...props }: React.ComponentProps<"ul">) {
|
|
|
456
456
|
<ul
|
|
457
457
|
data-slot="sidebar-menu"
|
|
458
458
|
data-sidebar="menu"
|
|
459
|
-
className={cn("flex w-full min-w-0 flex-col gap-1", className)}
|
|
459
|
+
className={cn("copa:flex copa:w-full copa:min-w-0 copa:flex-col copa:gap-1", className)}
|
|
460
460
|
{...props}
|
|
461
461
|
/>
|
|
462
|
-
)
|
|
462
|
+
);
|
|
463
463
|
}
|
|
464
464
|
|
|
465
465
|
function SidebarMenuItem({ className, ...props }: React.ComponentProps<"li">) {
|
|
@@ -467,97 +467,102 @@ function SidebarMenuItem({ className, ...props }: React.ComponentProps<"li">) {
|
|
|
467
467
|
<li
|
|
468
468
|
data-slot="sidebar-menu-item"
|
|
469
469
|
data-sidebar="menu-item"
|
|
470
|
-
className={cn("group/menu-item relative", className)}
|
|
470
|
+
className={cn("copa:group/menu-item copa:relative", className)}
|
|
471
471
|
{...props}
|
|
472
472
|
/>
|
|
473
|
-
)
|
|
473
|
+
);
|
|
474
474
|
}
|
|
475
475
|
|
|
476
476
|
const sidebarMenuButtonVariants = cva(
|
|
477
|
-
"peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] 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 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
|
|
477
|
+
"copa:peer/menu-button copa:flex copa:w-full copa:items-center copa:gap-2 copa:overflow-hidden copa:rounded-md copa:p-2 copa:text-left copa:text-sm copa:outline-hidden copa:ring-sidebar-ring copa:transition-[width,height,padding] copa:hover:bg-sidebar-accent copa:hover:text-sidebar-accent-foreground copa:focus-visible:ring-2 copa:active:bg-sidebar-accent copa:active:text-sidebar-accent-foreground copa:disabled:pointer-events-none copa:disabled:opacity-50 copa:group-has-data-[sidebar=menu-action]/menu-item:pr-8 copa:aria-disabled:pointer-events-none copa:aria-disabled:opacity-50 copa:data-[active=true]:bg-sidebar-accent copa:data-[active=true]:font-medium copa:data-[active=true]:text-sidebar-accent-foreground copa:data-[state=open]:hover:bg-sidebar-accent copa:data-[state=open]:hover:text-sidebar-accent-foreground copa:group-data-[collapsible=icon]:size-8! copa:group-data-[collapsible=icon]:p-2! copa:[&>span:last-child]:truncate copa:[&>svg]:size-4 copa:[&>svg]:shrink-0",
|
|
478
478
|
{
|
|
479
479
|
variants: {
|
|
480
480
|
variant: {
|
|
481
|
-
default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
|
|
481
|
+
default: "copa:hover:bg-sidebar-accent copa:hover:text-sidebar-accent-foreground",
|
|
482
482
|
outline:
|
|
483
|
-
"bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]",
|
|
483
|
+
"copa:bg-background copa:shadow-[0_0_0_1px_hsl(var(--sidebar-border))] copa:hover:bg-sidebar-accent copa:hover:text-sidebar-accent-foreground copa:hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]",
|
|
484
484
|
},
|
|
485
485
|
size: {
|
|
486
|
-
default: "h-8 text-sm",
|
|
487
|
-
sm: "h-7 text-xs",
|
|
488
|
-
lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!",
|
|
486
|
+
default: "copa:h-8 copa:text-sm",
|
|
487
|
+
sm: "copa:h-7 copa:text-xs",
|
|
488
|
+
lg: "copa:h-12 copa:text-sm copa:group-data-[collapsible=icon]:p-0!",
|
|
489
489
|
},
|
|
490
490
|
},
|
|
491
491
|
defaultVariants: {
|
|
492
492
|
variant: "default",
|
|
493
493
|
size: "default",
|
|
494
494
|
},
|
|
495
|
-
}
|
|
496
|
-
)
|
|
495
|
+
},
|
|
496
|
+
);
|
|
497
497
|
|
|
498
498
|
const SidebarMenuButton = React.forwardRef<
|
|
499
499
|
HTMLButtonElement,
|
|
500
500
|
React.ComponentProps<"button"> & {
|
|
501
|
-
asChild?: boolean
|
|
502
|
-
isActive?: boolean
|
|
503
|
-
tooltip?: string | React.ComponentProps<typeof TooltipContent
|
|
501
|
+
asChild?: boolean;
|
|
502
|
+
isActive?: boolean;
|
|
503
|
+
tooltip?: string | React.ComponentProps<typeof TooltipContent>;
|
|
504
504
|
} & VariantProps<typeof sidebarMenuButtonVariants>
|
|
505
|
-
>(
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
505
|
+
>(
|
|
506
|
+
(
|
|
507
|
+
{
|
|
508
|
+
asChild = false,
|
|
509
|
+
isActive = false,
|
|
510
|
+
variant = "default",
|
|
511
|
+
size = "default",
|
|
512
|
+
tooltip,
|
|
513
|
+
className,
|
|
514
|
+
...props
|
|
515
|
+
},
|
|
516
|
+
ref,
|
|
517
|
+
) => {
|
|
518
|
+
const Comp = asChild ? Slot : "button";
|
|
519
|
+
const { isMobile, state } = useSidebar();
|
|
520
|
+
|
|
521
|
+
const button = (
|
|
522
|
+
<Comp
|
|
523
|
+
ref={ref}
|
|
524
|
+
data-slot="sidebar-menu-button"
|
|
525
|
+
data-sidebar="menu-button"
|
|
526
|
+
data-size={size}
|
|
527
|
+
data-active={isActive}
|
|
528
|
+
className={cn(sidebarMenuButtonVariants({ variant, size }), className)}
|
|
529
|
+
{...props}
|
|
530
|
+
/>
|
|
531
|
+
);
|
|
528
532
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
533
|
+
if (!tooltip) {
|
|
534
|
+
return button;
|
|
535
|
+
}
|
|
532
536
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
537
|
+
if (typeof tooltip === "string") {
|
|
538
|
+
tooltip = {
|
|
539
|
+
children: tooltip,
|
|
540
|
+
};
|
|
536
541
|
}
|
|
537
|
-
}
|
|
538
542
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
}
|
|
551
|
-
|
|
543
|
+
return (
|
|
544
|
+
<Tooltip>
|
|
545
|
+
<TooltipTrigger asChild>{button}</TooltipTrigger>
|
|
546
|
+
<TooltipContent
|
|
547
|
+
side="right"
|
|
548
|
+
align="center"
|
|
549
|
+
hidden={state !== "collapsed" || isMobile}
|
|
550
|
+
{...tooltip}
|
|
551
|
+
/>
|
|
552
|
+
</Tooltip>
|
|
553
|
+
);
|
|
554
|
+
},
|
|
555
|
+
);
|
|
556
|
+
SidebarMenuButton.displayName = "SidebarMenuButton";
|
|
552
557
|
|
|
553
558
|
const SidebarMenuAction = React.forwardRef<
|
|
554
559
|
HTMLButtonElement,
|
|
555
560
|
React.ComponentProps<"button"> & {
|
|
556
|
-
asChild?: boolean
|
|
557
|
-
showOnHover?: boolean
|
|
561
|
+
asChild?: boolean;
|
|
562
|
+
showOnHover?: boolean;
|
|
558
563
|
}
|
|
559
564
|
>(({ className, asChild = false, showOnHover = false, ...props }, ref) => {
|
|
560
|
-
const Comp = asChild ? Slot : "button"
|
|
565
|
+
const Comp = asChild ? Slot : "button";
|
|
561
566
|
|
|
562
567
|
return (
|
|
563
568
|
<Comp
|
|
@@ -565,22 +570,22 @@ const SidebarMenuAction = React.forwardRef<
|
|
|
565
570
|
data-slot="sidebar-menu-action"
|
|
566
571
|
data-sidebar="menu-action"
|
|
567
572
|
className={cn(
|
|
568
|
-
"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
|
|
573
|
+
"copa:text-sidebar-foreground copa:ring-sidebar-ring copa:hover:bg-sidebar-accent copa:hover:text-sidebar-accent-foreground copa:peer-hover/menu-button:text-sidebar-accent-foreground copa:absolute copa:top-1.5 copa:right-1 copa:flex copa:aspect-square copa:w-5 copa:items-center copa:justify-center copa:rounded-md copa:p-0 copa:outline-hidden copa:transition-transform copa:focus-visible:ring-2 copa:[&>svg]:size-4 copa:[&>svg]:shrink-0",
|
|
569
574
|
// Increases the hit area of the button on mobile.
|
|
570
|
-
"after:absolute after:-inset-2 md:after:hidden",
|
|
571
|
-
"peer-data-[size=sm]/menu-button:top-1",
|
|
572
|
-
"peer-data-[size=default]/menu-button:top-1.5",
|
|
573
|
-
"peer-data-[size=lg]/menu-button:top-2.5",
|
|
574
|
-
"group-data-[collapsible=icon]:hidden",
|
|
575
|
+
"copa:after:absolute copa:after:-inset-2 copa:md:after:hidden",
|
|
576
|
+
"copa:peer-data-[size=sm]/menu-button:top-1",
|
|
577
|
+
"copa:peer-data-[size=default]/menu-button:top-1.5",
|
|
578
|
+
"copa:peer-data-[size=lg]/menu-button:top-2.5",
|
|
579
|
+
"copa:group-data-[collapsible=icon]:hidden",
|
|
575
580
|
showOnHover &&
|
|
576
|
-
"peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0",
|
|
577
|
-
className
|
|
581
|
+
"copa:peer-data-[active=true]/menu-button:text-sidebar-accent-foreground copa:group-focus-within/menu-item:opacity-100 copa:group-hover/menu-item:opacity-100 copa:data-[state=open]:opacity-100 copa:md:opacity-0",
|
|
582
|
+
className,
|
|
578
583
|
)}
|
|
579
584
|
{...props}
|
|
580
585
|
/>
|
|
581
|
-
)
|
|
582
|
-
})
|
|
583
|
-
SidebarMenuAction.displayName = "SidebarMenuAction"
|
|
586
|
+
);
|
|
587
|
+
});
|
|
588
|
+
SidebarMenuAction.displayName = "SidebarMenuAction";
|
|
584
589
|
|
|
585
590
|
function SidebarMenuBadge({
|
|
586
591
|
className,
|
|
@@ -591,17 +596,17 @@ function SidebarMenuBadge({
|
|
|
591
596
|
data-slot="sidebar-menu-badge"
|
|
592
597
|
data-sidebar="menu-badge"
|
|
593
598
|
className={cn(
|
|
594
|
-
"text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none",
|
|
595
|
-
"peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground",
|
|
596
|
-
"peer-data-[size=sm]/menu-button:top-1",
|
|
597
|
-
"peer-data-[size=default]/menu-button:top-1.5",
|
|
598
|
-
"peer-data-[size=lg]/menu-button:top-2.5",
|
|
599
|
-
"group-data-[collapsible=icon]:hidden",
|
|
600
|
-
className
|
|
599
|
+
"copa:text-sidebar-foreground copa:pointer-events-none copa:absolute copa:right-1 copa:flex copa:h-5 copa:min-w-5 copa:items-center copa:justify-center copa:rounded-md copa:px-1 copa:text-xs copa:font-medium copa:tabular-nums copa:select-none",
|
|
600
|
+
"copa:peer-hover/menu-button:text-sidebar-accent-foreground copa:peer-data-[active=true]/menu-button:text-sidebar-accent-foreground",
|
|
601
|
+
"copa:peer-data-[size=sm]/menu-button:top-1",
|
|
602
|
+
"copa:peer-data-[size=default]/menu-button:top-1.5",
|
|
603
|
+
"copa:peer-data-[size=lg]/menu-button:top-2.5",
|
|
604
|
+
"copa:group-data-[collapsible=icon]:hidden",
|
|
605
|
+
className,
|
|
601
606
|
)}
|
|
602
607
|
{...props}
|
|
603
608
|
/>
|
|
604
|
-
)
|
|
609
|
+
);
|
|
605
610
|
}
|
|
606
611
|
|
|
607
612
|
function SidebarMenuSkeleton({
|
|
@@ -609,28 +614,28 @@ function SidebarMenuSkeleton({
|
|
|
609
614
|
showIcon = false,
|
|
610
615
|
...props
|
|
611
616
|
}: React.ComponentProps<"div"> & {
|
|
612
|
-
showIcon?: boolean
|
|
617
|
+
showIcon?: boolean;
|
|
613
618
|
}) {
|
|
614
619
|
// Random width between 50 to 90%.
|
|
615
620
|
const width = React.useMemo(() => {
|
|
616
|
-
return `${Math.floor(Math.random() * 40) + 50}
|
|
617
|
-
}, [])
|
|
621
|
+
return `${Math.floor(Math.random() * 40) + 50}%`;
|
|
622
|
+
}, []);
|
|
618
623
|
|
|
619
624
|
return (
|
|
620
625
|
<div
|
|
621
626
|
data-slot="sidebar-menu-skeleton"
|
|
622
627
|
data-sidebar="menu-skeleton"
|
|
623
|
-
className={cn("flex h-8 items-center gap-2 rounded-md px-2", className)}
|
|
628
|
+
className={cn("copa:flex copa:h-8 copa:items-center copa:gap-2 copa:rounded-md copa:px-2", className)}
|
|
624
629
|
{...props}
|
|
625
630
|
>
|
|
626
631
|
{showIcon && (
|
|
627
632
|
<Skeleton
|
|
628
|
-
className="size-4 rounded-md"
|
|
633
|
+
className="copa:size-4 copa:rounded-md"
|
|
629
634
|
data-sidebar="menu-skeleton-icon"
|
|
630
635
|
/>
|
|
631
636
|
)}
|
|
632
637
|
<Skeleton
|
|
633
|
-
className="h-4 max-w-(--skeleton-width) flex-1"
|
|
638
|
+
className="copa:h-4 copa:max-w-(--skeleton-width) copa:flex-1"
|
|
634
639
|
data-sidebar="menu-skeleton-text"
|
|
635
640
|
style={
|
|
636
641
|
{
|
|
@@ -639,7 +644,7 @@ function SidebarMenuSkeleton({
|
|
|
639
644
|
}
|
|
640
645
|
/>
|
|
641
646
|
</div>
|
|
642
|
-
)
|
|
647
|
+
);
|
|
643
648
|
}
|
|
644
649
|
|
|
645
650
|
function SidebarMenuSub({ className, ...props }: React.ComponentProps<"ul">) {
|
|
@@ -648,13 +653,13 @@ function SidebarMenuSub({ className, ...props }: React.ComponentProps<"ul">) {
|
|
|
648
653
|
data-slot="sidebar-menu-sub"
|
|
649
654
|
data-sidebar="menu-sub"
|
|
650
655
|
className={cn(
|
|
651
|
-
"border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5",
|
|
652
|
-
"group-data-[collapsible=icon]:hidden",
|
|
653
|
-
className
|
|
656
|
+
"copa:border-sidebar-border copa:mx-3.5 copa:flex copa:min-w-0 copa:translate-x-px copa:flex-col copa:gap-1 copa:border-l copa:px-2.5 copa:py-0.5",
|
|
657
|
+
"copa:group-data-[collapsible=icon]:hidden",
|
|
658
|
+
className,
|
|
654
659
|
)}
|
|
655
660
|
{...props}
|
|
656
661
|
/>
|
|
657
|
-
)
|
|
662
|
+
);
|
|
658
663
|
}
|
|
659
664
|
|
|
660
665
|
function SidebarMenuSubItem({
|
|
@@ -665,10 +670,10 @@ function SidebarMenuSubItem({
|
|
|
665
670
|
<li
|
|
666
671
|
data-slot="sidebar-menu-sub-item"
|
|
667
672
|
data-sidebar="menu-sub-item"
|
|
668
|
-
className={cn("group/menu-sub-item relative", className)}
|
|
673
|
+
className={cn("copa:group/menu-sub-item copa:relative", className)}
|
|
669
674
|
{...props}
|
|
670
675
|
/>
|
|
671
|
-
)
|
|
676
|
+
);
|
|
672
677
|
}
|
|
673
678
|
|
|
674
679
|
function SidebarMenuSubButton({
|
|
@@ -678,11 +683,11 @@ function SidebarMenuSubButton({
|
|
|
678
683
|
className,
|
|
679
684
|
...props
|
|
680
685
|
}: React.ComponentProps<"a"> & {
|
|
681
|
-
asChild?: boolean
|
|
682
|
-
size?: "sm" | "md"
|
|
683
|
-
isActive?: boolean
|
|
686
|
+
asChild?: boolean;
|
|
687
|
+
size?: "sm" | "md";
|
|
688
|
+
isActive?: boolean;
|
|
684
689
|
}) {
|
|
685
|
-
const Comp = asChild ? Slot : "a"
|
|
690
|
+
const Comp = asChild ? Slot : "a";
|
|
686
691
|
|
|
687
692
|
return (
|
|
688
693
|
<Comp
|
|
@@ -691,16 +696,16 @@ function SidebarMenuSubButton({
|
|
|
691
696
|
data-size={size}
|
|
692
697
|
data-active={isActive}
|
|
693
698
|
className={cn(
|
|
694
|
-
"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0
|
|
695
|
-
"data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground",
|
|
696
|
-
size === "sm" && "text-xs",
|
|
697
|
-
size === "md" && "text-sm",
|
|
698
|
-
"group-data-[collapsible=icon]:hidden",
|
|
699
|
-
className
|
|
699
|
+
"copa:text-sidebar-foreground copa:ring-sidebar-ring copa:hover:bg-sidebar-accent copa:hover:text-sidebar-accent-foreground copa:active:bg-sidebar-accent copa:active:text-sidebar-accent-foreground copa:[&>svg]:text-sidebar-accent-foreground copa:flex copa:h-7 copa:min-w-0 copa:-translate-x-px copa:items-center copa:gap-2 copa:overflow-hidden copa:rounded-md copa:px-2 copa:outline-hidden copa:focus-visible:ring-2 copa:disabled:pointer-events-none copa:disabled:opacity-50 copa:aria-disabled:pointer-events-none copa:aria-disabled:opacity-50 copa:[&>span:last-child]:truncate copa:[&>svg]:size-4 copa:[&>svg]:shrink-0",
|
|
700
|
+
"copa:data-[active=true]:bg-sidebar-accent copa:data-[active=true]:text-sidebar-accent-foreground",
|
|
701
|
+
size === "sm" && "copa:text-xs",
|
|
702
|
+
size === "md" && "copa:text-sm",
|
|
703
|
+
"copa:group-data-[collapsible=icon]:hidden",
|
|
704
|
+
className,
|
|
700
705
|
)}
|
|
701
706
|
{...props}
|
|
702
707
|
/>
|
|
703
|
-
)
|
|
708
|
+
);
|
|
704
709
|
}
|
|
705
710
|
|
|
706
711
|
export {
|
|
@@ -728,4 +733,4 @@ export {
|
|
|
728
733
|
SidebarSeparator,
|
|
729
734
|
SidebarTrigger,
|
|
730
735
|
useSidebar,
|
|
731
|
-
}
|
|
736
|
+
};
|