@gv-tech/ui-web 2.15.1 → 2.16.0

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 (134) hide show
  1. package/dist/accordion.cjs +1 -1
  2. package/dist/accordion.mjs +3 -3
  3. package/dist/alert-dialog.cjs +2 -2
  4. package/dist/alert-dialog.mjs +16 -16
  5. package/dist/alert.cjs +1 -1
  6. package/dist/alert.mjs +1 -1
  7. package/dist/avatar.cjs +1 -1
  8. package/dist/avatar.mjs +34 -34
  9. package/dist/badge.cjs +1 -1
  10. package/dist/badge.mjs +1 -1
  11. package/dist/breadcrumb.cjs +1 -1
  12. package/dist/breadcrumb.mjs +1 -1
  13. package/dist/button.cjs +1 -1
  14. package/dist/button.mjs +1 -1
  15. package/dist/calendar.cjs +1 -1
  16. package/dist/calendar.mjs +1 -1
  17. package/dist/card.cjs +1 -1
  18. package/dist/card.mjs +1 -1
  19. package/dist/carousel.cjs +1 -1
  20. package/dist/carousel.mjs +1 -1
  21. package/dist/chart.cjs +1 -1
  22. package/dist/chart.mjs +1 -1
  23. package/dist/checkbox.cjs +1 -1
  24. package/dist/checkbox.mjs +2 -2
  25. package/dist/command.cjs +1 -1
  26. package/dist/command.mjs +114 -114
  27. package/dist/context-menu.cjs +1 -1
  28. package/dist/context-menu.mjs +68 -68
  29. package/dist/dialog.cjs +1 -1
  30. package/dist/dialog.mjs +21 -21
  31. package/dist/drawer.cjs +1 -1
  32. package/dist/drawer.mjs +16 -16
  33. package/dist/dropdown-menu.cjs +1 -1
  34. package/dist/dropdown-menu.mjs +43 -43
  35. package/dist/form.cjs +1 -1
  36. package/dist/form.mjs +1 -1
  37. package/dist/hover-card.cjs +1 -1
  38. package/dist/hover-card.mjs +2 -2
  39. package/dist/index.cjs +1 -1
  40. package/dist/index.d.ts +28 -0
  41. package/dist/index.mjs +22 -20
  42. package/dist/input.cjs +1 -1
  43. package/dist/input.mjs +1 -1
  44. package/dist/label.cjs +1 -1
  45. package/dist/label.mjs +2 -2
  46. package/dist/menubar.cjs +1 -1
  47. package/dist/menubar.mjs +77 -77
  48. package/dist/navigation-menu.cjs +1 -1
  49. package/dist/navigation-menu.mjs +57 -57
  50. package/dist/pagination.cjs +1 -1
  51. package/dist/pagination.mjs +1 -1
  52. package/dist/popover.cjs +1 -1
  53. package/dist/popover.mjs +62 -62
  54. package/dist/progress.cjs +2 -2
  55. package/dist/progress.mjs +2 -2
  56. package/dist/radio-group.cjs +1 -1
  57. package/dist/radio-group.mjs +36 -36
  58. package/dist/resizable.cjs +1 -1
  59. package/dist/resizable.mjs +1 -1
  60. package/dist/scroll-area.cjs +1 -1
  61. package/dist/scroll-area.mjs +88 -88
  62. package/dist/search.cjs +1 -1
  63. package/dist/search.mjs +51 -38
  64. package/dist/select.cjs +1 -1
  65. package/dist/select.mjs +74 -74
  66. package/dist/separator.cjs +1 -1
  67. package/dist/separator.mjs +9 -9
  68. package/dist/sheet.cjs +1 -1
  69. package/dist/sheet.mjs +12 -12
  70. package/dist/skeleton.cjs +1 -1
  71. package/dist/skeleton.mjs +1 -1
  72. package/dist/slider.cjs +1 -1
  73. package/dist/slider.mjs +2 -2
  74. package/dist/switch.cjs +1 -1
  75. package/dist/switch.mjs +12 -12
  76. package/dist/table-of-contents.cjs +1 -0
  77. package/dist/table-of-contents.d.ts +35 -0
  78. package/dist/table-of-contents.mjs +160 -0
  79. package/dist/table.cjs +1 -1
  80. package/dist/table.mjs +1 -1
  81. package/dist/tabs.cjs +1 -1
  82. package/dist/tabs.mjs +41 -41
  83. package/dist/text.cjs +1 -1
  84. package/dist/text.mjs +1 -1
  85. package/dist/textarea.cjs +1 -1
  86. package/dist/textarea.mjs +1 -1
  87. package/dist/{theme-toggle-B4VZTDpe.js → theme-toggle-DXQGNfCe.js} +1 -1
  88. package/dist/{theme-toggle-WtPW9UZi.mjs → theme-toggle-tHXIbr8W.mjs} +1 -1
  89. package/dist/theme-toggle.cjs +1 -1
  90. package/dist/theme-toggle.mjs +2 -2
  91. package/dist/toast.cjs +1 -1
  92. package/dist/toast.mjs +35 -35
  93. package/dist/toggle-group.cjs +1 -1
  94. package/dist/toggle-group.mjs +15 -15
  95. package/dist/toggle.cjs +1 -1
  96. package/dist/toggle.mjs +4 -4
  97. package/dist/tooltip.cjs +1 -1
  98. package/dist/tooltip.mjs +3 -3
  99. package/dist/utils-DY6fhrgS.mjs +12 -0
  100. package/dist/utils-cdbZV8DZ.js +1 -0
  101. package/package.json +1 -1
  102. package/src/accordion.tsx +2 -2
  103. package/src/alert-dialog.tsx +6 -6
  104. package/src/avatar.tsx +3 -3
  105. package/src/checkbox.tsx +1 -1
  106. package/src/command.tsx +7 -7
  107. package/src/context-menu.tsx +8 -8
  108. package/src/dialog.tsx +4 -4
  109. package/src/drawer.tsx +3 -3
  110. package/src/dropdown-menu.tsx +8 -8
  111. package/src/hover-card.tsx +1 -1
  112. package/src/index.ts +4 -1
  113. package/src/label.tsx +1 -1
  114. package/src/lib/utils.ts +10 -0
  115. package/src/menubar.tsx +10 -10
  116. package/src/navigation-menu.tsx +6 -6
  117. package/src/popover.tsx +1 -1
  118. package/src/progress.tsx +1 -1
  119. package/src/radio-group.tsx +2 -2
  120. package/src/scroll-area.tsx +2 -2
  121. package/src/search.tsx +15 -4
  122. package/src/select.tsx +7 -7
  123. package/src/separator.tsx +1 -1
  124. package/src/sheet.tsx +4 -4
  125. package/src/slider.tsx +1 -1
  126. package/src/switch.tsx +1 -1
  127. package/src/table-of-contents.tsx +285 -0
  128. package/src/tabs.tsx +3 -3
  129. package/src/toast.tsx +6 -6
  130. package/src/toggle-group.tsx +2 -2
  131. package/src/toggle.tsx +1 -1
  132. package/src/tooltip.tsx +2 -2
  133. package/dist/utils-B6yFEsav.mjs +0 -8
  134. package/dist/utils-IjLH3w2e.js +0 -1
