-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
28 changed files
with
794 additions
and
360 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { act, renderHook } from "@testing-library/react"; | ||
import { type Mock, afterEach, beforeEach, describe, expect, it, vi } from "vitest"; | ||
import { useMediaQuery } from "./use-media-query"; | ||
|
||
describe("useMediaQuery", () => { | ||
let matchMediaMock: Mock; | ||
|
||
beforeEach(() => { | ||
matchMediaMock = vi.fn(); | ||
window.matchMedia = matchMediaMock; | ||
}); | ||
|
||
afterEach(() => { | ||
vi.restoreAllMocks(); | ||
}); | ||
|
||
function createMatchMedia(matches: boolean) { | ||
return () => ({ | ||
matches, | ||
addEventListener: vi.fn(), | ||
removeEventListener: vi.fn(), | ||
}); | ||
} | ||
|
||
it("should return initial value based on media query", () => { | ||
matchMediaMock.mockImplementation(createMatchMedia(true)); | ||
|
||
const { result } = renderHook(() => useMediaQuery("(min-width: 768px)")); | ||
|
||
expect(result.current).toBe(true); | ||
}); | ||
|
||
it("should update value when media query changes", () => { | ||
const listeners: ((event: MediaQueryListEvent) => void)[] = []; | ||
matchMediaMock.mockImplementation(() => ({ | ||
matches: false, | ||
addEventListener: (_, listener) => listeners.push(listener), | ||
removeEventListener: (_, listener) => { | ||
const index = listeners.indexOf(listener); | ||
if (index > -1) { | ||
listeners.splice(index, 1); | ||
} | ||
}, | ||
})); | ||
|
||
const { result } = renderHook(() => useMediaQuery("(min-width: 768px)")); | ||
|
||
expect(result.current).toBe(false); | ||
act(() => { | ||
for (const listener of listeners) { | ||
listener({ matches: true } as MediaQueryListEvent); | ||
} | ||
}); | ||
|
||
expect(result.current).toBe(true); | ||
}); | ||
|
||
it("should remove event listener on unmount", () => { | ||
const removeEventListenerMock = vi.fn(); | ||
matchMediaMock.mockImplementation(() => ({ | ||
matches: true, | ||
addEventListener: vi.fn(), | ||
removeEventListener: removeEventListenerMock, | ||
})); | ||
|
||
const { unmount } = renderHook(() => useMediaQuery("(min-width: 768px)")); | ||
|
||
unmount(); | ||
|
||
expect(removeEventListenerMock).toHaveBeenCalledWith("change", expect.any(Function)); | ||
}); | ||
|
||
it("should update when query changes", () => { | ||
let currentQuery = "(min-width: 768px)"; | ||
matchMediaMock.mockImplementation(() => ({ | ||
matches: currentQuery === "(min-width: 768px)", | ||
addEventListener: vi.fn(), | ||
removeEventListener: vi.fn(), | ||
})); | ||
|
||
const { result, rerender } = renderHook(({ query }) => useMediaQuery(query), { | ||
initialProps: { query: currentQuery }, | ||
}); | ||
|
||
expect(result.current).toBe(true); | ||
|
||
currentQuery = "(max-width: 480px)"; | ||
rerender({ query: currentQuery }); | ||
|
||
expect(result.current).toBe(false); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
"use client"; | ||
|
||
import { useEffect, useState } from "react"; | ||
|
||
export function useMediaQuery(query: string) { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
"use client"; | ||
|
||
import { useEffect, useState } from "react"; | ||
|
||
export function useMounted() { | ||
|
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,32 @@ | ||
/* c8 ignore start */ | ||
import { Alert, AlertDescription, AlertTitle } from "alert"; | ||
import { RocketIcon } from "lucide-react"; | ||
import { Alert, AlertDescription, AlertTitle } from "../alert"; | ||
|
||
export const Default = () => ( | ||
<Alert> | ||
<RocketIcon className="size-4" /> | ||
<AlertTitle>Heads up!</AlertTitle> | ||
<AlertDescription>You can add components to your app using the cli.</AlertDescription> | ||
</Alert> | ||
); | ||
export function Default() { | ||
return ( | ||
<Alert> | ||
<RocketIcon className="size-4" /> | ||
<AlertTitle>Heads up!</AlertTitle> | ||
<AlertDescription>You can add components to your app using the cli.</AlertDescription> | ||
</Alert> | ||
); | ||
} | ||
|
||
export const Destructive = () => ( | ||
<Alert variant="destructive"> | ||
<RocketIcon className="size-4" /> | ||
<AlertTitle>Heads up!</AlertTitle> | ||
<AlertDescription>You can add components to your app using the cli.</AlertDescription> | ||
</Alert> | ||
); | ||
export function Destructive() { | ||
return ( | ||
<Alert variant="destructive"> | ||
<RocketIcon className="size-4" /> | ||
<AlertTitle>Error</AlertTitle> | ||
<AlertDescription>Your session has expired. Please log in again.</AlertDescription> | ||
</Alert> | ||
); | ||
} | ||
|
||
export function WithoutIcon() { | ||
return ( | ||
<Alert> | ||
<AlertTitle>Note</AlertTitle> | ||
<AlertDescription>This is a simple alert without an icon.</AlertDescription> | ||
</Alert> | ||
); | ||
} |
Oops, something went wrong.