@authdog/react-elements 0.0.46 → 0.0.48

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.
@@ -24,12 +24,19 @@ import { Sheet, SheetContent, SheetTrigger } from "../../components/ui/sheet";
24
24
  import { IconWrapper } from "../icons";
25
25
  import { ThemeToggle } from "../ui/theme-toggle";
26
26
 
27
- interface NavItem {
27
+ export interface NavItem {
28
28
  title: string;
29
29
  href: string;
30
30
  disabled?: boolean;
31
31
  }
32
32
 
33
+ export interface DropdownMenuItem {
34
+ name: string;
35
+ uri: string;
36
+ icon?: React.ComponentType<{ className?: string }>;
37
+ disabled?: boolean;
38
+ }
39
+
33
40
  interface NavbarProps {
34
41
  items?: NavItem[] | undefined;
35
42
  children?: React.ReactNode;
@@ -46,6 +53,19 @@ interface NavbarProps {
46
53
  user?: any;
47
54
  onNavigateHome?: () => void;
48
55
  onNavItemClick?: (href: string) => void;
56
+ /**
57
+ * Custom dropdown menu items that appear in the user avatar dropdown.
58
+ * If not provided, defaults to a "Profile" link.
59
+ */
60
+ dropdownMenuItems?: DropdownMenuItem[];
61
+ /**
62
+ * Callback when a dropdown menu item is clicked.
63
+ * Receives the URI of the clicked item.
64
+ */
65
+ onDropdownMenuItemClick?: (uri: string) => void;
66
+ /**
67
+ * @deprecated Use dropdownMenuItems with a custom item instead
68
+ */
49
69
  onProfileSelected?: () => void;
50
70
  onLogout?: () => void;
51
71
  // signinUrl?: string;
@@ -69,6 +89,10 @@ export function Navbar({
69
89
  },
70
90
  onNavigateHome = () => console.log("Navigating to home"),
71
91
  onNavItemClick = (href: string) => console.log(`Navigating to ${href}`),
92
+ dropdownMenuItems = [
93
+ { name: "Profile", uri: "/profile", icon: User },
94
+ ],
95
+ onDropdownMenuItemClick = (uri: string) => console.log(`Navigating to ${uri}`),
72
96
  onProfileSelected,
73
97
  onLogout = () => console.log("Logout clicked"),
74
98
  isLoading = false,
@@ -103,7 +127,7 @@ export function Navbar({
103
127
  type="button"
104
128
  onClick={onNavigateHome}
105
129
  className={cn(
106
- "group inline-flex items-center gap-2 md:gap-3 rounded-md px-1 py-1 text-left",
130
+ "group inline-flex items-center gap-2 md:gap-3 rounded-md px-1 py-1 text-left cursor-pointer",
107
131
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
108
132
  )}
109
133
  aria-label="Go to homepage"
@@ -164,7 +188,7 @@ export function Navbar({
164
188
  key={index}
165
189
  href={item.href}
166
190
  className={cn(
167
- "flex w-full items-center rounded-md px-3 py-2 text-sm font-medium hover:bg-accent",
191
+ "flex w-full items-center rounded-md px-3 py-2 text-sm font-medium hover:bg-accent cursor-pointer",
168
192
  item.disabled && "cursor-not-allowed opacity-80",
169
193
  )}
170
194
  onClick={() => setOpen(false)}
@@ -181,7 +205,7 @@ export function Navbar({
181
205
  <DropdownMenuTrigger asChild>
182
206
  <Button
183
207
  variant="ghost"
184
- className="relative h-8 w-8 rounded-full"
208
+ className="relative h-8 w-8 rounded-full cursor-pointer"
185
209
  disabled={isLoading}
186
210
  >
187
211
  <Avatar className="h-8 w-8">
@@ -219,15 +243,34 @@ export function Navbar({
219
243
  </p>
220
244
  </div>
221
245
  </DropdownMenuLabel>
222
- <DropdownMenuSeparator />
223
- <DropdownMenuGroup>
224
- <DropdownMenuItem onClick={onProfileSelected}>
225
- <IconWrapper Icon={User} />
226
- <span>Profile</span>
227
- </DropdownMenuItem>
228
- </DropdownMenuGroup>
229
- <DropdownMenuSeparator />
230
- <DropdownMenuItem onClick={onLogout}>
246
+ {dropdownMenuItems.length > 0 && (
247
+ <>
248
+ <DropdownMenuSeparator />
249
+ <DropdownMenuGroup>
250
+ {dropdownMenuItems.map((item, index) => (
251
+ <DropdownMenuItem
252
+ key={index}
253
+ onClick={() => {
254
+ if (!item.disabled) {
255
+ // Backward compatibility: if it's the profile item and onProfileSelected exists
256
+ if (item.uri === "/profile" && onProfileSelected) {
257
+ onProfileSelected();
258
+ }
259
+ onDropdownMenuItemClick(item.uri);
260
+ }
261
+ }}
262
+ disabled={item.disabled}
263
+ className="cursor-pointer"
264
+ >
265
+ {item.icon && <IconWrapper Icon={item.icon} />}
266
+ <span>{item.name}</span>
267
+ </DropdownMenuItem>
268
+ ))}
269
+ </DropdownMenuGroup>
270
+ <DropdownMenuSeparator />
271
+ </>
272
+ )}
273
+ <DropdownMenuItem onClick={onLogout} className="cursor-pointer">
231
274
  <IconWrapper Icon={LogOut} />
232
275
  <span>Log out</span>
233
276
  </DropdownMenuItem>
@@ -46,6 +46,7 @@ export const ThemeToggle = () => {
46
46
  <Button
47
47
  variant="ghost"
48
48
  size="icon"
49
+ className="cursor-pointer"
49
50
  aria-label={mode === "dark" ? "Switch to light theme" : "Switch to dark theme"}
50
51
  onClick={toggle}
51
52
  >
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { Button } from "./components/ui/button";
2
2
  export { ClientOnly } from "./components/core/client-only";
3
3
  export { Navbar } from "./components/core/navbar";
4
+ export type { NavItem, DropdownMenuItem } from "./components/core/navbar";
4
5
  export { UserProfile } from "./components/core/user-profile";
5
6
  export { UserDropdown } from "./components/core/user-dropdown";
6
7
  export { PlaceholderAlert } from "./components/core/placeholder-alert";