package/src/menubar.tsx CHANGED
@@ -51,7 +51,7 @@ const Menubar = React.forwardRef<
51
51
  {...props}
52
52
  />
53
53
  ));
54
- Menubar.displayName = MenubarPrimitive.Root.displayName;
54
+ Menubar.displayName = MenubarPrimitive.Root?.displayName || 'Menubar';
55
55
 
56
56
  const MenubarTrigger = React.forwardRef<
57
57
  React.ElementRef<typeof MenubarPrimitive.Trigger>,
@@ -66,7 +66,7 @@ const MenubarTrigger = React.forwardRef<
66
66
  {...props}
67
67
  />
68
68
  ));
69
- MenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName;
69
+ MenubarTrigger.displayName = MenubarPrimitive.Trigger?.displayName || 'MenubarTrigger';
70
70
 
71
71
  const MenubarSubTrigger = React.forwardRef<
72
72
  React.ElementRef<typeof MenubarPrimitive.SubTrigger>,
@@ -85,7 +85,7 @@ const MenubarSubTrigger = React.forwardRef<
85
85
  <ChevronRight className="ml-auto h-4 w-4" />
86
86
  </MenubarPrimitive.SubTrigger>
87
87
  ));
88
- MenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName;
88
+ MenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger?.displayName || 'MenubarSubTrigger';
89
89
 
90
90
  const MenubarSubContent = React.forwardRef<
91
91
  React.ElementRef<typeof MenubarPrimitive.SubContent>,
@@ -100,7 +100,7 @@ const MenubarSubContent = React.forwardRef<
100
100
  {...props}
101
101
  />
102
102
  ));
103
- MenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName;
103
+ MenubarSubContent.displayName = MenubarPrimitive.SubContent?.displayName || 'MenubarSubContent';
104
104
 
105
105
  const MenubarContent = React.forwardRef<
106
106
  React.ElementRef<typeof MenubarPrimitive.Content>,
@@ -120,7 +120,7 @@ const MenubarContent = React.forwardRef<
120
120
  />
121
121
  </MenubarPrimitive.Portal>
122
122
  ));
123
- MenubarContent.displayName = MenubarPrimitive.Content.displayName;
123
+ MenubarContent.displayName = MenubarPrimitive.Content?.displayName || 'MenubarContent';
124
124
 
125
125
  const MenubarItem = React.forwardRef<
126
126
  React.ElementRef<typeof MenubarPrimitive.Item>,
@@ -136,7 +136,7 @@ const MenubarItem = React.forwardRef<
136
136
  {...props}
137
137
  />
138
138
  ));
139
- MenubarItem.displayName = MenubarPrimitive.Item.displayName;
139
+ MenubarItem.displayName = MenubarPrimitive.Item?.displayName || 'MenubarItem';
140
140
 
