From 11af86abd8bbe78e49cf666a01fdaa292be3f14d Mon Sep 17 00:00:00 2001 From: Felipe Barso <77860630+aprendendofelipe@users.noreply.github.com> Date: Mon, 29 Dec 2025 12:54:21 -0300 Subject: [PATCH 1/3] feat(useMediaQuery): add new `useMediaQuery` hook --- packages/hooks/src/index.js | 1 + packages/hooks/src/useMediaQuery/index.js | 1 + .../hooks/src/useMediaQuery/useMediaQuery.js | 17 ++++++ .../src/useMediaQuery/useMediaQuery.test.js | 60 +++++++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 packages/hooks/src/useMediaQuery/index.js create mode 100644 packages/hooks/src/useMediaQuery/useMediaQuery.js create mode 100644 packages/hooks/src/useMediaQuery/useMediaQuery.test.js diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index d281bdbf..eaf95150 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -1,3 +1,4 @@ export * from './useConfig/index.js'; +export * from './useMediaQuery/index.js'; export * from './useMergedState/index.js'; export * from './useTreeCollapse/index.js'; diff --git a/packages/hooks/src/useMediaQuery/index.js b/packages/hooks/src/useMediaQuery/index.js new file mode 100644 index 00000000..549eaca1 --- /dev/null +++ b/packages/hooks/src/useMediaQuery/index.js @@ -0,0 +1 @@ +export * from './useMediaQuery.js'; diff --git a/packages/hooks/src/useMediaQuery/useMediaQuery.js b/packages/hooks/src/useMediaQuery/useMediaQuery.js new file mode 100644 index 00000000..30c4b7a3 --- /dev/null +++ b/packages/hooks/src/useMediaQuery/useMediaQuery.js @@ -0,0 +1,17 @@ +import { useEffect, useState } from 'react'; + +export function useMediaQuery(query) { + const [matches, setMatches] = useState(() => typeof window !== 'undefined' && !!window.matchMedia(query).matches); + + useEffect(() => { + const media = window.matchMedia(query); + const listener = () => setMatches(media.matches); + + listener(); + + media.addEventListener('change', listener); + return () => media.removeEventListener('change', listener); + }, [query]); + + return matches; +} diff --git a/packages/hooks/src/useMediaQuery/useMediaQuery.test.js b/packages/hooks/src/useMediaQuery/useMediaQuery.test.js new file mode 100644 index 00000000..58aa7c3a --- /dev/null +++ b/packages/hooks/src/useMediaQuery/useMediaQuery.test.js @@ -0,0 +1,60 @@ +import { act, renderHook } from '@testing-library/react'; +import { renderToString } from 'react-dom/server'; + +import { useMediaQuery } from './index.js'; + +describe('useMediaQuery', () => { + describe('renderHook', () => { + let matches = false; + const listeners = new Set(); + + beforeAll(() => { + vi.spyOn(window, 'matchMedia').mockImplementation((query) => ({ + get matches() { + return matches; + }, + media: query, + addEventListener: (event, cb) => listeners.add(cb), + removeEventListener: (event, cb) => listeners.delete(cb), + })); + }); + + beforeEach(() => { + matches = false; + listeners.clear(); + }); + + afterAll(() => { + window.matchMedia.mockRestore(); + }); + + it('should return true if the media query matches', () => { + matches = true; + const { result } = renderHook(() => useMediaQuery('(min-width: 600px)')); + expect(result.current).toBe(true); + }); + + it('should return false if the media query does not match', () => { + const { result } = renderHook(() => useMediaQuery('(min-width: 1200px)')); + expect(result.current).toBe(false); + }); + + it('should update when the media query changes', () => { + const { result } = renderHook(() => useMediaQuery('(min-width: 800px)')); + expect(result.current).toBe(false); + + act(() => { + matches = true; + listeners.forEach((cb) => cb()); + }); + expect(result.current).toBe(true); + }); + }); + + describe('SSR', () => { + it('should not throw during SSR and return false', () => { + const TestComponent = () => String(useMediaQuery('(min-width: 600px)')); + expect(renderToString()).toBe('false'); + }); + }); +}); From b3669b8265238ff31c9fbcd97481e83936a8328d Mon Sep 17 00:00:00 2001 From: Felipe Barso <77860630+aprendendofelipe@users.noreply.github.com> Date: Tue, 30 Dec 2025 10:37:05 -0300 Subject: [PATCH 2/3] feat(example): add dynamic favicon based on color scheme via `useMediaQuery` hook --- examples/form/app/layout.jsx | 2 ++ examples/form/components/Head/Head.App.jsx | 10 ++++++++++ examples/form/components/Head/Head.Pages.jsx | 11 +++++++++++ examples/form/components/Head/Tags.jsx | 13 +++++++++++++ examples/form/pages/_app.js | 2 ++ examples/form/public/favicon-dark.png | Bin 0 -> 6616 bytes examples/form/public/favicon-light.png | Bin 0 -> 6388 bytes 7 files changed, 38 insertions(+) create mode 100644 examples/form/components/Head/Head.App.jsx create mode 100644 examples/form/components/Head/Head.Pages.jsx create mode 100644 examples/form/components/Head/Tags.jsx create mode 100644 examples/form/public/favicon-dark.png create mode 100644 examples/form/public/favicon-light.png diff --git a/examples/form/app/layout.jsx b/examples/form/app/layout.jsx index 5a32e7b9..c4c0aaf9 100644 --- a/examples/form/app/layout.jsx +++ b/examples/form/app/layout.jsx @@ -2,11 +2,13 @@ import { PrimerRoot } from '@barso/ui'; import '@barso/ui/css'; import { DefaultLayout } from '../components/DefaultLayout.jsx'; +import { DefaultHead } from '../components/Head/Head.App'; import { NotificationsProvider } from '../components/Notifications'; export default function Layout({ children }) { return ( + {children} diff --git a/examples/form/components/Head/Head.App.jsx b/examples/form/components/Head/Head.App.jsx new file mode 100644 index 00000000..5dcd4ec3 --- /dev/null +++ b/examples/form/components/Head/Head.App.jsx @@ -0,0 +1,10 @@ +/* eslint-disable @next/next/no-head-element */ +import { DefaultTags } from './Tags'; + +export function DefaultHead() { + return ( + + + + ); +} diff --git a/examples/form/components/Head/Head.Pages.jsx b/examples/form/components/Head/Head.Pages.jsx new file mode 100644 index 00000000..a35e4f91 --- /dev/null +++ b/examples/form/components/Head/Head.Pages.jsx @@ -0,0 +1,11 @@ +import NextHead from 'next/head'; + +import { DefaultTags } from './Tags'; + +export function DefaultHead() { + // next/head does not mount child components like a normal React tree. + // Using results in the SSR output being reused on the client, + // so hooks inside the component never run. + // Calling DefaultTags() forces evaluation instead of relying on component mounting. + return {DefaultTags()}; +} diff --git a/examples/form/components/Head/Tags.jsx b/examples/form/components/Head/Tags.jsx new file mode 100644 index 00000000..00426612 --- /dev/null +++ b/examples/form/components/Head/Tags.jsx @@ -0,0 +1,13 @@ +'use client'; +import { useMediaQuery } from '@barso/hooks'; + +export function DefaultTags() { + const isDark = useMediaQuery('(prefers-color-scheme: dark)'); + + return ( + <> + + {/* Add other SEO tags or links here as needed */} + + ); +} diff --git a/examples/form/pages/_app.js b/examples/form/pages/_app.js index 8064d86d..fd799dbb 100644 --- a/examples/form/pages/_app.js +++ b/examples/form/pages/_app.js @@ -1,11 +1,13 @@ import { AutoThemeProvider } from '@barso/ui'; import '@barso/ui/css'; +import { DefaultHead } from '../components/Head/Head.Pages'; import { NotificationsProvider } from '../components/Notifications'; export default function MyApp({ Component, pageProps }) { return ( + diff --git a/examples/form/public/favicon-dark.png b/examples/form/public/favicon-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..58a1efded7ae8ee72320729bba53e417a86c9c6e GIT binary patch literal 6616 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 MyZgA6EDqlMZ{2Kc(f|Me literal 0 HcmV?d00001 diff --git a/examples/form/public/favicon-light.png b/examples/form/public/favicon-light.png new file mode 100644 index 0000000000000000000000000000000000000000..f0501728dd84437f3cc459204eef53bdf64155ae GIT binary patch literal 6388 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 JqjP>)^Dp=+B+38) literal 0 HcmV?d00001 From 7f2e22296487c73ab28e8750520b786b3fa3d97b Mon Sep 17 00:00:00 2001 From: Felipe Barso <77860630+aprendendofelipe@users.noreply.github.com> Date: Tue, 30 Dec 2025 10:38:05 -0300 Subject: [PATCH 3/3] feat(example): add `Head` component for dynamic title and description management --- examples/form/app/layout.jsx | 5 +++++ examples/form/components/Head/Head.Pages.jsx | 9 +++++++++ examples/form/pages/_app.js | 3 ++- examples/form/pages/pages_router.jsx | 2 ++ examples/form/pages/registration.jsx | 2 ++ 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/examples/form/app/layout.jsx b/examples/form/app/layout.jsx index c4c0aaf9..a00d4a5e 100644 --- a/examples/form/app/layout.jsx +++ b/examples/form/app/layout.jsx @@ -5,6 +5,11 @@ import { DefaultLayout } from '../components/DefaultLayout.jsx'; import { DefaultHead } from '../components/Head/Head.App'; import { NotificationsProvider } from '../components/Notifications'; +export const metadata = { + title: 'App Router · Default Title', + description: 'App Router · Default Description', +}; + export default function Layout({ children }) { return ( diff --git a/examples/form/components/Head/Head.Pages.jsx b/examples/form/components/Head/Head.Pages.jsx index a35e4f91..f9ac0b30 100644 --- a/examples/form/components/Head/Head.Pages.jsx +++ b/examples/form/components/Head/Head.Pages.jsx @@ -9,3 +9,12 @@ export function DefaultHead() { // Calling DefaultTags() forces evaluation instead of relying on component mounting. return {DefaultTags()}; } + +export function Head({ title, description }) { + return ( + + {title && {title}} + {description && } + + ); +} diff --git a/examples/form/pages/_app.js b/examples/form/pages/_app.js index fd799dbb..58aad699 100644 --- a/examples/form/pages/_app.js +++ b/examples/form/pages/_app.js @@ -1,13 +1,14 @@ import { AutoThemeProvider } from '@barso/ui'; import '@barso/ui/css'; -import { DefaultHead } from '../components/Head/Head.Pages'; +import { DefaultHead, Head } from '../components/Head/Head.Pages'; import { NotificationsProvider } from '../components/Notifications'; export default function MyApp({ Component, pageProps }) { return ( + diff --git a/examples/form/pages/pages_router.jsx b/examples/form/pages/pages_router.jsx index 299dd22b..87dbde6f 100644 --- a/examples/form/pages/pages_router.jsx +++ b/examples/form/pages/pages_router.jsx @@ -1,10 +1,12 @@ import { Checkout } from '../components/Checkout.jsx'; import { DefaultLayout } from '../components/DefaultLayout.jsx'; +import { Head } from '../components/Head/Head.Pages.jsx'; import { checkoutFields, product, store } from '../form-config.js'; export default function Home() { return ( + ); diff --git a/examples/form/pages/registration.jsx b/examples/form/pages/registration.jsx index 27e950a2..573dbac8 100644 --- a/examples/form/pages/registration.jsx +++ b/examples/form/pages/registration.jsx @@ -1,10 +1,12 @@ import { DefaultLayout } from '../components/DefaultLayout.jsx'; +import { Head } from '../components/Head/Head.Pages.jsx'; import { Registration } from '../components/Registration.jsx'; import { registrationFields, store } from '../form-config.js'; export default function RegistrationPage() { return ( + );