@authdog/react-elements 0.0.45 → 0.0.47

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,22 +24,48 @@ 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;
36
43
  className?: string;
37
44
  logoText?: string;
38
45
  logoSrc?: string;
46
+ /**
47
+ * Optional custom alt text element rendered next to the logo.
48
+ * When not provided, the plain `logoText` string is rendered.
49
+ * Use this to pass in custom typography / font classes.
50
+ */
51
+ altText?: React.ReactNode;
39
52
  isLoading?: boolean;
40
53
  user?: any;
41
54
  onNavigateHome?: () => void;
42
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
+ */
43
69
  onProfileSelected?: () => void;
44
70
  onLogout?: () => void;
45
71
  // signinUrl?: string;
@@ -55,6 +81,7 @@ export function Navbar({
55
81
  className,
56
82
  logoText = "ACME Corp",
57
83
  logoSrc,
84
+ altText,
58
85
  user = {
59
86
  name: "John Doe",
60
87
  email: "john@example.com",
@@ -62,6 +89,10 @@ export function Navbar({
62
89
  },
63
90
  onNavigateHome = () => console.log("Navigating to home"),
64
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}`),
65
96
  onProfileSelected,
66
97
  onLogout = () => console.log("Logout clicked"),
67
98
  isLoading = false,
@@ -96,7 +127,7 @@ export function Navbar({
96
127
  type="button"
97
128
  onClick={onNavigateHome}
98
129
  className={cn(
99
- "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",
100
131
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
101
132
  )}
102
133
  aria-label="Go to homepage"
@@ -111,9 +142,11 @@ export function Navbar({
111
142
  />
112
143
  </span>
113
144
  )}
114
- <span className="text-base font-semibold tracking-tight md:text-lg group-hover:text-primary">
115
- {logoText}
116
- </span>
145
+ {altText ?? (
146
+ <span className="text-base font-semibold tracking-tight md:text-lg group-hover:text-primary">
147
+ {logoText}
148
+ </span>
149
+ )}
117
150
  </button>
118
151
  {children}
119
152
  </div>
@@ -155,7 +188,7 @@ export function Navbar({
155
188
  key={index}
156
189
  href={item.href}
157
190
  className={cn(
158
- "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",
159
192
  item.disabled && "cursor-not-allowed opacity-80",
160
193
  )}
161
194
  onClick={() => setOpen(false)}
@@ -212,13 +245,28 @@ export function Navbar({
212
245
  </DropdownMenuLabel>
213
246
  <DropdownMenuSeparator />
214
247
  <DropdownMenuGroup>
215
- <DropdownMenuItem onClick={onProfileSelected}>
216
- <IconWrapper Icon={User} />
217
- <span>Profile</span>
218
- </DropdownMenuItem>
248
+ {dropdownMenuItems.map((item, index) => (
249
+ <DropdownMenuItem
250
+ key={index}
251
+ onClick={() => {
252
+ if (!item.disabled) {
253
+ // Backward compatibility: if it's the profile item and onProfileSelected exists
254
+ if (item.uri === "/profile" && onProfileSelected) {
255
+ onProfileSelected();
256
+ }
257
+ onDropdownMenuItemClick(item.uri);
258
+ }
259
+ }}
260
+ disabled={item.disabled}
261
+ className="cursor-pointer"
262
+ >
263
+ {item.icon && <IconWrapper Icon={item.icon} />}
264
+ <span>{item.name}</span>
265
+ </DropdownMenuItem>
266
+ ))}
219
267
  </DropdownMenuGroup>
220
268
  <DropdownMenuSeparator />
221
- <DropdownMenuItem onClick={onLogout}>
269
+ <DropdownMenuItem onClick={onLogout} className="cursor-pointer">
222
270
  <IconWrapper Icon={LogOut} />
223
271
  <span>Log out</span>
224
272
  </DropdownMenuItem>
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";