141
141
  const MenubarCheckboxItem = React.forwardRef<
142
142
  React.ElementRef<typeof MenubarPrimitive.CheckboxItem>,
@@ -159,7 +159,7 @@ const MenubarCheckboxItem = React.forwardRef<
159
159
  {children}
160
160
  </MenubarPrimitive.CheckboxItem>
161
161
  ));
162
- MenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName;
162
+ MenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem?.displayName || 'MenubarCheckboxItem';
163
163
 
164
164
  const MenubarRadioItem = React.forwardRef<
165
165
  React.ElementRef<typeof MenubarPrimitive.RadioItem>,
@@ -181,7 +181,7 @@ const MenubarRadioItem = React.forwardRef<
181
181
  {children}
182
182
  </MenubarPrimitive.RadioItem>
183
183
  ));
184
- MenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName;
184
+ MenubarRadioItem.displayName = MenubarPrimitive.RadioItem?.displayName || 'MenubarRadioItem';
185
185
 
186
186
  const MenubarLabel = React.forwardRef<
187
187
  React.ElementRef<typeof MenubarPrimitive.Label>,
@@ -193,7 +193,7 @@ const MenubarLabel = React.forwardRef<
193
193
  {...props}
194
194
  />
195
195
  ));
196
- MenubarLabel.displayName = MenubarPrimitive.Label.displayName;
196
+ MenubarLabel.displayName = MenubarPrimitive.Label?.displayName || 'MenubarLabel';
197
197
 
198
198
  const MenubarSeparator = React.forwardRef<
199
199
  React.ElementRef<typeof MenubarPrimitive.Separator>,
@@ -201,7 +201,7 @@ const MenubarSeparator = React.forwardRef<
201
201
  >(({ className, ...props }, ref) => (
202
202
  <MenubarPrimitive.Separator ref={ref} className={cn('bg-muted -mx-1 my-1 h-px', className)} {...props} />
203
203
  ));
204
- MenubarSeparator.displayName = MenubarPrimitive.Separator.displayName;
204
+ MenubarSeparator.displayName = MenubarPrimitive.Separator?.displayName || 'MenubarSeparator';
205
205
 
206
206
  const MenubarShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement> & MenubarShortcutBaseProps) => {
207
207
  return <span className={cn('text-muted-foreground ml-auto text-xs tracking-widest', className)} {...props} />;
@@ -30,7 +30,7 @@ const NavigationMenu = React.forwardRef<
30
30
  <NavigationMenuViewport />
31
31
  </NavigationMenuPrimitive.Root>
32
32
  ));
33
- NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName;
33
+ NavigationMenu.displayName = NavigationMenuPrimitive.Root?.displayName || 'NavigationMenu';
34
34
 
35
35
  const NavigationMenuList = React.forwardRef<
36
36
  React.ElementRef<typeof NavigationMenuPrimitive.List>,
@@ -42,7 +42,7 @@ const NavigationMenuList = React.forwardRef<
42
42
  {...props}
43
43
  />
44
44
  ));
45
- NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;
45
+ NavigationMenuList.displayName = NavigationMenuPrimitive.List?.displayName || 'NavigationMenuList';
46
46
 
47
47
  const NavigationMenuItem = NavigationMenuPrimitive.Item;
48
48
 
@@ -66,7 +66,7 @@ const NavigationMenuTrigger = React.forwardRef<
66
66
  />
67
67
  </NavigationMenuPrimitive.Trigger>
68
68
  ));
69
- NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName;
69
+ NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger?.displayName || 'NavigationMenuTrigger';
70
70
 
71
71
  const NavigationMenuContent = React.forwardRef<
72
72
  React.ElementRef<typeof NavigationMenuPrimitive.Content>,
@@ -81,7 +81,7 @@ const NavigationMenuContent = React.forwardRef<
81
81
  {...props}
82
82
  />
83
83
  ));
84
- NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName;
84
+ NavigationMenuContent.displayName = NavigationMenuPrimitive.Content?.displayName || 'NavigationMenuContent';
85
85
 
86
86
  const NavigationMenuLink = NavigationMenuPrimitive.Link;
87
87
 
@@ -100,7 +100,7 @@ const NavigationMenuViewport = React.forwardRef<
100
100
  />
101
101
  </div>
102
102
  ));
103
- NavigationMenuViewport.displayName = NavigationMenuPrimitive.Viewport.displayName;
103
+ NavigationMenuViewport.displayName = NavigationMenuPrimitive.Viewport?.displayName || 'NavigationMenuViewport';
104
104
 
105
105
  const NavigationMenuIndicator = React.forwardRef<
106
106
  React.ElementRef<typeof NavigationMenuPrimitive.Indicator>,
@@ -117,7 +117,7 @@ const NavigationMenuIndicator = React.forwardRef<
117
117
  <div className="bg-border relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm shadow-md" />
118
118
  </NavigationMenuPrimitive.Indicator>
119
119
  ));
