@inferencesh/ui 0.0.0-stage → 0.1.1

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 (165) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +68 -2
  3. package/components.json +22 -0
  4. package/package.json +231 -4
  5. package/src/components/audio-player.tsx +549 -0
  6. package/src/components/button.tsx +13 -0
  7. package/src/components/chart.tsx +403 -0
  8. package/src/components/circuit.tsx +276 -0
  9. package/src/components/code-block/code-block.tsx +260 -0
  10. package/src/components/code-block/index.ts +18 -0
  11. package/src/components/code-block/languages.ts +311 -0
  12. package/src/components/code-block/styles.ts +39 -0
  13. package/src/components/code-block/tokenizer.ts +290 -0
  14. package/src/components/code-block/types.ts +38 -0
  15. package/src/components/code-block/utils.ts +39 -0
  16. package/src/components/code.tsx +48 -0
  17. package/src/components/cookie-consent.tsx +137 -0
  18. package/src/components/copy-button.tsx +44 -0
  19. package/src/components/country-dropdown.tsx +188 -0
  20. package/src/components/glow-loader-fast.tsx +32 -0
  21. package/src/components/glow-loader-mono.tsx +33 -0
  22. package/src/components/glow-loader-sm-fast.tsx +32 -0
  23. package/src/components/glow-loader-sm-mono.tsx +34 -0
  24. package/src/components/glow-loader-sm.tsx +32 -0
  25. package/src/components/glow-loader.tsx +32 -0
  26. package/src/components/glow-logo.tsx +32 -0
  27. package/src/components/gradient.tsx +80 -0
  28. package/src/components/index.ts +45 -0
  29. package/src/components/inline-sidebar.tsx +351 -0
  30. package/src/components/input-color.tsx +349 -0
  31. package/src/components/logo-base.tsx +213 -0
  32. package/src/components/logo-color.tsx +23 -0
  33. package/src/components/logo-full.tsx +71 -0
  34. package/src/components/logo-svg.tsx +23 -0
  35. package/src/components/menu-navigation.tsx +359 -0
  36. package/src/components/multi-select.tsx +721 -0
  37. package/src/components/pastel-gradient.tsx +25 -0
  38. package/src/components/pixel-symmetry.tsx +151 -0
  39. package/src/components/progress.tsx +28 -0
  40. package/src/components/scroll-more.tsx +131 -0
  41. package/src/components/select.tsx +85 -0
  42. package/src/components/shimmering-text.tsx +108 -0
  43. package/src/components/sidebar-light.tsx +102 -0
  44. package/src/components/sonner.tsx +38 -0
  45. package/src/components/theme-switcher-sidebar.tsx +56 -0
  46. package/src/components/theme-switcher-simple.tsx +110 -0
  47. package/src/components/theme-switcher.tsx +47 -0
  48. package/src/components/toggle-group.tsx +55 -0
  49. package/src/components/tooltip-button.tsx +91 -0
  50. package/src/components/tooltip.tsx +71 -0
  51. package/src/components/tree-view.tsx +499 -0
  52. package/src/components/unglow-loader.tsx +33 -0
  53. package/src/components/waveform.tsx +1632 -0
  54. package/src/components/zoomable-image.tsx +76 -0
  55. package/src/docs/api-docs.tsx +763 -0
  56. package/src/docs/callout.tsx +160 -0
  57. package/src/docs/code-group.tsx +215 -0
  58. package/src/docs/copy-menu.tsx +143 -0
  59. package/src/docs/doc-tabs.tsx +84 -0
  60. package/src/docs/index.ts +16 -0
  61. package/src/docs/steps.tsx +105 -0
  62. package/src/docs/table-of-contents.tsx +174 -0
  63. package/src/examples/guide-markdown.ts +129 -0
  64. package/src/examples/index.ts +1153 -0
  65. package/src/global.d.ts +1 -0
  66. package/src/hooks/use-copy-to-clipboard.ts +36 -0
  67. package/src/hooks/use-mobile.ts +19 -0
  68. package/src/lib/display-name.ts +15 -0
  69. package/src/lib/example-input.ts +130 -0
  70. package/src/lib/plans.ts +44 -0
  71. package/src/lib/safe-content.ts +137 -0
  72. package/src/lib/schema.ts +320 -0
  73. package/src/lib/storage.ts +108 -0
  74. package/src/markdown/docs-markdown-renderer.tsx +518 -0
  75. package/src/markdown/helpers.ts +95 -0
  76. package/src/markdown/index.ts +24 -0
  77. package/src/markdown/markdown-renderer.tsx +232 -0
  78. package/src/markdown/youtube-embed.tsx +43 -0
  79. package/src/og/image.ts +312 -0
  80. package/src/og/index.tsx +430 -0
  81. package/src/og/query.ts +26 -0
  82. package/src/shadcn/accordion.tsx +71 -0
  83. package/src/shadcn/alert-dialog.tsx +187 -0
  84. package/src/shadcn/alert.tsx +75 -0
  85. package/src/shadcn/aspect-ratio.tsx +22 -0
  86. package/src/shadcn/attachment.tsx +207 -0
  87. package/src/shadcn/avatar.tsx +106 -0
  88. package/src/shadcn/badge.tsx +51 -0
  89. package/src/shadcn/breadcrumb.tsx +124 -0
  90. package/src/shadcn/bubble.tsx +127 -0
  91. package/src/shadcn/button-group.tsx +87 -0
  92. package/src/shadcn/button.tsx +57 -0
  93. package/src/shadcn/calendar.tsx +219 -0
  94. package/src/shadcn/card.tsx +102 -0
  95. package/src/shadcn/carousel.tsx +242 -0
  96. package/src/shadcn/chart.tsx +372 -0
  97. package/src/shadcn/checkbox.tsx +28 -0
  98. package/src/shadcn/collapsible.tsx +19 -0
  99. package/src/shadcn/combobox.tsx +297 -0
  100. package/src/shadcn/command.tsx +194 -0
  101. package/src/shadcn/context-menu.tsx +270 -0
  102. package/src/shadcn/dialog.tsx +158 -0
  103. package/src/shadcn/direction.tsx +4 -0
  104. package/src/shadcn/drawer.tsx +227 -0
  105. package/src/shadcn/dropdown-menu.tsx +265 -0
  106. package/src/shadcn/empty.tsx +103 -0
  107. package/src/shadcn/field.tsx +238 -0
  108. package/src/shadcn/form.tsx +173 -0
  109. package/src/shadcn/hover-card.tsx +50 -0
  110. package/src/shadcn/index.ts +53 -0
  111. package/src/shadcn/input-group.tsx +156 -0
  112. package/src/shadcn/input-otp.tsx +84 -0
  113. package/src/shadcn/input.tsx +19 -0
  114. package/src/shadcn/item.tsx +201 -0
  115. package/src/shadcn/kbd.tsx +26 -0
  116. package/src/shadcn/label.tsx +19 -0
  117. package/src/shadcn/marker.tsx +70 -0
  118. package/src/shadcn/menubar.tsx +278 -0
  119. package/src/shadcn/message-scroller.tsx +131 -0
  120. package/src/shadcn/message.tsx +91 -0
  121. package/src/shadcn/native-select.tsx +60 -0
  122. package/src/shadcn/navigation-menu.tsx +167 -0
  123. package/src/shadcn/pagination.tsx +130 -0
  124. package/src/shadcn/popover.tsx +87 -0
  125. package/src/shadcn/progress.tsx +82 -0
  126. package/src/shadcn/radio-group.tsx +35 -0
  127. package/src/shadcn/resizable.tsx +49 -0
  128. package/src/shadcn/scroll-area.tsx +52 -0
  129. package/src/shadcn/select.tsx +200 -0
  130. package/src/shadcn/separator.tsx +22 -0
  131. package/src/shadcn/sheet.tsx +136 -0
  132. package/src/shadcn/sidebar.tsx +721 -0
  133. package/src/shadcn/skeleton.tsx +13 -0
  134. package/src/shadcn/slider.tsx +51 -0
  135. package/src/shadcn/sonner.tsx +49 -0
  136. package/src/shadcn/spinner.tsx +10 -0
  137. package/src/shadcn/switch.tsx +29 -0
  138. package/src/shadcn/table.tsx +115 -0
  139. package/src/shadcn/tabs.tsx +79 -0
  140. package/src/shadcn/textarea.tsx +17 -0
  141. package/src/shadcn/toggle-group.tsx +89 -0
  142. package/src/shadcn/toggle.tsx +44 -0
  143. package/src/shadcn/tooltip.tsx +63 -0
  144. package/src/theme/config.ts +48 -0
  145. package/src/theme/css/base.css +92 -0
  146. package/src/theme/css/bitboy.css +75 -0
  147. package/src/theme/css/dark.css +47 -0
  148. package/src/theme/css/designer.css +122 -0
  149. package/src/theme/css/fonts.css +33 -0
  150. package/src/theme/css/globals.css +14 -0
  151. package/src/theme/css/hackintosh.css +57 -0
  152. package/src/theme/css/llama.css +103 -0
  153. package/src/theme/css/safelist.css +39 -0
  154. package/src/theme/css/shadcn.css +77 -0
  155. package/src/theme/css/theme.css +216 -0
  156. package/src/theme/embed-theme.ts +146 -0
  157. package/src/theme/fonts/FiraCode-VF.woff2 +0 -0
  158. package/src/theme/fonts/Hack-Regular.woff2 +0 -0
  159. package/src/theme/fonts/LICENSE-FiraCode.txt +93 -0
  160. package/src/theme/fonts/LICENSE-Hack.txt +45 -0
  161. package/src/theme/fonts/LICENSE-MonaSans.txt +93 -0
  162. package/src/theme/fonts/Mona-Sans.woff2 +0 -0
  163. package/src/theme/index.ts +15 -0
  164. package/src/utils/cn.ts +3 -0
  165. package/src/utils/index.ts +2 -0
