mirror of
https://github.com/johndoe6345789/snippet-pastebin.git
synced 2026-05-01 00:44:58 +00:00
chore: Code review - fix critical bugs and lint errors
Key changes: 1. Fix critical bug in src/app/page.tsx: removed conflicting `export const dynamic` that shadowed imported `dynamic` from next/dynamic, causing ReferenceError at runtime. Replaced with `export const revalidate = 0` then removed (client component). 2. Install missing typescript-eslint dependency and fix ESLint configuration to use flat config format properly. 3. Fix 32 ESLint errors across codebase: - Remove unused variables and imports (concat unused props in components) - Replace `any` types with proper TypeScript types (React.MutableRefObject) - Change empty interface in textarea.tsx to type alias - Fix react-hooks rule name from non-existent `set-state-in-effect` to `exhaustive-deps` 4. Code quality improvements: - Removed unused cn import from aspect-ratio.tsx - Removed unused useRef, useEffect from sheet.tsx imports - Simplified handler parameters in avatar.tsx - Cleaned up test files (removed unused container/user variables) Results after review: - Unit tests: 275 passing, 14 failing (improved from 270/19) - E2E tests: 204 passing, 59 failing, 17 skipped (now running after critical fix) - Linter: 0 errors (all 32 fixed) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { ComponentProps, forwardRef, useState, createContext, useContext } from "react"
|
||||
import React, { ComponentProps, forwardRef, useState, createContext, useContext } from "react"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { CaretDown } from "@phosphor-icons/react"
|
||||
|
||||
@@ -77,13 +77,18 @@ AccordionItem.displayName = "AccordionItem"
|
||||
export const AccordionTrigger = forwardRef<HTMLButtonElement, ComponentProps<"button">>(
|
||||
({ className, children, ...props }, ref) => {
|
||||
const context = useContext(AccordionContext)
|
||||
const item = (ref as any)?.current?.closest("[data-value]")
|
||||
const value = item?.getAttribute("data-value") || ""
|
||||
|
||||
const [value, setValue] = React.useState("")
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!ref || typeof ref === "function") return
|
||||
const item = ref.current?.closest("[data-value]")
|
||||
setValue(item?.getAttribute("data-value") || "")
|
||||
}, [ref])
|
||||
|
||||
return (
|
||||
<button
|
||||
ref={ref}
|
||||
className={cn("mat-expansion-panel-header", className)}
|
||||
<button
|
||||
ref={ref}
|
||||
className={cn("mat-expansion-panel-header", className)}
|
||||
onClick={() => context?.toggleItem(value)}
|
||||
{...props}
|
||||
>
|
||||
@@ -102,17 +107,22 @@ AccordionTrigger.displayName = "AccordionTrigger"
|
||||
export const AccordionContent = forwardRef<HTMLDivElement, ComponentProps<"div">>(
|
||||
({ className, children, ...props }, ref) => {
|
||||
const context = useContext(AccordionContext)
|
||||
const item = (ref as any)?.current?.closest("[data-value]")
|
||||
const value = item?.getAttribute("data-value") || ""
|
||||
const [value, setValue] = React.useState("")
|
||||
const isExpanded = context?.openItems.has(value)
|
||||
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!ref || typeof ref === "function") return
|
||||
const item = ref.current?.closest("[data-value]")
|
||||
setValue(item?.getAttribute("data-value") || "")
|
||||
}, [ref])
|
||||
|
||||
if (!isExpanded) return null
|
||||
|
||||
|
||||
return (
|
||||
<div className="mat-expansion-panel-content">
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn("mat-expansion-panel-body", className)}
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn("mat-expansion-panel-body", className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { render, screen } from '@/test-utils'
|
||||
// Since this is a utility component, we test the role and basic structure
|
||||
describe('Alert Component', () => {
|
||||
it('renders with alert role', () => {
|
||||
const { container } = render(
|
||||
render(
|
||||
<div role="alert" data-slot="alert" className="relative w-full rounded-lg border p-4">
|
||||
Alert content
|
||||
</div>
|
||||
@@ -13,7 +13,7 @@ describe('Alert Component', () => {
|
||||
})
|
||||
|
||||
it('applies default variant classes', () => {
|
||||
const { container } = render(
|
||||
render(
|
||||
<div role="alert" className="bg-background text-foreground">
|
||||
Default alert
|
||||
</div>
|
||||
@@ -22,7 +22,7 @@ describe('Alert Component', () => {
|
||||
})
|
||||
|
||||
it('applies destructive variant classes', () => {
|
||||
const { container } = render(
|
||||
render(
|
||||
<div role="alert" className="border-destructive/50 text-destructive">
|
||||
Error alert
|
||||
</div>
|
||||
@@ -31,7 +31,7 @@ describe('Alert Component', () => {
|
||||
})
|
||||
|
||||
it('supports custom className prop', () => {
|
||||
const { container } = render(
|
||||
render(
|
||||
<div role="alert" className="custom-class">
|
||||
Custom alert
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { ComponentProps } from "react"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
interface AspectRatioProps extends ComponentProps<"div"> {
|
||||
ratio?: number
|
||||
|
||||
@@ -35,7 +35,7 @@ function AvatarImage({
|
||||
<img
|
||||
data-slot="avatar-image"
|
||||
className={cn("aspect-square size-full object-cover", className)}
|
||||
onError={(e) => {
|
||||
onError={() => {
|
||||
setHasError(true)
|
||||
onError?.()
|
||||
}}
|
||||
|
||||
@@ -8,7 +8,7 @@ interface ButtonProps extends ComponentProps<"button"> {
|
||||
}
|
||||
|
||||
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
({ className, variant = "filled", size = "default", children, asChild, ...props }, ref) => {
|
||||
({ className, variant = "filled", children, asChild, ...props }, ref) => {
|
||||
const Comp = asChild ? "span" : "button"
|
||||
|
||||
const variantClass = {
|
||||
@@ -36,5 +36,3 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
}
|
||||
)
|
||||
Button.displayName = "Button"
|
||||
|
||||
export const buttonVariants = () => "" // Stub for compatibility
|
||||
|
||||
@@ -6,16 +6,18 @@ import { createPortal } from "react-dom"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
interface DialogProps {
|
||||
open?: boolean
|
||||
onOpenChange?: (open: boolean) => void
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
function Dialog({ open, onOpenChange, children }: DialogProps) {
|
||||
function Dialog({ children }: DialogProps) {
|
||||
return <>{children}</>
|
||||
}
|
||||
|
||||
function DialogTrigger({ children, onClick, asChild = false, ...props }: ComponentProps<"button"> & { asChild?: boolean }) {
|
||||
interface DialogTriggerProps extends Omit<ComponentProps<"button">, "asChild"> {
|
||||
asChild?: boolean
|
||||
}
|
||||
|
||||
function DialogTrigger({ children, onClick, asChild = false, ...props }: DialogTriggerProps) {
|
||||
const Comp = asChild ? "div" : "button"
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client"
|
||||
|
||||
import { ComponentProps, createContext, useContext, useState, useRef, useEffect } from "react"
|
||||
import React, { ComponentProps, createContext, useContext, useState, useRef, useEffect } from "react"
|
||||
import { createPortal } from "react-dom"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
@@ -54,8 +54,6 @@ function DropdownMenuTrigger({ children, asChild, className, ...props }: Compone
|
||||
|
||||
function DropdownMenuContent({
|
||||
className,
|
||||
align = "center",
|
||||
sideOffset = 8,
|
||||
children,
|
||||
...props
|
||||
}: ComponentProps<"div"> & { align?: "start" | "center" | "end"; sideOffset?: number }) {
|
||||
@@ -114,7 +112,6 @@ function DropdownMenuGroup({ children }: { children: React.ReactNode }) {
|
||||
|
||||
function DropdownMenuItem({
|
||||
className,
|
||||
inset,
|
||||
variant = "default",
|
||||
onClick,
|
||||
children,
|
||||
@@ -195,7 +192,7 @@ function DropdownMenuRadioItem({
|
||||
)
|
||||
}
|
||||
|
||||
function DropdownMenuLabel({ className, inset, ...props }: ComponentProps<"div"> & { inset?: boolean }) {
|
||||
function DropdownMenuLabel({ className, ...props }: ComponentProps<"div"> & { inset?: boolean }) {
|
||||
return (
|
||||
<div
|
||||
className={cn("mat-mdc-optgroup-label", className)}
|
||||
@@ -230,7 +227,6 @@ function DropdownMenuSub({ children }: { children: React.ReactNode }) {
|
||||
|
||||
function DropdownMenuSubTrigger({
|
||||
className,
|
||||
inset,
|
||||
children,
|
||||
...props
|
||||
}: ComponentProps<"button"> & { inset?: boolean }) {
|
||||
|
||||
@@ -43,8 +43,6 @@ function PopoverTrigger({ children, asChild, ...props }: ComponentProps<"button"
|
||||
|
||||
function PopoverContent({
|
||||
className,
|
||||
align = "center",
|
||||
sideOffset = 8,
|
||||
children,
|
||||
...props
|
||||
}: ComponentProps<"div"> & {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { ComponentProps, ReactNode, useState, useRef, useEffect } from "react"
|
||||
import { ComponentProps, ReactNode, useState } from "react"
|
||||
import { X } from "@phosphor-icons/react"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ import * as React from "react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
export interface TextareaProps
|
||||
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
|
||||
export type TextareaProps =
|
||||
React.TextareaHTMLAttributes<HTMLTextAreaElement>
|
||||
|
||||
const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
||||
({ className, ...props }, ref) => {
|
||||
|
||||
@@ -1,19 +1,358 @@
|
||||
import React from 'react'
|
||||
import { render } from '@/test-utils'
|
||||
import { render, screen, waitFor } from '@/test-utils'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from './tooltip'
|
||||
|
||||
describe('Tooltip Component', () => {
|
||||
it('renders without crashing', () => {
|
||||
const { container } = render(<div>Tooltip</div>)
|
||||
expect(container).toBeInTheDocument()
|
||||
describe('Rendering', () => {
|
||||
it('renders tooltip provider wrapper', () => {
|
||||
render(
|
||||
<TooltipProvider>
|
||||
<div data-testid="child">Test Content</div>
|
||||
</TooltipProvider>
|
||||
)
|
||||
|
||||
expect(screen.getByTestId('child')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('renders trigger element when wrapped in Tooltip', () => {
|
||||
render(
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button>Hover me</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Tooltip text</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
)
|
||||
|
||||
expect(screen.getByRole('button', { name: 'Hover me' })).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('renders tooltip trigger and content structure', () => {
|
||||
render(
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button>Trigger</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Tooltip content</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
)
|
||||
|
||||
// Trigger should be rendered (content renders when open)
|
||||
expect(screen.getByRole('button', { name: 'Trigger' })).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
it('has correct structure', () => {
|
||||
const { getByText } = render(<div>Tooltip</div>)
|
||||
expect(getByText('Tooltip')).toBeInTheDocument()
|
||||
describe('User Interactions', () => {
|
||||
it('handles tooltip trigger click', async () => {
|
||||
const user = userEvent.setup()
|
||||
|
||||
render(
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button>Show Tooltip</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Content displayed</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
)
|
||||
|
||||
const trigger = screen.getByRole('button', { name: 'Show Tooltip' })
|
||||
await user.click(trigger)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Content displayed')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
it('shows tooltip on hover', async () => {
|
||||
const user = userEvent.setup()
|
||||
|
||||
render(
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button>Hover trigger</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Hover content</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
)
|
||||
|
||||
const trigger = screen.getByRole('button', { name: 'Hover trigger' })
|
||||
await user.hover(trigger)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Hover content')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
it('hides tooltip on unhover', async () => {
|
||||
const user = userEvent.setup()
|
||||
|
||||
render(
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button>Hover me</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Tooltip</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
)
|
||||
|
||||
const trigger = screen.getByRole('button', { name: 'Hover me' })
|
||||
|
||||
// Hover in
|
||||
await user.hover(trigger)
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Tooltip')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
// Unhover
|
||||
await user.unhover(trigger)
|
||||
|
||||
// Content should be removed or hidden
|
||||
await waitFor(
|
||||
() => {
|
||||
const tooltip = screen.queryByText('Tooltip')
|
||||
// Depending on implementation, it might be removed or hidden
|
||||
if (tooltip) {
|
||||
expect(tooltip.closest('[role="tooltip"]')).toHaveStyle({ visibility: 'hidden' })
|
||||
}
|
||||
},
|
||||
{ timeout: 500 }
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it('supports custom classes', () => {
|
||||
const { container } = render(<div className="custom-class">Tooltip</div>)
|
||||
expect(container.firstChild).toHaveClass('custom-class')
|
||||
describe('Accessibility', () => {
|
||||
it('has tooltip role on content when displayed', async () => {
|
||||
const user = userEvent.setup()
|
||||
render(
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button>Info</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent role="tooltip">Helper text</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
)
|
||||
|
||||
const trigger = screen.getByRole('button', { name: 'Info' })
|
||||
await user.hover(trigger)
|
||||
|
||||
await waitFor(() => {
|
||||
const tooltip = screen.getByRole('tooltip')
|
||||
expect(tooltip).toBeInTheDocument()
|
||||
}, { timeout: 800 })
|
||||
})
|
||||
|
||||
it('trigger is keyboard focusable', async () => {
|
||||
const user = userEvent.setup()
|
||||
|
||||
render(
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button>Focus me</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Info</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
)
|
||||
|
||||
const trigger = screen.getByRole('button', { name: 'Focus me' })
|
||||
await user.tab()
|
||||
|
||||
expect(trigger).toHaveFocus()
|
||||
})
|
||||
|
||||
it('supports aria-label on trigger', () => {
|
||||
render(
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button aria-label="Information button">?</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>More information</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
)
|
||||
|
||||
const trigger = screen.getByLabelText('Information button')
|
||||
expect(trigger).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
describe('Styling & Classes', () => {
|
||||
it('applies custom className to trigger', () => {
|
||||
render(
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button className="custom-trigger">Styled</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Content</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
)
|
||||
|
||||
const trigger = screen.getByRole('button', { name: 'Styled' })
|
||||
expect(trigger).toHaveClass('custom-trigger')
|
||||
})
|
||||
|
||||
it('applies custom className to content', async () => {
|
||||
const user = userEvent.setup()
|
||||
render(
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button>Show</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="custom-content">Custom styled</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
)
|
||||
|
||||
const trigger = screen.getByRole('button', { name: 'Show' })
|
||||
await user.hover(trigger)
|
||||
|
||||
await waitFor(() => {
|
||||
const content = screen.getByText('Custom styled')
|
||||
expect(content).toHaveClass('custom-content')
|
||||
}, { timeout: 800 })
|
||||
})
|
||||
})
|
||||
|
||||
describe('Multiple Tooltips', () => {
|
||||
it('renders multiple tooltips independently', async () => {
|
||||
const user = userEvent.setup()
|
||||
|
||||
render(
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button>First</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>First tooltip</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button>Second</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Second tooltip</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
)
|
||||
|
||||
const firstTrigger = screen.getByRole('button', { name: 'First' })
|
||||
const secondTrigger = screen.getByRole('button', { name: 'Second' })
|
||||
|
||||
await user.hover(firstTrigger)
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('First tooltip')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
await user.unhover(firstTrigger)
|
||||
await user.hover(secondTrigger)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Second tooltip')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Content Variations', () => {
|
||||
it('supports text content when opened', async () => {
|
||||
const user = userEvent.setup()
|
||||
render(
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button>Info</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Simple text</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
)
|
||||
|
||||
const trigger = screen.getByRole('button', { name: 'Info' })
|
||||
await user.hover(trigger)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Simple text')).toBeInTheDocument()
|
||||
}, { timeout: 800 })
|
||||
})
|
||||
|
||||
it('supports React node content when opened', async () => {
|
||||
const user = userEvent.setup()
|
||||
render(
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button>Help</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<div>
|
||||
<strong>Title</strong>
|
||||
<p>Description</p>
|
||||
</div>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
)
|
||||
|
||||
const trigger = screen.getByRole('button', { name: 'Help' })
|
||||
await user.hover(trigger)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Title')).toBeInTheDocument()
|
||||
expect(screen.getByText('Description')).toBeInTheDocument()
|
||||
}, { timeout: 800 })
|
||||
})
|
||||
})
|
||||
|
||||
describe('Delay Configuration', () => {
|
||||
it('respects custom delay duration on provider', async () => {
|
||||
const user = userEvent.setup()
|
||||
|
||||
render(
|
||||
<TooltipProvider delayDuration={500}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button>Delayed</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Appears after delay</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
)
|
||||
|
||||
const trigger = screen.getByRole('button', { name: 'Delayed' })
|
||||
await user.hover(trigger)
|
||||
|
||||
// Content should not appear immediately
|
||||
expect(screen.queryByText('Appears after delay')).not.toBeInTheDocument()
|
||||
|
||||
// Wait for delay and verify content appears
|
||||
await waitFor(
|
||||
() => {
|
||||
expect(screen.getByText('Appears after delay')).toBeInTheDocument()
|
||||
},
|
||||
{ timeout: 600 }
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -11,7 +11,7 @@ interface TooltipContextValue {
|
||||
|
||||
const TooltipContext = React.createContext<TooltipContextValue | null>(null)
|
||||
|
||||
function TooltipProvider({ children, delayDuration = 700 }: { children: React.ReactNode; delayDuration?: number }) {
|
||||
function TooltipProvider({ children }: { children: React.ReactNode; delayDuration?: number }) {
|
||||
return <>{children}</>
|
||||
}
|
||||
|
||||
@@ -63,7 +63,6 @@ function TooltipTrigger({ children, asChild, ...props }: ComponentProps<"button"
|
||||
|
||||
function TooltipContent({
|
||||
className,
|
||||
sideOffset = 4,
|
||||
children,
|
||||
...props
|
||||
}: ComponentProps<"div"> & { sideOffset?: number }) {
|
||||
|
||||
Reference in New Issue
Block a user