120
- NavigationMenuIndicator.displayName = NavigationMenuPrimitive.Indicator.displayName;
120
+ NavigationMenuIndicator.displayName = NavigationMenuPrimitive.Indicator?.displayName || 'NavigationMenuIndicator';
121
121
 
122
122
  export {
123
123
  NavigationMenu,
package/src/popover.tsx CHANGED
@@ -34,7 +34,7 @@ const PopoverContent = React.forwardRef<
34
34
  />
35
35
  </PopoverPrimitive.Portal>
36
36
  ));
37
- PopoverContent.displayName = PopoverPrimitive.Content.displayName;
37
+ PopoverContent.displayName = PopoverPrimitive.Content?.displayName || 'PopoverContent';
38
38
 
39
39
  export { Popover, PopoverAnchor, PopoverContent, PopoverTrigger };
40
40
  export type {
package/src/progress.tsx CHANGED
@@ -22,7 +22,7 @@ const Progress = React.forwardRef<
22
22
  />
23
23
  </ProgressPrimitive.Root>
24
24
  ));
25
- Progress.displayName = ProgressPrimitive.Root.displayName;
25
+ Progress.displayName = ProgressPrimitive.Root?.displayName || 'Progress';
26
26
 
27
27
  export { Progress };
28
28
  export type { ProgressBaseProps as ProgressProps };
@@ -14,7 +14,7 @@ const RadioGroup = React.forwardRef<React.ElementRef<typeof RadioGroupPrimitive.
14
14
  return <RadioGroupPrimitive.Root className={cn('grid gap-2', className)} {...props} ref={ref} />;
15
15
  },
16
16
  );
17
- RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
17
+ RadioGroup.displayName = RadioGroupPrimitive.Root?.displayName || 'RadioGroup';
18
18
 
19
19
  export interface RadioGroupItemProps
20
20
  extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>, RadioGroupItemBaseProps {}
@@ -37,6 +37,6 @@ const RadioGroupItem = React.forwardRef<React.ElementRef<typeof RadioGroupPrimit
37
37
  );
38
38
  },
39
39
  );
40
- RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
40
+ RadioGroupItem.displayName = RadioGroupPrimitive.Item?.displayName || 'RadioGroupItem';
41
41
 
42
42
  export { RadioGroup, RadioGroupItem };
@@ -16,7 +16,7 @@ const ScrollArea = React.forwardRef<
16
16
  <ScrollAreaPrimitive.Corner />
17
17
  </ScrollAreaPrimitive.Root>
18
18
  ));
19
- ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
19
+ ScrollArea.displayName = ScrollAreaPrimitive.Root?.displayName || 'ScrollArea';
20
20
 
21
21
  const ScrollBar = React.forwardRef<
22
22
  React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
@@ -36,7 +36,7 @@ const ScrollBar = React.forwardRef<
36
36
  <ScrollAreaPrimitive.ScrollAreaThumb className="bg-border relative flex-1 rounded-full" />
37
37
  </ScrollAreaPrimitive.ScrollAreaScrollbar>
38
38
  ));
39
- ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
39
+ ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar?.displayName || 'ScrollBar';
40
40
 
41
41
  export { ScrollArea, ScrollBar };
42
42
  export type { ScrollAreaBaseProps as ScrollAreaProps, ScrollBarBaseProps as ScrollBarProps };