@@ -0,0 +1,56 @@
1
+ "use client"
2
+
3
+ import {
4
+ Popover,
5
+ PopoverContent,
6
+ PopoverTrigger
7
+ } from "../shadcn/popover"
8
+ import {
9
+ SidebarMenu, SidebarMenuButton, SidebarMenuItem
10
+ } from "../shadcn/sidebar"
11
+ import { cn } from "cn"
12
+ import { themeConfig, menuThemeNames } from "../theme"
13
+ import { ChevronRight } from "lucide-react"
14
+ import { useTheme } from "next-themes"
15
+
16
+ export function ThemeSwitcherSidebar() {
17
+ const { theme, setTheme } = useTheme()
18
+
19
+ const config = themeConfig[theme as keyof typeof themeConfig] || themeConfig.system
20
+ const Icon = config.icon
21
+
22
+ return (
23
+ <SidebarMenu>
24
+ <SidebarMenuItem>
25
+ <Popover>
26
+ <PopoverTrigger render={<SidebarMenuButton className="group w-full cursor-pointer focus:!outline-none focus:!ring-0 select-none" tooltip="theme" />}>
27
+ <Icon style={{ width: "24px", height: "24px", strokeWidth: "1.0" }} />
28
+ <span>theme</span>
29
+ <ChevronRight className="ml-auto h-4 w-4 text-muted-foreground/50 transition-transform group-data-popup-open:rotate-90" />
30
+ </PopoverTrigger>
31
+ <PopoverContent
32
+ side="right"
33
+ className="w-48 p-1"
34
+ >
35
+ <div className="grid gap-1">
36
+ {menuThemeNames.map(key => ({ key, ...themeConfig[key] })).map(({ key, icon: ThemeIcon, label, iconClassName }) => (
37
+ <button
38
+ key={key}
39
+ onClick={() => setTheme(key)}
40
+ className={cn(
41
+ "flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none",
42
+ "hover:bg-accent hover:text-accent-foreground cursor-pointer",
43
+ theme === key && "bg-accent text-accent-foreground"
44
+ )}
45
+ >
46
+ <ThemeIcon className={cn("h-4 w-4", iconClassName)} />
47
+ {label}
48
+ </button>
49
+ ))}
50
+ </div>
51
+ </PopoverContent>
52
+ </Popover>
53
+ </SidebarMenuItem>
54
+ </SidebarMenu>
55
+ )
56
+ }
@@ -0,0 +1,110 @@
1
+ "use client"
2
+
3
+ import { Button } from "../shadcn/button"
4
+ import {
5
+ DropdownMenu,
6
+ DropdownMenuContent,
7
+ DropdownMenuRadioGroup,
8
+ DropdownMenuRadioItem,
9
+ DropdownMenuTrigger,
10
+ } from "../shadcn/dropdown-menu"
11
+ import { cn } from "cn"
12
+ import { themeConfig, menuThemeNames } from "../theme"
13
+ import { Laptop, Moon, Sun, SunMoon } from "lucide-react"
14
+ import { useTheme } from "next-themes"
15
+ import { useEffect, useState } from "react"
16
+
17
+ /**
18
+ * ThemeSwitcherSimple - Button-style theme switcher (for footer/standalone use)
19
+ * Does not require SidebarProvider
20
+ */
21
+ export function ThemeSwitcherSimple() {
22
+ const [mounted, setMounted] = useState(false)
23
+ const { theme, setTheme } = useTheme()
24
+
25
+ useEffect(() => {
26
+ setMounted(true)
27
+ }, [])
28
+
29
+ if (!mounted) {
30
+ return null
31
+ }
32
+
33
+ const ICON_SIZE = 16
34
+
35
+ return (
36
+ <DropdownMenu>
37
+ <DropdownMenuTrigger render={<Button variant="ghost" size="sm" aria-label="Toggle theme" />}>
38
+ {theme === "light" ? (
39
+ <Sun key="light" size={ICON_SIZE} className="text-muted-foreground" />
40
+ ) : theme === "dark" ? (
41
+ <Moon key="dark" size={ICON_SIZE} className="text-muted-foreground" />
42
+ ) : (
43
+ <Laptop key="system" size={ICON_SIZE} className="text-muted-foreground" />
44
+ )}
45
+ </DropdownMenuTrigger>
46
+ <DropdownMenuContent className="w-content" align="start">
47
+ <DropdownMenuRadioGroup value={theme} onValueChange={setTheme}>
48
+ <DropdownMenuRadioItem className="flex gap-2" value="light">
49
+ <Sun size={ICON_SIZE} className="text-muted-foreground" /> <span>light</span>
50
+ </DropdownMenuRadioItem>
51
+ <DropdownMenuRadioItem className="flex gap-2" value="dark">
52
+ <Moon size={ICON_SIZE} className="text-muted-foreground" /> <span>dark</span>
53
+ </DropdownMenuRadioItem>
54
+ </DropdownMenuRadioGroup>
55
+ </DropdownMenuContent>
56
+ </DropdownMenu>
57
+ )
58
+ }
59
+
60
+ /**
61
+ * ThemeSwitcherCompact - Compact icon-only theme switcher (for navbar use)
62
+ * Does not require SidebarProvider
63
+ */
64
+ export function ThemeSwitcherCompact() {
65
+ const [mounted, setMounted] = useState(false)
66
+ const { theme, setTheme } = useTheme()
67
+
68
+ useEffect(() => {
69
+ setMounted(true)
70
+ }, [])
71
+
72
+ if (!mounted) {
73
+ return (
74
+ <div
75
+ role="button"
76
+ tabIndex={0}
77
+ aria-label="Toggle theme"
78
+ className="w-8 h-8 flex items-center justify-center p-0 rounded-md transition-colors"
79
+ >
80
+ <div className="w-5 h-5 opacity-0" />
81
+ </div>
82
+ )
83
+ }
84
+
85
+ return (
86
+ <DropdownMenu>
87
+ <DropdownMenuTrigger>
88
+ <div
89
+ role="button"
90
+ tabIndex={0}
91
+ aria-label="Toggle theme"
92
+ className="w-8 h-8 flex items-center justify-center p-0 rounded-md transition-colors hover:bg-accent hover:text-accent-foreground cursor-pointer focus:ring-0 focus:outline-none"
93
+ >
94
+ <SunMoon className="w-5 h-5" />
95
+ </div>
96
+ </DropdownMenuTrigger>
97
+ <DropdownMenuContent className="w-[150px]" align="start">
98
+ <DropdownMenuRadioGroup value={theme} onValueChange={setTheme}>
99
+ {menuThemeNames.map(key => ({ key, ...themeConfig[key] })).map(({ key, icon: Icon, label, iconClassName }) => (
100
+ <DropdownMenuRadioItem key={key} className="flex gap-2" value={key}>
101
+ <Icon className={cn("w-4 h-4", iconClassName)} />
102
+ <span>{label}</span>
103
+ </DropdownMenuRadioItem>
104
+ ))}
105
+ </DropdownMenuRadioGroup>
106
+ </DropdownMenuContent>
107
+ </DropdownMenu>
108
+ )
109
+ }
110
+
@@ -0,0 +1,47 @@
1
+ import {
2
+ DropdownMenu,
3
+ DropdownMenuContent,
4
+ DropdownMenuRadioGroup,
5
+ DropdownMenuRadioItem,
6
+ DropdownMenuTrigger
7
+ } from "../shadcn/dropdown-menu"
8
+ import { SidebarMenuButton } from "../shadcn/sidebar"
9
+ import { cn } from "cn"
10
+ import { themeConfig, menuThemeNames } from "../theme"
11
+ import { MoreHorizontal } from "lucide-react"
12
+ import { useTheme } from "next-themes"
13
+
14
+ interface ThemeSwitcherProps {
15
+ isMobile?: boolean;
16
+ }
17
+
18
+ export function ThemeSwitcher({ isMobile }: ThemeSwitcherProps) {
19
+ const { theme, setTheme } = useTheme()
20
+
21
+ return (
22
+ <DropdownMenu>
23
+ <DropdownMenuTrigger render={<SidebarMenuButton className="data-popup-open:bg-sidebar-accent data-popup-open:text-sidebar-accent-foreground" />}>
24
+ {(() => {
25
+ const config = themeConfig[theme as keyof typeof themeConfig] || themeConfig.system
26
+ const Icon = config.icon
27
+ return <Icon className={cn("w-4 h-4 mr-2", config.iconClassName)} />
28
+ })()}
29
+ theme <MoreHorizontal className="ml-auto" />
30
+ </DropdownMenuTrigger>
31
+ <DropdownMenuContent
32
+ side={isMobile ? "bottom" : "right"}
33
+ align={isMobile ? "end" : "start"}
34
+ className="min-w-56 rounded-lg"
35
+ >
36
+ <DropdownMenuRadioGroup value={theme} onValueChange={setTheme}>
37
+ {menuThemeNames.map(key => ({ key, ...themeConfig[key] })).map(({ key, icon: Icon, label, iconClassName }) => (
38
+ <DropdownMenuRadioItem key={key} className="flex gap-2" value={key}>
39
+ <Icon className={cn("w-4 h-4", iconClassName)} />
40
+ <span>{label}</span>
41
+ </DropdownMenuRadioItem>
42
+ ))}
43
+ </DropdownMenuRadioGroup>
44
+ </DropdownMenuContent>
45
+ </DropdownMenu>
46
+ )
47
+ }
@@ -0,0 +1,55 @@
1
+ import * as React from "react"
2
+
3
+ import { ToggleGroup as ToggleGroupBase } from "../shadcn/toggle-group"
4
+
5
+ export { ToggleGroupItem } from "../shadcn/toggle-group"
6
+
7
+ // The shadcn toggle group with a `type`: "single" takes and gives one value,
8
+ // "multiple" an array, as the call sites here are written. Base UI's group
9
+ // (and so the shadcn one) always holds an array. ui/shadcn/toggle-group.tsx
10
+ // stays as the CLI writes it.
11
+
12
+ type BaseProps = Omit<React.ComponentProps<typeof ToggleGroupBase>, "value" | "defaultValue" | "onValueChange" | "multiple">
13
+
14
+ type ToggleGroupSingleProps<T extends string> = BaseProps & {
15
+ type: "single"
16
+ value?: T
17
+ defaultValue?: T
18
+ onValueChange?: (value: T) => void
19
+ }
20
+
21
+ type ToggleGroupMultipleProps<T extends string> = BaseProps & {
22
+ type?: "multiple"
23
+ value?: T[]
24
+ defaultValue?: T[]
25
+ onValueChange?: (value: T[]) => void
26
+ }
27
+
28
+ export type ToggleGroupProps<T extends string> = ToggleGroupSingleProps<T> | ToggleGroupMultipleProps<T>
29
+
30
+ export function ToggleGroup<T extends string>({ type, value, defaultValue, onValueChange, ...props }: ToggleGroupProps<T>) {
31
+ const single = type === "single"
32
+ const groupValue = single ? (value !== undefined ? [value as T] : undefined) : (value as T[] | undefined)
33
+ const groupDefault = single ? (defaultValue !== undefined ? [defaultValue as T] : undefined) : (defaultValue as T[] | undefined)
34
+ const onGroupChange = (next: unknown[]) => {
35
+ if (!onValueChange) return
36
+ if (single) {
37
+ // Pressing the pressed item leaves the group empty: the single stays.
38
+ const last = next[next.length - 1] as T | undefined
39
+ if (last !== undefined) (onValueChange as (v: T) => void)(last)
40
+ } else {
41
+ ;(onValueChange as (v: T[]) => void)(next as T[])
42
+ }
43
+ }
44
+
45
+ return (
46
+ <ToggleGroupBase
47
+ // Without a type the group is Base UI's: one pressed item, array value.
48
+ multiple={type === "multiple" || undefined}
49
+ value={groupValue}
50
+ defaultValue={groupDefault}
51
+ onValueChange={onGroupChange}
52
+ {...props}
53
+ />
54
+ )
55
+ }
@@ -0,0 +1,91 @@
1
+ import { cn } from "cn"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+ import * as React from "react"
4
+ import {
5
+ Tooltip,
6
+ TooltipContent,
7
+ TooltipProvider,
8
+ TooltipTrigger
9
+ } from "./tooltip"
10
+
11
+ const buttonVariants = cva(
12
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
13
+ {
14
+ variants: {
15
+ variant: {
16
+ default:
17
+ "bg-primary text-primary-foreground shadow hover:bg-primary/90",
18
+ destructive:
19
+ "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
20
+ outline:
21
+ "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
22
+ secondary:
23
+ "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
24
+ ghost: "hover:bg-accent hover:text-accent-foreground",
25
+ link: "text-primary underline-offset-4 hover:underline",
26
+ },
27
+ size: {
28
+ default: "h-9 px-4 py-2",
29
+ sm: "h-8 rounded-md px-3 text-xs",
30
+ lg: "h-10 rounded-md px-8",
31
+ icon: "h-9 w-9",
32
+ },
33
+ },
34
+ defaultVariants: {
35
+ variant: "default",
36
+ size: "default",
37
+ },
38
+ }
39
+ )
40
+
41
+ interface TooltipButtonBaseProps
42
+ extends React.ButtonHTMLAttributes<HTMLButtonElement>,
43
+ VariantProps<typeof buttonVariants> {}
44
+
45
+ export interface TooltipButtonProps extends TooltipButtonBaseProps {
46
+ tooltipText: string
47
+ delay?: number
48
+ icon?: React.ReactNode
49
+ onCopy?: () => void
50
+ render?: React.ReactElement<{ className?: string }>
51
+ }
52
+
53
+ const TooltipButton = React.forwardRef<HTMLButtonElement, TooltipButtonProps>(
54
+ ({
55
+ className,
56
+ variant,
57
+ size,
58
+ tooltipText,
59
+ delay = 300,
60
+ icon,
61
+ onCopy,
62
+ render,
63
+ children,
64
+ ...props
65
+ }, ref) => {
66
+ const triggerElement = render
67
+ ? React.cloneElement(render, {
68
+ className: cn(buttonVariants({ variant, size, className }), "cursor-pointer", render.props.className),
69
+ })
70
+ : <button
71
+ className={cn(buttonVariants({ variant, size, className }), "cursor-pointer")}
72
+ onClick={onCopy}
73
+ ref={ref}
74
+ {...props}
75
+ />
76
+ return (
77
+ <TooltipProvider delay={delay}>
78
+ <Tooltip>
79
+ <TooltipTrigger render={triggerElement}>
80
+ {icon || children}
81
+ </TooltipTrigger>
82
+ <TooltipContent>{tooltipText}</TooltipContent>
83
+ </Tooltip>
84
+ </TooltipProvider>
85
+ )
86
+ }
87
+ )
88
+
89
+ TooltipButton.displayName = "TooltipButton"
90
+
91
+ export { TooltipButton }
@@ -0,0 +1,71 @@
1
+ "use client"
2
+
3
+ import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip"
4
+
5
+ import { cn } from "cn"
6
+
7
+ function TooltipProvider({
8
+ delay = 0,
9
+ ...props
10
+ }: TooltipPrimitive.Provider.Props) {
11
+ return (
12
+ <TooltipPrimitive.Provider
13
+ data-slot="tooltip-provider"
14
+ delay={delay}
15
+ {...props}
16
+ />
17
+ )
18
+ }
19
+
20
+ function Tooltip({ ...props }: TooltipPrimitive.Root.Props) {
21
+ return (
22
+ <TooltipProvider>
23
+ <TooltipPrimitive.Root data-slot="tooltip" {...props} />
24
+ </TooltipProvider>
25
+ )
26
+ }
27
+
28
+ function TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {
29
+ return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />
30
+ }
31
+
32
+ function TooltipContent({
33
+ className,
34
+ sideOffset = 0,
35
+ side = "top",
36
+ align = "center",
37
+ alignOffset = 0,
38
+ children,
39
+ ...props
40
+ }: TooltipPrimitive.Popup.Props &
41
+ Pick<
42
+ TooltipPrimitive.Positioner.Props,
43
+ "align" | "alignOffset" | "side" | "sideOffset"
44
+ >) {
45
+ return (
46
+ <TooltipPrimitive.Portal>
47
+ <TooltipPrimitive.Positioner
48
+ align={align}
49
+ alignOffset={alignOffset}
50
+ side={side}
51
+ sideOffset={sideOffset}
52
+ positionMethod="fixed"
53
+ className="isolate z-50"
54
+ >
55
+ <TooltipPrimitive.Popup
56
+ data-slot="tooltip-content"
57
+ className={cn(
58
+ "bg-background text-foreground border border-border z-50 w-fit rounded-md px-2 py-1.5 text-xs text-balance origin-(--transform-origin) data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 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",
59
+ className
60
+ )}
61
+ {...props}
62
+ >
63
+ {children}
64
+ <TooltipPrimitive.Arrow className="bg-transparent fill-transparent z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" />
65
+ </TooltipPrimitive.Popup>
66
+ </TooltipPrimitive.Positioner>
67
+ </TooltipPrimitive.Portal>
68
+ )
69
+ }
70
+
71
+ export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }