feat(saju-ui-v2): useViewportMode hook (1024px breakpoint) + 3 tests
This commit is contained in:
16
src/pages/saju/_shell/useViewportMode.js
Normal file
16
src/pages/saju/_shell/useViewportMode.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
|
||||||
|
export default function useViewportMode() {
|
||||||
|
const [mode, setMode] = useState(() =>
|
||||||
|
typeof window !== 'undefined' && window.innerWidth >= 1024 ? 'desktop' : 'mobile'
|
||||||
|
);
|
||||||
|
useEffect(() => {
|
||||||
|
const onResize = () => {
|
||||||
|
const next = window.innerWidth >= 1024 ? 'desktop' : 'mobile';
|
||||||
|
setMode((prev) => (prev === next ? prev : next));
|
||||||
|
};
|
||||||
|
window.addEventListener('resize', onResize);
|
||||||
|
return () => window.removeEventListener('resize', onResize);
|
||||||
|
}, []);
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
32
src/pages/saju/_shell/useViewportMode.test.js
Normal file
32
src/pages/saju/_shell/useViewportMode.test.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { renderHook, act } from '@testing-library/react';
|
||||||
|
import { describe, it, expect, beforeEach } from 'vitest';
|
||||||
|
import useViewportMode from './useViewportMode';
|
||||||
|
|
||||||
|
describe('useViewportMode', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
window.innerWidth = 800;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns mobile when width < 1024', () => {
|
||||||
|
window.innerWidth = 1023;
|
||||||
|
const { result } = renderHook(() => useViewportMode());
|
||||||
|
expect(result.current).toBe('mobile');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns desktop when width >= 1024', () => {
|
||||||
|
window.innerWidth = 1024;
|
||||||
|
const { result } = renderHook(() => useViewportMode());
|
||||||
|
expect(result.current).toBe('desktop');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('updates on resize', () => {
|
||||||
|
window.innerWidth = 800;
|
||||||
|
const { result } = renderHook(() => useViewportMode());
|
||||||
|
expect(result.current).toBe('mobile');
|
||||||
|
act(() => {
|
||||||
|
window.innerWidth = 1200;
|
||||||
|
window.dispatchEvent(new Event('resize'));
|
||||||
|
});
|
||||||
|
expect(result.current).toBe('desktop');
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user