package/src/search.tsx CHANGED
@@ -59,7 +59,10 @@ export function Search({ children, open: customOpen, onOpenChange }: SearchProps
59
59
  export interface SearchTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, SearchTriggerBaseProps {}
60
60
 
61
61
  export const SearchTrigger = React.forwardRef<HTMLButtonElement, SearchTriggerProps>(
62
- ({ className, placeholder = 'Search docs...', variant = 'default', ...props }, ref) => {
62
+ ({ className, placeholder, variant = 'default', responsive = false, ...props }, ref) => {
63
+ const defaultPlaceholder = variant === 'compact' ? 'Search...' : 'Search docs...';
64
+ const activePlaceholder = placeholder || defaultPlaceholder;
65
+
63
66
  return (
64
67
  <Button
65
68
  variant="outline"
@@ -67,7 +70,7 @@ export const SearchTrigger = React.forwardRef<HTMLButtonElement, SearchTriggerPr
67
70
  'text-muted-foreground relative h-9 text-sm transition-all transition-colors',
68
71
  variant === 'default'
69
72
  ? 'w-full justify-start pr-12'
70
- : 'w-9 justify-center px-0 md:w-40 md:justify-start md:px-3 md:pr-12 lg:w-64',
73
+ : cn('w-9 justify-center px-0', responsive && '2xl:w-48 2xl:justify-start 2xl:px-3 2xl:pr-12'),
71
74
  className,
72
75
  )}
73
76
  ref={ref}
@@ -75,9 +78,17 @@ export const SearchTrigger = React.forwardRef<HTMLButtonElement, SearchTriggerPr
75
78
  >
76
79
  <span className="inline-flex items-center gap-2">
77
80
  <SearchIcon className="h-4 w-4 shrink-0" />
78
- <span className={cn('truncate', variant === 'compact' && 'hidden md:inline')}>{placeholder}</span>
81
+ <span className={cn('truncate', variant === 'compact' && (responsive ? 'hidden 2xl:inline' : 'hidden'))}>
82
+ {activePlaceholder}
83
+ </span>
79
84
  </span>
80
- <kbd className="bg-muted pointer-events-none absolute top-1.5 right-1.5 hidden h-6 items-center gap-1 rounded border px-1.5 font-mono text-[10px] font-medium opacity-100 select-none sm:flex">
85
+ <kbd
86
+ className={cn(
87
+ 'bg-muted pointer-events-none absolute top-1.5 right-1.5 hidden h-6 items-center gap-1 rounded border px-1.5 font-mono text-[10px] font-medium opacity-100 select-none',
88
+ variant === 'default' && 'sm:flex',
89
+ variant === 'compact' && responsive && '2xl:flex',
90
+ )}
91
+ >
81
92
  <span className="text-xs">⌘</span>K
82
93
  </kbd>
83
94
  </Button>
package/src/select.tsx CHANGED
@@ -42,7 +42,7 @@ const SelectTrigger = React.forwardRef<
42
42
  </SelectPrimitive.Icon>
43
43
  </SelectPrimitive.Trigger>
44
44
  ));
45
- SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
45
+ SelectTrigger.displayName = SelectPrimitive.Trigger?.displayName || 'SelectTrigger';
46
46
 
47
47
  const SelectScrollUpButton = React.forwardRef<
48
48
  React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
@@ -56,7 +56,7 @@ const SelectScrollUpButton = React.forwardRef<
56
56
  <ChevronUp className="h-4 w-4" />
57
57
  </SelectPrimitive.ScrollUpButton>
58
58
  ));
59
- SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
59
+ SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton?.displayName || 'SelectScrollUpButton';
60
60
 
61
61
  const SelectScrollDownButton = React.forwardRef<
62
62
  React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
@@ -70,7 +70,7 @@ const SelectScrollDownButton = React.forwardRef<
70
70
  <ChevronDown className="h-4 w-4" />
71
71
  </SelectPrimitive.ScrollDownButton>
72
72
  ));
73
- SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
73
+ SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton?.displayName || 'SelectScrollDownButton';
74
74
 
75
75
  const SelectContent = React.forwardRef<
76
76
  React.ElementRef<typeof SelectPrimitive.Content>,
@@ -102,7 +102,7 @@ const SelectContent = React.forwardRef<
102
102
  </SelectPrimitive.Content>
103
103
  </SelectPrimitive.Portal>
104
104
  ));
105
- SelectContent.displayName = SelectPrimitive.Content.displayName;
105
+ SelectContent.displayName = SelectPrimitive.Content?.displayName || 'SelectContent';
106
106
 
107
107
  const SelectLabel = React.forwardRef<
108
108
  React.ElementRef<typeof SelectPrimitive.Label>,
@@ -110,7 +110,7 @@ const SelectLabel = React.forwardRef<
110
110
  >(({ className, ...props }, ref) => (
111
111
  <SelectPrimitive.Label ref={ref} className={cn('px-2 py-1.5 text-sm font-semibold', className)} {...props} />
112
112
  ));
113
- SelectLabel.displayName = SelectPrimitive.Label.displayName;
113
+ SelectLabel.displayName = SelectPrimitive.Label?.displayName || 'SelectLabel';
114
114
 
115
115
  const SelectItem = React.forwardRef<
116
116
  React.ElementRef<typeof SelectPrimitive.Item>,
@@ -132,7 +132,7 @@ const SelectItem = React.forwardRef<
132
132
  <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
133
133
  </SelectPrimitive.Item>
134
134
  ));
135
- SelectItem.displayName = SelectPrimitive.Item.displayName;
135
+ SelectItem.displayName = SelectPrimitive.Item?.displayName || 'SelectItem';
136
136
 
137
137
  const SelectSeparator = React.forwardRef<
138
138
  React.ElementRef<typeof SelectPrimitive.Separator>,
@@ -140,7 +140,7 @@ const SelectSeparator = React.forwardRef<
140
140
  >(({ className, ...props }, ref) => (
141
141
  <SelectPrimitive.Separator ref={ref} className={cn('bg-muted -mx-1 my-1 h-px', className)} {...props} />
142
142
  ));
143
- SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
143
+ SelectSeparator.displayName = SelectPrimitive.Separator?.displayName || 'SelectSeparator';
144
144
 
145
145
  export {
146
146
  Select,
package/src/separator.tsx CHANGED
@@ -18,7 +18,7 @@ const Separator = React.forwardRef<
18
18
  {...props}
19
19
  />
20
20
  ));
21
- Separator.displayName = SeparatorPrimitive.Root.displayName;
21
+ Separator.displayName = SeparatorPrimitive.Root?.displayName || 'Separator';
22
22
 
23
23
  export { Separator };
