sonance-brand-mcp 1.3.111 → 1.3.113

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.
Files changed (79) hide show
  1. package/dist/assets/api/sonance-save-image/route.ts +625 -0
  2. package/dist/assets/api/sonance-vision-apply/image-styling-detection.ts +1360 -0
  3. package/dist/assets/api/sonance-vision-apply/route.ts +988 -57
  4. package/dist/assets/api/sonance-vision-apply/styling-detection.ts +730 -0
  5. package/dist/assets/api/sonance-vision-apply/theme-discovery.ts +1 -1
  6. package/dist/assets/brand-system.ts +13 -12
  7. package/dist/assets/components/accordion.tsx +15 -7
  8. package/dist/assets/components/alert-dialog.tsx +35 -10
  9. package/dist/assets/components/alert.tsx +11 -10
  10. package/dist/assets/components/avatar.tsx +4 -4
  11. package/dist/assets/components/badge.tsx +16 -12
  12. package/dist/assets/components/button.stories.tsx +3 -3
  13. package/dist/assets/components/button.tsx +50 -31
  14. package/dist/assets/components/calendar.tsx +12 -8
  15. package/dist/assets/components/card.tsx +35 -29
  16. package/dist/assets/components/checkbox.tsx +9 -8
  17. package/dist/assets/components/code.tsx +19 -11
  18. package/dist/assets/components/command.tsx +32 -13
  19. package/dist/assets/components/context-menu.tsx +37 -16
  20. package/dist/assets/components/dialog.tsx +8 -5
  21. package/dist/assets/components/divider.tsx +15 -5
  22. package/dist/assets/components/drawer.tsx +4 -3
  23. package/dist/assets/components/dropdown-menu.tsx +15 -13
  24. package/dist/assets/components/hover-card.tsx +4 -1
  25. package/dist/assets/components/image.tsx +1 -1
  26. package/dist/assets/components/input.tsx +29 -14
  27. package/dist/assets/components/kbd.stories.tsx +3 -3
  28. package/dist/assets/components/kbd.tsx +29 -13
  29. package/dist/assets/components/listbox.tsx +8 -8
  30. package/dist/assets/components/menubar.tsx +50 -23
  31. package/dist/assets/components/navbar.stories.tsx +140 -13
  32. package/dist/assets/components/navbar.tsx +22 -5
  33. package/dist/assets/components/navigation-menu.tsx +28 -6
  34. package/dist/assets/components/pagination.tsx +10 -10
  35. package/dist/assets/components/popover.tsx +10 -8
  36. package/dist/assets/components/progress.tsx +6 -4
  37. package/dist/assets/components/radio-group.tsx +5 -5
  38. package/dist/assets/components/select.tsx +49 -29
  39. package/dist/assets/components/separator.tsx +3 -3
  40. package/dist/assets/components/sheet.tsx +4 -4
  41. package/dist/assets/components/sidebar.tsx +10 -10
  42. package/dist/assets/components/skeleton.tsx +13 -5
  43. package/dist/assets/components/slider.tsx +12 -10
  44. package/dist/assets/components/switch.tsx +4 -4
  45. package/dist/assets/components/table.tsx +5 -5
  46. package/dist/assets/components/tabs.tsx +8 -8
  47. package/dist/assets/components/textarea.tsx +11 -9
  48. package/dist/assets/components/toast.tsx +7 -7
  49. package/dist/assets/components/toggle.tsx +27 -7
  50. package/dist/assets/components/tooltip.tsx +10 -8
  51. package/dist/assets/components/user.tsx +8 -6
  52. package/dist/assets/dev-tools/SonanceDevTools.tsx +429 -362
  53. package/dist/assets/dev-tools/components/ApplyFirstPreview.tsx +10 -10
  54. package/dist/assets/dev-tools/components/ChatHistory.tsx +11 -7
  55. package/dist/assets/dev-tools/components/ChatInterface.tsx +61 -20
  56. package/dist/assets/dev-tools/components/ChatTabBar.tsx +1 -1
  57. package/dist/assets/dev-tools/components/DiffPreview.tsx +1 -1
  58. package/dist/assets/dev-tools/components/InlineDiffPreview.tsx +360 -36
  59. package/dist/assets/dev-tools/components/InspectorOverlay.tsx +9 -9
  60. package/dist/assets/dev-tools/components/PropertiesPanel.tsx +743 -93
  61. package/dist/assets/dev-tools/components/ScreenshotAnnotator.tsx +1 -1
  62. package/dist/assets/dev-tools/components/SectionHighlight.tsx +1 -1
  63. package/dist/assets/dev-tools/components/VisionDiffPreview.tsx +7 -7
  64. package/dist/assets/dev-tools/components/VisionModeBorder.tsx +4 -64
  65. package/dist/assets/dev-tools/hooks/index.ts +69 -0
  66. package/dist/assets/dev-tools/hooks/useComponentDetection.ts +132 -0
  67. package/dist/assets/dev-tools/hooks/useComputedStyles.ts +171 -65
  68. package/dist/assets/dev-tools/hooks/useContentHash.ts +212 -0
  69. package/dist/assets/dev-tools/hooks/useElementScanner.ts +398 -0
  70. package/dist/assets/dev-tools/hooks/useImageDetection.ts +162 -0
  71. package/dist/assets/dev-tools/hooks/useTextDetection.ts +217 -0
  72. package/dist/assets/dev-tools/panels/ComponentsPanel.tsx +160 -57
  73. package/dist/assets/dev-tools/panels/TextPanel.tsx +10 -10
  74. package/dist/assets/dev-tools/types.ts +42 -0
  75. package/dist/assets/globals.css +225 -9
  76. package/dist/assets/styles/brand-overrides.css +3 -2
  77. package/dist/assets/utils.ts +2 -1
  78. package/dist/index.js +32 -1
  79. package/package.json +1 -1
@@ -3,18 +3,33 @@ import { cva, type VariantProps } from "class-variance-authority";
3
3
  import { cn } from "@/lib/utils";
4
4
 
5
5
  const kbdVariants = cva(
6
- "inline-flex items-center justify-center font-mono font-medium border transition-all",
6
+ cn(
7
+ "inline-flex items-center justify-center font-mono font-medium",
8
+ "transition-all backdrop-blur-sm"
9
+ ),
7
10
  {
8
11
  variants: {
9
12
  variant: {
10
- default: "bg-background-secondary border-border text-foreground",
11
- outline: "bg-transparent border-border text-foreground-secondary",
12
- flat: "bg-background-tertiary border-transparent text-foreground-muted",
13
+ default: cn(
14
+ "bg-white/60 dark:bg-white/5",
15
+ "border border-black/10 dark:border-white/10",
16
+ "text-foreground shadow-sm"
17
+ ),
18
+ outline: cn(
19
+ "bg-transparent",
20
+ "border border-black/15 dark:border-white/15",
21
+ "text-foreground-muted"
22
+ ),
23
+ glass: cn(
24
+ "bg-white/40 dark:bg-white/5",
25
+ "border border-black/5 dark:border-white/10",
26
+ "text-foreground-muted shadow-sm"
27
+ ),
13
28
  },
14
29
  size: {
15
- sm: "h-4 sm:h-5 min-w-4 sm:min-w-5 px-0.5 sm:px-1 text-[9px] sm:text-[10px] rounded-sm",
16
- md: "h-5 sm:h-6 min-w-5 sm:min-w-6 px-1 sm:px-1.5 text-[10px] sm:text-xs rounded-sm",
17
- lg: "h-6 sm:h-7 min-w-6 sm:min-w-7 px-1.5 sm:px-2 text-xs sm:text-sm rounded",
30
+ sm: "h-4 sm:h-5 min-w-4 sm:min-w-5 px-0.5 sm:px-1 text-[9px] sm:text-[10px] rounded-md",
31
+ md: "h-5 sm:h-6 min-w-5 sm:min-w-6 px-1 sm:px-1.5 text-[10px] sm:text-xs rounded-md",
32
+ lg: "h-6 sm:h-7 min-w-6 sm:min-w-7 px-1.5 sm:px-2 text-xs sm:text-sm rounded-lg",
18
33
  },
19
34
  },
20
35
  defaultVariants: {
@@ -36,12 +51,13 @@ export const Kbd = forwardRef<HTMLElement, KbdProps>(
36
51
  if (keys) {
37
52
  const keyArray = Array.isArray(keys) ? keys : [keys];
38
53
  return (
39
- <span id="kbd-span" data-sonance-name="kbd" className="inline-flex items-center gap-1">
54
+ <span data-sonance-name="kbd" className="inline-flex items-center gap-1">
40
55
  {keyArray.map((key, index) => (
41
56
  <kbd
42
57
  key={index}
43
58
  ref={index === 0 ? ref : undefined}
44
- className={cn(kbdVariants({ variant, size }), className)} data-sonance-name="kbd"
59
+ data-sonance-name="kbd"
60
+ className={cn(kbdVariants({ variant, size }), className)}
45
61
  {...props}
46
62
  >
47
63
  {formatKey(key)}
@@ -54,7 +70,8 @@ export const Kbd = forwardRef<HTMLElement, KbdProps>(
54
70
  return (
55
71
  <kbd
56
72
  ref={ref}
57
- className={cn(kbdVariants({ variant, size }), className)} data-sonance-name="kbd"
73
+ data-sonance-name="kbd"
74
+ className={cn(kbdVariants({ variant, size }), className)}
58
75
  {...props}
59
76
  >
60
77
  {children}
@@ -103,8 +120,8 @@ interface KeyboardShortcutProps {
103
120
 
104
121
  export function KeyboardShortcut({ keys, label, className }: KeyboardShortcutProps) {
105
122
  return (
106
- <span id="keyboard-shortcut-span" data-sonance-name="kbd" className={cn("inline-flex items-center gap-1.5 sm:gap-2 flex-wrap", className)}>
107
- {label && <span id="keyboard-shortcut-span-label" className="text-xs sm:text-sm text-foreground-muted">{label}</span>}
123
+ <span data-sonance-name="kbd" className={cn("inline-flex items-center gap-1.5 sm:gap-2 flex-wrap", className)}>
124
+ {label && <span className="text-xs sm:text-sm text-foreground-muted">{label}</span>}
108
125
  <Kbd keys={keys} />
109
126
  </span>
110
127
  );
@@ -123,4 +140,3 @@ export const shortcuts = {
123
140
  newTab: ["cmd", "t"],
124
141
  closeTab: ["cmd", "w"],
125
142
  } as const;
126
-
@@ -11,9 +11,9 @@ const getItemStateStyles = (state?: ListboxItemState, isSelected?: boolean) => {
11
11
  if (!state || state === "default") return "";
12
12
 
13
13
  const stateMap: Record<string, string> = {
14
- hover: "bg-secondary-hover",
15
- focus: "ring-2 ring-border-focus ring-inset",
16
- selected: "bg-primary text-primary-foreground",
14
+ hover: "bg-white/50 dark:bg-white/5",
15
+ focus: "ring-2 ring-[color:var(--sonance-blue)]/30 ring-inset",
16
+ selected: "bg-[color:var(--sonance-blue)] text-white",
17
17
  disabled: "opacity-50 cursor-not-allowed",
18
18
  };
19
19
 
@@ -82,7 +82,7 @@ export function Listbox({
82
82
  <ul
83
83
  role="listbox"
84
84
  aria-multiselectable={multiple}
85
- className="border border-border bg-card divide-y divide-border overflow-hidden"
85
+ className="bg-white/70 dark:bg-white/[0.03] backdrop-blur-sm border border-black/8 dark:border-white/8 divide-y divide-black/5 dark:divide-white/5 rounded-xl overflow-hidden"
86
86
  >
87
87
  {children}
88
88
  </ul>
@@ -137,10 +137,10 @@ export const ListboxItem = forwardRef<HTMLLIElement, ListboxItemProps>(
137
137
  onClick={() => !isDisabled && onChange(value)}
138
138
  className={cn(
139
139
  "flex items-center gap-3 px-4 py-3 cursor-pointer",
140
- "transition-colors duration-150",
140
+ "transition-all duration-150",
141
141
  finalSelected
142
- ? "bg-primary text-primary-foreground"
143
- : "hover:bg-secondary-hover",
142
+ ? "bg-[color:var(--sonance-blue)] text-white"
143
+ : "hover:bg-white/50 dark:hover:bg-white/5",
144
144
  isDisabled && "cursor-not-allowed opacity-50",
145
145
  getItemStateStyles(state, finalSelected),
146
146
  className
@@ -186,7 +186,7 @@ export function ListboxSection({ title, children, className }: ListboxSectionPro
186
186
  return (
187
187
  <li data-sonance-name="listbox" className={className}>
188
188
  {title && (
189
- <div className="px-4 py-2 text-xs font-medium uppercase tracking-widest text-foreground-muted bg-background-secondary">
189
+ <div className="px-4 py-2 text-xs font-medium uppercase tracking-widest text-foreground-muted bg-white/50 dark:bg-white/[0.02]">
190
190
  {title}
191
191
  </div>
192
192
  )}
@@ -17,8 +17,12 @@ const Menubar = React.forwardRef<
17
17
  >(({ className, ...props }, ref) => (
18
18
  <MenubarPrimitive.Root
19
19
  ref={ref}
20
+ data-sonance-name="menubar"
20
21
  className={cn(
21
- "flex h-10 items-center space-x-1 rounded-sm border border-border bg-background p-1",
22
+ "flex h-10 items-center space-x-1 rounded-xl p-1",
23
+ "bg-white/70 dark:bg-white/5 backdrop-blur-sm",
24
+ "border border-black/8 dark:border-white/8",
25
+ "shadow-sm",
22
26
  className
23
27
  )}
24
28
  {...props}
@@ -33,9 +37,10 @@ const MenubarTrigger = React.forwardRef<
33
37
  <MenubarPrimitive.Trigger
34
38
  ref={ref}
35
39
  className={cn(
36
- "flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none",
37
- "focus:bg-secondary-hover focus:text-foreground",
38
- "data-[state=open]:bg-secondary-hover data-[state=open]:text-foreground",
40
+ "flex cursor-default select-none items-center rounded-lg px-3 py-1.5 text-sm font-medium outline-none",
41
+ "transition-all duration-150",
42
+ "focus:bg-white/60 dark:focus:bg-white/10 focus:text-foreground",
43
+ "data-[state=open]:bg-white/60 dark:data-[state=open]:bg-white/10 data-[state=open]:text-foreground",
39
44
  className
40
45
  )}
41
46
  {...props}
@@ -52,9 +57,10 @@ const MenubarSubTrigger = React.forwardRef<
52
57
  <MenubarPrimitive.SubTrigger
53
58
  ref={ref}
54
59
  className={cn(
55
- "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none",
56
- "focus:bg-secondary-hover focus:text-foreground",
57
- "data-[state=open]:bg-secondary-hover data-[state=open]:text-foreground",
60
+ "flex cursor-default select-none items-center rounded-xl px-2 py-1.5 text-sm outline-none",
61
+ "transition-all duration-150",
62
+ "focus:bg-white/60 dark:focus:bg-white/10 focus:text-foreground",
63
+ "data-[state=open]:bg-white/60 dark:data-[state=open]:bg-white/10 data-[state=open]:text-foreground",
58
64
  inset && "pl-8",
59
65
  className
60
66
  )}
@@ -73,7 +79,10 @@ const MenubarSubContent = React.forwardRef<
73
79
  <MenubarPrimitive.SubContent
74
80
  ref={ref}
75
81
  className={cn(
76
- "z-50 min-w-[8rem] overflow-hidden rounded-sm border border-border bg-card p-1 text-foreground shadow-md",
82
+ "z-50 min-w-[8rem] overflow-hidden rounded-xl p-1 text-foreground",
83
+ "bg-white/90 dark:bg-black/80 backdrop-blur-xl",
84
+ "border border-black/10 dark:border-white/10",
85
+ "shadow-[0_8px_32px_rgba(0,0,0,0.12)] dark:shadow-[0_8px_32px_rgba(0,0,0,0.4)]",
77
86
  "data-[state=open]:animate-in data-[state=closed]:animate-out",
78
87
  "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
79
88
  "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
@@ -103,9 +112,14 @@ const MenubarContent = React.forwardRef<
103
112
  alignOffset={alignOffset}
104
113
  sideOffset={sideOffset}
105
114
  className={cn(
106
- "z-50 min-w-[12rem] overflow-hidden rounded-sm border border-border bg-card p-1 text-foreground shadow-md",
107
- "data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
108
- "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",
115
+ "z-50 min-w-[12rem] overflow-hidden rounded-xl p-1 text-foreground",
116
+ "bg-white/90 dark:bg-black/80 backdrop-blur-xl",
117
+ "border border-black/10 dark:border-white/10",
118
+ "shadow-[0_8px_32px_rgba(0,0,0,0.12)] dark:shadow-[0_8px_32px_rgba(0,0,0,0.4)]",
119
+ "data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
120
+ "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
121
+ "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
122
+ "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
109
123
  className
110
124
  )}
111
125
  {...props}
@@ -124,8 +138,10 @@ const MenubarItem = React.forwardRef<
124
138
  <MenubarPrimitive.Item
125
139
  ref={ref}
126
140
  className={cn(
127
- "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none",
128
- "focus:bg-secondary-hover focus:text-foreground",
141
+ "relative flex cursor-default select-none items-center rounded-xl px-2 py-1.5 text-sm outline-none",
142
+ "transition-all duration-150",
143
+ "focus:bg-white/60 dark:focus:bg-white/10 focus:text-foreground",
144
+ "focus:shadow-[0_0_12px_var(--glow-primary-subtle)]",
129
145
  "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
130
146
  inset && "pl-8",
131
147
  className
@@ -142,15 +158,17 @@ const MenubarCheckboxItem = React.forwardRef<
142
158
  <MenubarPrimitive.CheckboxItem
143
159
  ref={ref}
144
160
  className={cn(
145
- "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none",
146
- "focus:bg-secondary-hover focus:text-foreground",
161
+ "relative flex cursor-default select-none items-center rounded-xl py-1.5 pl-8 pr-2 text-sm outline-none",
162
+ "transition-all duration-150",
163
+ "focus:bg-white/60 dark:focus:bg-white/10 focus:text-foreground",
164
+ "focus:shadow-[0_0_12px_var(--glow-primary-subtle)]",
147
165
  "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
148
166
  className
149
167
  )}
150
168
  checked={checked}
151
169
  {...props}
152
170
  >
153
- <span id="menubar-checkbox-item-span" className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
171
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
154
172
  <MenubarPrimitive.ItemIndicator>
155
173
  <Check className="h-4 w-4" />
156
174
  </MenubarPrimitive.ItemIndicator>
@@ -167,14 +185,16 @@ const MenubarRadioItem = React.forwardRef<
167
185
  <MenubarPrimitive.RadioItem
168
186
  ref={ref}
169
187
  className={cn(
170
- "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none",
171
- "focus:bg-secondary-hover focus:text-foreground",
188
+ "relative flex cursor-default select-none items-center rounded-xl py-1.5 pl-8 pr-2 text-sm outline-none",
189
+ "transition-all duration-150",
190
+ "focus:bg-white/60 dark:focus:bg-white/10 focus:text-foreground",
191
+ "focus:shadow-[0_0_12px_var(--glow-primary-subtle)]",
172
192
  "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
173
193
  className
174
194
  )}
175
195
  {...props}
176
196
  >
177
- <span id="menubar-radio-item-span" className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
197
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
178
198
  <MenubarPrimitive.ItemIndicator>
179
199
  <Circle className="h-2 w-2 fill-current" />
180
200
  </MenubarPrimitive.ItemIndicator>
@@ -208,7 +228,7 @@ const MenubarSeparator = React.forwardRef<
208
228
  >(({ className, ...props }, ref) => (
209
229
  <MenubarPrimitive.Separator
210
230
  ref={ref}
211
- className={cn("-mx-1 my-1 h-px bg-border", className)}
231
+ className={cn("-mx-1 my-1 h-px bg-black/8 dark:bg-white/8", className)}
212
232
  {...props}
213
233
  />
214
234
  ));
@@ -219,12 +239,20 @@ const MenubarShortcut = ({
219
239
  ...props
220
240
  }: React.HTMLAttributes<HTMLSpanElement>) => {
221
241
  return (
222
- <span id="menubar-shortcut-span" data-sonance-name="menubar"
242
+ <span
243
+ data-sonance-name="menubar"
244
+ className={cn(
245
+ "ml-auto text-xs tracking-widest text-foreground-muted",
246
+ "px-1.5 py-0.5 rounded-md",
247
+ "bg-white/40 dark:bg-white/5",
248
+ "border border-black/5 dark:border-white/10",
249
+ className
250
+ )}
223
251
  {...props}
224
252
  />
225
253
  );
226
254
  };
227
- MenubarShortcut.displayname = "MenubarShortcut";
255
+ MenubarShortcut.displayName = "MenubarShortcut";
228
256
 
229
257
  export {
230
258
  Menubar,
@@ -244,4 +272,3 @@ export {
244
272
  MenubarSub,
245
273
  MenubarShortcut,
246
274
  };
247
-
@@ -1,4 +1,5 @@
1
1
  import type { Meta, StoryObj } from '@storybook/nextjs-vite';
2
+ import Image from 'next/image';
2
3
  import {
3
4
  Navbar,
4
5
  NavbarContent,
@@ -9,6 +10,24 @@ import {
9
10
  } from './navbar';
10
11
  import { Button } from './button';
11
12
 
13
+ // Logo paths for different contexts
14
+ const LOGO_DARK = '/logos/sonance/Sonance_Logo_2C_Dark_RGB.png'; // Charcoal text - for light backgrounds
15
+ const LOGO_LIGHT = '/logos/sonance/Sonance_Logo_2C_Light_RGB.png'; // White/light text - for dark backgrounds
16
+
17
+ // Reusable logo component for stories
18
+ function NavbarLogo({ variant = 'dark' }: { variant?: 'dark' | 'light' }) {
19
+ return (
20
+ <Image
21
+ src={variant === 'dark' ? LOGO_DARK : LOGO_LIGHT}
22
+ alt="Sonance"
23
+ width={120}
24
+ height={24}
25
+ className="h-5 w-auto object-contain"
26
+ priority
27
+ />
28
+ );
29
+ }
30
+
12
31
  const meta: Meta<typeof Navbar> = {
13
32
  title: 'Components/Navigation/Navbar',
14
33
  component: Navbar,
@@ -39,7 +58,7 @@ export const Default: Story = {
39
58
  <Navbar>
40
59
  <NavbarContent>
41
60
  <NavbarBrand>
42
- <span id="nav-span-sonance" className="text-xl font-semibold">Sonance</span>
61
+ <NavbarLogo variant="dark" />
43
62
  </NavbarBrand>
44
63
  <NavbarItems>
45
64
  <NavbarItem href="#" active>Home</NavbarItem>
@@ -58,14 +77,14 @@ export const Dark: Story = {
58
77
  <Navbar variant="dark">
59
78
  <NavbarContent>
60
79
  <NavbarBrand>
61
- <span id="nav-span-sonance" className="text-xl font-semibold">Sonance</span>
80
+ <NavbarLogo variant="light" />
62
81
  </NavbarBrand>
63
82
  <NavbarItems>
64
83
  <NavbarItem href="#" active>Home</NavbarItem>
65
84
  <NavbarItem href="#">Products</NavbarItem>
66
85
  <NavbarItem href="#">About</NavbarItem>
67
86
  </NavbarItems>
68
- <Button id="nav-button-inverted" size="sm" variant="inverted">Sign In</Button>
87
+ <Button id="nav-button-outline" size="sm" variant="outline" className="text-white border-white/30 hover:bg-white/10">Sign In</Button>
69
88
  </NavbarContent>
70
89
  </Navbar>
71
90
  ),
@@ -77,14 +96,14 @@ export const Transparent: Story = {
77
96
  <Navbar variant="transparent" className="text-white">
78
97
  <NavbarContent>
79
98
  <NavbarBrand>
80
- <span id="nav-span-sonance" className="text-xl font-semibold">Sonance</span>
99
+ <NavbarLogo variant="light" />
81
100
  </NavbarBrand>
82
101
  <NavbarItems>
83
102
  <NavbarItem href="#" active>Home</NavbarItem>
84
103
  <NavbarItem href="#">Products</NavbarItem>
85
104
  <NavbarItem href="#">About</NavbarItem>
86
105
  </NavbarItems>
87
- <Button id="nav-button-inverted" size="sm" variant="inverted">Sign In</Button>
106
+ <Button id="nav-button-outline" size="sm" variant="outline" className="text-white border-white/30 hover:bg-white/10">Sign In</Button>
88
107
  </NavbarContent>
89
108
  </Navbar>
90
109
  </div>
@@ -97,7 +116,7 @@ export const Blur: Story = {
97
116
  <Navbar variant="blur">
98
117
  <NavbarContent>
99
118
  <NavbarBrand>
100
- <span id="nav-span-sonance" className="text-xl font-semibold">Sonance</span>
119
+ <NavbarLogo variant="dark" />
101
120
  </NavbarBrand>
102
121
  <NavbarItems>
103
122
  <NavbarItem href="#" active>Home</NavbarItem>
@@ -114,10 +133,56 @@ export const Blur: Story = {
114
133
  ),
115
134
  };
116
135
 
136
+ export const Sticky: Story = {
137
+ render: () => (
138
+ <div className="h-[400px] overflow-auto bg-background-secondary">
139
+ <Navbar sticky>
140
+ <NavbarContent>
141
+ <NavbarBrand>
142
+ <NavbarLogo variant="dark" />
143
+ </NavbarBrand>
144
+ <NavbarItems>
145
+ <NavbarItem href="#" active>Home</NavbarItem>
146
+ <NavbarItem href="#">Products</NavbarItem>
147
+ <NavbarItem href="#">About</NavbarItem>
148
+ </NavbarItems>
149
+ <Button id="nav-button" size="sm">Sign In</Button>
150
+ </NavbarContent>
151
+ </Navbar>
152
+ <div className="p-8 space-y-4">
153
+ {Array.from({ length: 10 }).map((_, i) => (
154
+ <p key={i} className="text-foreground-secondary">
155
+ Scroll down to see the sticky navbar in action. Lorem ipsum dolor sit amet,
156
+ consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore.
157
+ </p>
158
+ ))}
159
+ </div>
160
+ </div>
161
+ ),
162
+ };
163
+
164
+ export const NoBorder: Story = {
165
+ render: () => (
166
+ <Navbar bordered={false}>
167
+ <NavbarContent>
168
+ <NavbarBrand>
169
+ <NavbarLogo variant="dark" />
170
+ </NavbarBrand>
171
+ <NavbarItems>
172
+ <NavbarItem href="#" active>Home</NavbarItem>
173
+ <NavbarItem href="#">Products</NavbarItem>
174
+ <NavbarItem href="#">About</NavbarItem>
175
+ </NavbarItems>
176
+ <Button id="nav-button" size="sm">Sign In</Button>
177
+ </NavbarContent>
178
+ </Navbar>
179
+ ),
180
+ };
181
+
117
182
  export const Responsive: Story = {
118
183
  render: () => (
119
184
  <ResponsiveNavbar
120
- brand={<span id="nav-span-sonance" className="text-xl font-semibold">Sonance</span>}
185
+ brand={<NavbarLogo variant="dark" />}
121
186
  items={[
122
187
  { label: 'Home', href: '#', active: true },
123
188
  { label: 'Products', href: '#' },
@@ -129,13 +194,12 @@ export const Responsive: Story = {
129
194
  ),
130
195
  };
131
196
 
132
- export const WithLogo: Story = {
197
+ export const WithActions: Story = {
133
198
  render: () => (
134
199
  <Navbar>
135
200
  <NavbarContent>
136
201
  <NavbarBrand>
137
- <div className="w-8 h-8 bg-primary rounded" />
138
- <span id="nav-span-sonance" className="text-xl font-semibold">Sonance</span>
202
+ <NavbarLogo variant="dark" />
139
203
  </NavbarBrand>
140
204
  <NavbarItems>
141
205
  <NavbarItem href="#" active>Home</NavbarItem>
@@ -160,7 +224,7 @@ export const ResponsiveMatrix: Story = {
160
224
  <h4 id="nav-h4-mobile-375px" className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
161
225
  <div className="w-[375px] border border-dashed border-border overflow-hidden">
162
226
  <ResponsiveNavbar
163
- brand={<span id="responsive-matrix-span-sonance" className="text-lg font-semibold">Sonance</span>}
227
+ brand={<NavbarLogo variant="dark" />}
164
228
  items={[
165
229
  { label: 'Home', href: '#', active: true },
166
230
  { label: 'Products', href: '#' },
@@ -177,7 +241,7 @@ export const ResponsiveMatrix: Story = {
177
241
  <Navbar>
178
242
  <NavbarContent>
179
243
  <NavbarBrand>
180
- <span id="nav-span-sonance" className="text-xl font-semibold">Sonance</span>
244
+ <NavbarLogo variant="dark" />
181
245
  </NavbarBrand>
182
246
  <NavbarItems>
183
247
  <NavbarItem href="#" active>Home</NavbarItem>
@@ -196,7 +260,7 @@ export const ResponsiveMatrix: Story = {
196
260
  <Navbar>
197
261
  <NavbarContent>
198
262
  <NavbarBrand>
199
- <span id="nav-span-sonance" className="text-xl font-semibold">Sonance</span>
263
+ <NavbarLogo variant="dark" />
200
264
  </NavbarBrand>
201
265
  <NavbarItems>
202
266
  <NavbarItem href="#" active>Home</NavbarItem>
@@ -216,3 +280,66 @@ export const ResponsiveMatrix: Story = {
216
280
  </div>
217
281
  ),
218
282
  };
283
+
284
+ // All Variants Side by Side
285
+ export const AllVariants: Story = {
286
+ render: () => (
287
+ <div className="space-y-8">
288
+ <div>
289
+ <h4 className="text-xs uppercase text-foreground-muted mb-2">Default</h4>
290
+ <Navbar>
291
+ <NavbarContent>
292
+ <NavbarBrand><NavbarLogo variant="dark" /></NavbarBrand>
293
+ <NavbarItems>
294
+ <NavbarItem href="#" active>Home</NavbarItem>
295
+ <NavbarItem href="#">Products</NavbarItem>
296
+ </NavbarItems>
297
+ <Button size="sm">Sign In</Button>
298
+ </NavbarContent>
299
+ </Navbar>
300
+ </div>
301
+
302
+ <div>
303
+ <h4 className="text-xs uppercase text-foreground-muted mb-2">Dark</h4>
304
+ <Navbar variant="dark">
305
+ <NavbarContent>
306
+ <NavbarBrand><NavbarLogo variant="light" /></NavbarBrand>
307
+ <NavbarItems>
308
+ <NavbarItem href="#" active>Home</NavbarItem>
309
+ <NavbarItem href="#">Products</NavbarItem>
310
+ </NavbarItems>
311
+ <Button size="sm" variant="outline" className="text-white border-white/30 hover:bg-white/10">Sign In</Button>
312
+ </NavbarContent>
313
+ </Navbar>
314
+ </div>
315
+
316
+ <div className="bg-gradient-to-r from-sonance-charcoal to-sonance-gray-700 p-0">
317
+ <h4 className="text-xs uppercase text-white/60 mb-2 px-4 pt-4">Transparent (on gradient)</h4>
318
+ <Navbar variant="transparent" className="text-white">
319
+ <NavbarContent>
320
+ <NavbarBrand><NavbarLogo variant="light" /></NavbarBrand>
321
+ <NavbarItems>
322
+ <NavbarItem href="#" active>Home</NavbarItem>
323
+ <NavbarItem href="#">Products</NavbarItem>
324
+ </NavbarItems>
325
+ <Button size="sm" variant="outline" className="text-white border-white/30 hover:bg-white/10">Sign In</Button>
326
+ </NavbarContent>
327
+ </Navbar>
328
+ </div>
329
+
330
+ <div className="bg-gradient-to-r from-sonance-blue to-foundation-green p-0">
331
+ <h4 className="text-xs uppercase text-white/60 mb-2 px-4 pt-4">Blur (on gradient)</h4>
332
+ <Navbar variant="blur">
333
+ <NavbarContent>
334
+ <NavbarBrand><NavbarLogo variant="dark" /></NavbarBrand>
335
+ <NavbarItems>
336
+ <NavbarItem href="#" active>Home</NavbarItem>
337
+ <NavbarItem href="#">Products</NavbarItem>
338
+ </NavbarItems>
339
+ <Button size="sm">Sign In</Button>
340
+ </NavbarContent>
341
+ </Navbar>
342
+ </div>
343
+ </div>
344
+ ),
345
+ };
@@ -13,14 +13,30 @@ interface NavbarProps extends React.HTMLAttributes<HTMLElement> {
13
13
  export const Navbar = forwardRef<HTMLElement, NavbarProps>(
14
14
  ({ className, variant = "default", sticky = false, bordered = true, children, ...props }, ref) => {
15
15
  const variantClasses = {
16
- default: "bg-background",
16
+ default: "bg-white/70 dark:bg-white/[0.03] backdrop-blur-lg",
17
17
  dark: "bg-sonance-charcoal text-sonance-white",
18
18
  transparent: "bg-transparent",
19
- blur: "bg-backdrop backdrop-blur-md",
19
+ blur: "bg-white/60 dark:bg-black/40 backdrop-blur-xl",
20
+ };
21
+
22
+ const borderClasses = {
23
+ default: "border-b border-black/8 dark:border-white/8",
24
+ dark: "border-b border-white/10",
25
+ transparent: "",
26
+ blur: "border-b border-black/8 dark:border-white/8",
20
27
  };
21
28
 
22
29
  return (
23
- <nav data-sonance-name="navbar"
30
+ <nav
31
+ ref={ref}
32
+ data-sonance-name="navbar"
33
+ className={cn(
34
+ "w-full px-4 md:px-6 py-3",
35
+ variantClasses[variant],
36
+ bordered && borderClasses[variant],
37
+ sticky && "sticky top-0 z-50",
38
+ className
39
+ )}
24
40
  {...props}
25
41
  >
26
42
  {children}
@@ -133,7 +149,8 @@ export function NavbarMobileMenu({ isOpen, children, className }: NavbarMobileMe
133
149
  <div
134
150
  className={cn(
135
151
  "md:hidden absolute left-0 right-0 top-full",
136
- "bg-background border-b border-border shadow-lg",
152
+ "bg-white/90 dark:bg-black/80 backdrop-blur-xl",
153
+ "border-b border-black/10 dark:border-white/10 shadow-xl",
137
154
  "animate-in slide-in-from-top-2 duration-200",
138
155
  className
139
156
  )}
@@ -198,7 +215,7 @@ export function ResponsiveNavbar({
198
215
  {item.label}
199
216
  </a>
200
217
  ))}
201
- {actions && <div className="pt-4 border-t border-border">{actions}</div>}
218
+ {actions && <div className="pt-4 border-t border-black/8 dark:border-white/8">{actions}</div>}
202
219
  </NavbarMobileMenu>
203
220
  </Navbar>
204
221
  );
@@ -12,6 +12,7 @@ const NavigationMenu = React.forwardRef<
12
12
  >(({ className, children, ...props }, ref) => (
13
13
  <NavigationMenuPrimitive.Root
14
14
  ref={ref}
15
+ data-sonance-name="navigation-menu"
15
16
  className={cn(
16
17
  "relative z-10 flex max-w-max flex-1 items-center justify-center",
17
18
  className
@@ -42,7 +43,16 @@ NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;
42
43
  const NavigationMenuItem = NavigationMenuPrimitive.Item;
43
44
 
44
45
  const navigationMenuTriggerStyle = cva(
45
- "group inline-flex h-10 w-max items-center justify-center rounded-sm bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-secondary-hover hover:text-foreground focus:bg-secondary-hover focus:text-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-secondary-hover/50 data-[state=open]:bg-secondary-hover/50"
46
+ cn(
47
+ "group inline-flex h-10 w-max items-center justify-center rounded-xl px-4 py-2 text-sm font-medium",
48
+ "transition-all duration-150",
49
+ "bg-transparent backdrop-blur-sm",
50
+ "hover:bg-white/60 dark:hover:bg-white/10 hover:text-foreground",
51
+ "focus:bg-white/60 dark:focus:bg-white/10 focus:text-foreground focus:outline-none",
52
+ "disabled:pointer-events-none disabled:opacity-50",
53
+ "data-[active]:bg-white/50 dark:data-[active]:bg-white/8",
54
+ "data-[state=open]:bg-white/60 dark:data-[state=open]:bg-white/10"
55
+ )
46
56
  );
47
57
 
48
58
  const NavigationMenuTrigger = React.forwardRef<
@@ -70,7 +80,12 @@ const NavigationMenuContent = React.forwardRef<
70
80
  <NavigationMenuPrimitive.Content
71
81
  ref={ref}
72
82
  className={cn(
73
- "left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto",
83
+ "left-0 top-0 w-full",
84
+ "data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out",
85
+ "data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out",
86
+ "data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52",
87
+ "data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52",
88
+ "md:absolute md:w-auto",
74
89
  className
75
90
  )}
76
91
  {...props}
@@ -84,10 +99,18 @@ const NavigationMenuViewport = React.forwardRef<
84
99
  React.ElementRef<typeof NavigationMenuPrimitive.Viewport>,
85
100
  React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>
86
101
  >(({ className, ...props }, ref) => (
87
- <div data-sonance-name="navigation-menu" className={cn("absolute left-0 top-full flex justify-center")}>
102
+ <div
103
+ data-sonance-name="navigation-menu"
104
+ className={cn("absolute left-0 top-full flex justify-center")}
105
+ >
88
106
  <NavigationMenuPrimitive.Viewport
89
107
  className={cn(
90
- "origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-sm border border-border bg-card text-foreground shadow-lg",
108
+ "origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden",
109
+ "rounded-xl backdrop-blur-xl",
110
+ "bg-white/90 dark:bg-black/80",
111
+ "border border-black/10 dark:border-white/10",
112
+ "shadow-[0_8px_32px_rgba(0,0,0,0.12)] dark:shadow-[0_8px_32px_rgba(0,0,0,0.4)]",
113
+ "text-foreground",
91
114
  "data-[state=open]:animate-in data-[state=closed]:animate-out",
92
115
  "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90",
93
116
  "md:w-[var(--radix-navigation-menu-viewport-width)]",
@@ -115,7 +138,7 @@ const NavigationMenuIndicator = React.forwardRef<
115
138
  )}
116
139
  {...props}
117
140
  >
118
- <div className="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" />
141
+ <div className="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-white/80 dark:bg-white/10 shadow-md" />
119
142
  </NavigationMenuPrimitive.Indicator>
120
143
  ));
121
144
  NavigationMenuIndicator.displayName =
@@ -132,4 +155,3 @@ export {
132
155
  NavigationMenuIndicator,
133
156
  NavigationMenuViewport,
134
157
  };
135
-