24
24
  export type { SeparatorBaseProps as SeparatorProps };
package/src/sheet.tsx CHANGED
@@ -40,7 +40,7 @@ const SheetOverlay = React.forwardRef<
40
40
  ref={ref}
41
41
  />
42
42
  ));
43
- SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
43
+ SheetOverlay.displayName = SheetPrimitive.Overlay?.displayName || 'SheetOverlay';
44
44
 
45
45
  const sheetVariants = cva(
46
46
  'fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out',
@@ -81,7 +81,7 @@ const SheetContent = React.forwardRef<React.ElementRef<typeof SheetPrimitive.Con
81
81
  </SheetPortal>
82
82
  ),
83
83
  );
84
- SheetContent.displayName = SheetPrimitive.Content.displayName;
84
+ SheetContent.displayName = SheetPrimitive.Content?.displayName || 'SheetContent';
85
85
 
86
86
  const SheetHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement> & SheetHeaderBaseProps) => (
87
87
  <div className={cn('flex flex-col space-y-2 text-center sm:text-left', className)} {...props} />
@@ -99,7 +99,7 @@ const SheetTitle = React.forwardRef<
99
99
  >(({ className, ...props }, ref) => (
100
100
  <SheetPrimitive.Title ref={ref} className={cn('text-foreground text-lg font-semibold', className)} {...props} />
101
101
  ));
102
- SheetTitle.displayName = SheetPrimitive.Title.displayName;
102
+ SheetTitle.displayName = SheetPrimitive.Title?.displayName || 'SheetTitle';
103
103
 
104
104
  const SheetDescription = React.forwardRef<
105
105
  React.ElementRef<typeof SheetPrimitive.Description>,
@@ -107,7 +107,7 @@ const SheetDescription = React.forwardRef<
107
107
  >(({ className, ...props }, ref) => (
108
108
  <SheetPrimitive.Description ref={ref} className={cn('text-muted-foreground text-sm', className)} {...props} />
109
109
  ));
110
- SheetDescription.displayName = SheetPrimitive.Description.displayName;
110
+ SheetDescription.displayName = SheetPrimitive.Description?.displayName || 'SheetDescription';
111
111
 
112
112
  export {
113
113
  Sheet,
package/src/slider.tsx CHANGED
@@ -21,7 +21,7 @@ const Slider = React.forwardRef<
21
21
  <SliderPrimitive.Thumb className="border-primary/50 bg-background focus-visible:ring-ring block h-4 w-4 rounded-full border shadow transition-colors focus-visible:ring-1 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50" />
22
22
  </SliderPrimitive.Root>
23
23
  ));
24
- Slider.displayName = SliderPrimitive.Root.displayName;
24
+ Slider.displayName = SliderPrimitive.Root?.displayName || 'Slider';
25
25
 
26
26
  export { Slider };
27
27
  export type { SliderBaseProps as SliderProps };
package/src/switch.tsx CHANGED
@@ -25,7 +25,7 @@ const Switch = React.forwardRef<
25
25
  />
26
26
  </SwitchPrimitives.Root>
27
27
  ));
28
- Switch.displayName = SwitchPrimitives.Root.displayName;
28
+ Switch.displayName = SwitchPrimitives.Root?.displayName || 'Switch';
29
29
 
30
30
  export { Switch };
31
31
  export type { SwitchBaseProps as SwitchProps };
@@ -0,0 +1,285 @@
1
+ 'use client';
2
+
3
+ import {
4
+ HeadingItem,
5
+ TableOfContentsBaseProps,
6
+ TableOfContentsContentBaseProps,
7
+ TableOfContentsListBaseProps,
8
+ TableOfContentsRootBaseProps,
9
+ } from '@gv-tech/ui-core';
10
+ import * as React from 'react';
11
+ import { cn, slugify } from './lib/utils';
12
+
13
+ // Context for sharing heading data
14
+ interface TOCContextValue {
15
+ headings: HeadingItem[];
16
+ activeId: string | null;
17
+ activeHeadingText: string | null;
18
+ registerHeadings: (headings: HeadingItem[]) => void;
19
+ setActiveId: (id: string | null) => void;
20
+ config: TableOfContentsBaseProps;
21
+ }
22
+
23
+ const TOCContext = React.createContext<TOCContextValue | null>(null);
24
+
25
+ function useTOC() {
26
+ const context = React.useContext(TOCContext);
27
+ if (!context) {
28
+ throw new Error('TOC components must be used within a TableOfContents provider');
29
+ }
30
+ return context;
31
+ }
32
+
33
+ export type TableOfContentsProps = TableOfContentsRootBaseProps;
34
+
35
+ /**
36
+ * Root component that provides the Table of Contents context.
37
+ * Can be used as a wrapper OR standalone.
38
+ * If used as a wrapper: <TableOfContents><List /><Content>{children}</Content></TableOfContents>
39
+ * If used standalone: <TableOfContents /> (requires container ref or defaults to document)
40
+ */
41
+ function TableOfContents({
42
+ children,
43
+ className,
44
+ activeId: activeIdOverride,
45
+ minLevel = 1,
46
+ maxLevel = 4,
47
+ selector = 'h1, h2, h3, h4, h5, h6',
48
+ }: TableOfContentsProps) {
49
+ const [headings, setHeadings] = React.useState<HeadingItem[]>([]);
50
+ const [activeId, setActiveId] = React.useState<string | null>(null);
51
+
52
+ const activeHeadingText = React.useMemo(() => {
53
+ return headings.find((h) => h.id === activeId)?.text || null;
54
+ }, [headings, activeId]);
55
+
56
+ const registerHeadings = React.useCallback((newHeadings: HeadingItem[]) => {
57
+ setHeadings((prev) => {
58
+ if (JSON.stringify(prev) === JSON.stringify(newHeadings)) {
59
+ return prev;
60
+ }
61
+ return newHeadings;
62
+ });
63
+ }, []);
64
+
65
+ const value = React.useMemo(
66
+ () => ({
67
+ headings,
68
+ activeId: activeIdOverride || activeId,
69
+ activeHeadingText,
70
+ registerHeadings,
71
+ setActiveId,
72
+ config: { minLevel, maxLevel, selector, className },
73
+ }),
74
+ [
75
+ headings,
76
+ activeId,
77
+ activeIdOverride,
78
+ activeHeadingText,
79
+ registerHeadings,
80
+ minLevel,
81
+ maxLevel,
82
+ selector,
83
+ className,
84
+ ],
85
+ );
86
+
87
+ return (
88
+ <TOCContext.Provider value={value}>
89
+ <div className={cn('relative', className)}>
90
+ {children || (
91
+ <div className="flex flex-col gap-4">
92
+ <TableOfContentsList />
93
+ <TableOfContentsContent>{null}</TableOfContentsContent>
94
+ </div>
95
+ )}
96
+ </div>
97
+ </TOCContext.Provider>
98
+ );
99
+ }
100
+
101
+ /**
102
+ * Renders the actual list of links.
103
+ */
104
+ function TableOfContentsList({ className }: TableOfContentsListBaseProps) {
105
+ const { headings, activeId, activeHeadingText } = useTOC();
106
+ const [isOpen, setIsOpen] = React.useState(false);
107
+
108
+ // Auto-collapse on scroll
109
+ React.useEffect(() => {
110
+ if (!isOpen) {
111
+ return;
112
+ }
113
+
114
+ const handleScroll = () => {
115
+ setIsOpen(false);
116
+ };
117
+
118
+ window.addEventListener('scroll', handleScroll, { passive: true });
119
+ return () => window.removeEventListener('scroll', handleScroll);
120
+ }, [isOpen]);
121
+
122
+ if (headings.length === 0) {
123
+ return null;
124
+ }
125
+
126
+ const currentMinLevel = Math.min(...headings.map((h) => h.level));
127
+
128
+ const listContent = (
129
+ <ul className="m-0 list-none text-sm">
130
+ {headings.map((heading) => {
131
+ const isActive = activeId === heading.id;
132
+ const paddingLeft = `${(heading.level - currentMinLevel) * 1}rem`;
133
+
134
+ return (
135
+ <li key={heading.id} className="mt-0 pt-2">
136
+ <a
137
+ href={`#${heading.id}`}
138
+ onClick={() => setIsOpen(false)}
139
+ className={cn(
140
+ 'hover:text-foreground inline-block no-underline transition-colors',
141
+ isActive ? 'text-primary font-medium' : 'text-muted-foreground',
142
+ )}
143
+ style={{ paddingLeft }}
144
+ >
145
+ {heading.text}
146
+ </a>
147
+ </li>
148
+ );
149
+ })}
150
+ </ul>
151
+ );
152
+
153
+ return (
154
+ <>
155
+ {/* Mobile Sticky Header */}
156
+ <div className={cn('bg-background/95 sticky top-0 z-40 border-b backdrop-blur xl:hidden', className)}>
157
+ <button
158
+ onClick={() => setIsOpen(!isOpen)}
159
+ className="flex w-full items-center justify-between px-4 py-3 text-left"
160
+ >
161
+ <div className="flex items-center gap-2 overflow-hidden">
162
+ <span className="text-muted-foreground text-xs font-semibold tracking-wider uppercase">On this page:</span>
163
+ <span className="truncate text-sm font-medium">{activeHeadingText || 'Overview'}</span>
164
+ </div>
165
+ <svg
166
+ xmlns="http://www.w3.org/2000/svg"
167
+ width="16"
168
+ height="16"
169
+ viewBox="0 0 24 24"
170
+ fill="none"
171
+ stroke="currentColor"
172
+ strokeWidth="2"
173
+ strokeLinecap="round"
174
+ strokeLinejoin="round"
175
+ className={cn('shrink-0 transition-transform duration-200', isOpen && 'rotate-180')}
176
+ >
177
+ <path d="m6 9 6 6 6-6" />
178
+ </svg>
179
+ </button>
180
+
181
+ {isOpen && (
182
+ <div className="bg-background border-t px-4 pt-2 pb-6">
183
+ <nav aria-label="Table of contents mobile">{listContent}</nav>
184
+ </div>
185
+ )}
186
+ </div>
187
+
188
+ {/* Desktop Hidden List */}
189
+ <nav className={cn('hidden xl:block', className)} aria-label="Table of contents">
190
+ {listContent}
191
+ </nav>
192
+ </>
193
+ );
194
+ }
195
+
196
+ /**
197
+ * Wraps the content area and automatically detects headings within it.
198
+ */
199
+ function TableOfContentsContent({ children, className }: TableOfContentsContentBaseProps) {
200
+ const { registerHeadings, setActiveId, config } = useTOC();
201
+ const contentRef = React.useRef<HTMLDivElement>(null);
202
+
203
+ React.useEffect(() => {
204
+ const root = contentRef.current;
205
+ if (!root) {
206
+ return;
207
+ }
208
+
209
+ const queryHeadings = () => {
210
+ const elements = Array.from(root.querySelectorAll(config.selector || 'h1, h2, h3, h4, h5, h6')).filter(
211
+ (element) => {
212
+ const level = parseInt(element.tagName.charAt(1), 10);
213
+ return level >= (config.minLevel ?? 1) && level <= (config.maxLevel ?? 4);
214
+ },
215
+ );
216
+
217
+ const headingItems: HeadingItem[] = elements.map((element) => {
218
+ if (!element.id) {
219
+ element.id = slugify(element.textContent || 'heading');
220
+ }
221
+ return {
222
+ id: element.id,
223
+ text: element.textContent || '',
224
+ level: parseInt(element.tagName.charAt(1), 10),
225
+ };
226
+ });
227
+
228
+ registerHeadings(headingItems);
229
+ return elements;
230
+ };
231
+
232
+ // Initial query
233
+ const elements = queryHeadings();
234
+
235
+ // Intersection Observer for active ID
236
+ const observer = new IntersectionObserver(
237
+ (entries) => {
238
+ entries.forEach((entry) => {
239
+ if (entry.isIntersecting) {
240
+ setActiveId(entry.target.id);
241
+ }
242
+ });
243
+ },
244
+ {
245
+ rootMargin: '0px 0px -80% 0px',
246
+ threshold: 0.1,
247
+ },
248
+ );
249
+
250
+ elements.forEach((el) => observer.observe(el));
251
+
252
+ // Mutation Observer for dynamic content
253
+ const mutationObserver = new MutationObserver(() => {
254
+ const newElements = queryHeadings();
255
+ observer.disconnect();
256
+ newElements.forEach((el) => observer.observe(el));
257
+ });
258
+
259
+ mutationObserver.observe(root, {
260
+ childList: true,
261
+ subtree: true,
262
+ characterData: true,
263
+ });
264
+
265
+ return () => {
266
+ observer.disconnect();
267
+ mutationObserver.disconnect();
268
+ };
269
+ }, [config.selector, config.minLevel, config.maxLevel, registerHeadings, setActiveId]);
270
+
271
+ return (
272
+ <div ref={contentRef} className={className}>
273
+ {children}
274
+ </div>
275
+ );
276
+ }
277
+
278
+ TableOfContents.List = TableOfContentsList;
279
+ TableOfContents.Content = TableOfContentsContent;
280
+
281
+ export type {
282
+ TableOfContentsContentBaseProps as TableOfContentsContentProps,
283
+ TableOfContentsListBaseProps as TableOfContentsListProps,
284
+ } from '@gv-tech/ui-core';
285
+ export { TableOfContents, TableOfContentsContent, TableOfContentsList };
package/src/tabs.tsx CHANGED
@@ -21,7 +21,7 @@ const TabsList = React.forwardRef<
21
21
  {...props}
22
22
  />
23
23
  ));
24
- TabsList.displayName = TabsPrimitive.List.displayName;
24
+ TabsList.displayName = TabsPrimitive.List?.displayName || 'TabsList';
25
25
 
26
26
  const TabsTrigger = React.forwardRef<
27
27
  React.ElementRef<typeof TabsPrimitive.Trigger>,
@@ -36,7 +36,7 @@ const TabsTrigger = React.forwardRef<
36
36
  {...props}
37
37
  />
38
38
  ));
39
- TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
39
+ TabsTrigger.displayName = TabsPrimitive.Trigger?.displayName || 'TabsTrigger';
40
40
 
41
41
  const TabsContent = React.forwardRef<
42
42
  React.ElementRef<typeof TabsPrimitive.Content>,
@@ -51,7 +51,7 @@ const TabsContent = React.forwardRef<
51
51
  {...props}
52
52
  />
53
53
  ));
54
- TabsContent.displayName = TabsPrimitive.Content.displayName;
54
+ TabsContent.displayName = TabsPrimitive.Content?.displayName || 'TabsContent';
55
55
 
56
56
  export { Tabs, TabsContent, TabsList, TabsTrigger };
57
57
  export type {