{"_id":"@budarin/use-media-query","_rev":"4-4caa941f7b31786f188a2f87327cb6d3","name":"@budarin/use-media-query","dist-tags":{"latest":"1.0.3"},"versions":{"1.0.0":{"name":"@budarin/use-media-query","version":"1.0.0","keywords":["react","hook","media","query"],"author":{"name":"Vadim Budarin"},"license":"MIT","_id":"@budarin/use-media-query@1.0.0","maintainers":[{"name":"budarin","email":"budarin-vv@yandex.ru"}],"homepage":"https://github.com/budarin/useMediaQuery#readme","bugs":{"url":"https://github.com/budarin/useMediaQuery/issues"},"dist":{"shasum":"4a8802c975a7b700b5239f53e8d581ff4c94457b","tarball":"https://registry.npmjs.org/@budarin/use-media-query/-/use-media-query-1.0.0.tgz","fileCount":7,"integrity":"sha512-WBoMxNkPIoZFcUq5DJzVhhkd8F0+udbreKqjsg0am8mP/HKfktqCo9Sfl5qVWR4EkRKT5LOUwe4KnHYXfRl0Bw==","signatures":[{"sig":"MEUCIQDgvmfSdymMnmtsWTnMug+khgS+yU2/37ahfsrPuIpPsgIgf6nlfOXr8bVt9KL6KBvXPFYw07Ocj/Me+7RMWlPEiH8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":7324},"main":"dist/index.js","type":"module","_from":"file:budarin-use-media-query-1.0.0.tgz","types":"dist/index.d.ts","scripts":{"build":"tsc","pnpm-install":"pnpm install","publish-package":"pnpm build && pnpm publish --access=public","upgrade-dependencies":"pnpm upgrade -i"},"_npmUser":{"name":"budarin","email":"budarin-vv@yandex.ru"},"_resolved":"C:\\Users\\Vadim\\AppData\\Local\\Temp\\b21268a221424bb80345be6071644e6f\\budarin-use-media-query-1.0.0.tgz","_integrity":"sha512-WBoMxNkPIoZFcUq5DJzVhhkd8F0+udbreKqjsg0am8mP/HKfktqCo9Sfl5qVWR4EkRKT5LOUwe4KnHYXfRl0Bw==","repository":{"url":"git+https://github.com/budarin/useMediaQuery.git","type":"git"},"_npmVersion":"11.6.0","description":"React hook for media queries","directories":{},"_nodeVersion":"24.8.0","_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.0","prettier":"^3.6.2","typescript":"^5.9.3","@types/react":"^19.2.2"},"peerDependencies":{"react":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/use-media-query_1.0.0_1761318650930_0.5336317461835449","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@budarin/use-media-query","version":"1.0.1","keywords":["react","hook","media","query"],"author":{"name":"Vadim Budarin"},"license":"MIT","_id":"@budarin/use-media-query@1.0.1","maintainers":[{"name":"budarin","email":"budarin-vv@yandex.ru"}],"homepage":"https://github.com/budarin/useMediaQuery#readme","bugs":{"url":"https://github.com/budarin/useMediaQuery/issues"},"dist":{"shasum":"31cc55c3ecd755b66ddffc6e5297bc56bb14e9fe","tarball":"https://registry.npmjs.org/@budarin/use-media-query/-/use-media-query-1.0.1.tgz","fileCount":8,"integrity":"sha512-zS0WNBHk+vuRklFGsdaMK5TrCZ/S70eET+CzpZzTlbH0F+1M3gFxaD14ESgULelvBQ1S/F4V+HVcBAd8N0gVXw==","signatures":[{"sig":"MEUCIGiKUn02P9wtZ9wjzR4ZnpAI9CTv+y8pbJYpVj/s4ljpAiEA8PJn690yc77KSOzfHqN27yKRQDf7ZsNPR+3btCLVyxs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":16331},"main":"dist/index.js","type":"module","_from":"file:budarin-use-media-query-1.0.1.tgz","types":"dist/index.d.ts","scripts":{"build":"tsc","pnpm-install":"pnpm install","publish-package":"pnpm build && pnpm publish --access=public","upgrade-dependencies":"pnpm upgrade -i"},"_npmUser":{"name":"budarin","email":"budarin-vv@yandex.ru"},"_resolved":"C:\\Users\\Vadim\\AppData\\Local\\Temp\\cb4ffd69157a5b81a9d787fbb2f3b3cf\\budarin-use-media-query-1.0.1.tgz","_integrity":"sha512-zS0WNBHk+vuRklFGsdaMK5TrCZ/S70eET+CzpZzTlbH0F+1M3gFxaD14ESgULelvBQ1S/F4V+HVcBAd8N0gVXw==","repository":{"url":"git+https://github.com/budarin/useMediaQuery.git","type":"git"},"_npmVersion":"11.6.0","description":"React hook for media queries","directories":{},"_nodeVersion":"24.8.0","_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.0","prettier":"^3.6.2","typescript":"^5.9.3","@types/react":"^19.2.2"},"peerDependencies":{"react":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/use-media-query_1.0.1_1761320026140_0.886167016573709","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@budarin/use-media-query","version":"1.0.2","keywords":["react","hook","media","query"],"author":{"name":"Vadim Budarin"},"license":"MIT","_id":"@budarin/use-media-query@1.0.2","maintainers":[{"name":"budarin","email":"budarin-vv@yandex.ru"}],"homepage":"https://github.com/budarin/useMediaQuery#readme","bugs":{"url":"https://github.com/budarin/useMediaQuery/issues"},"dist":{"shasum":"6cd98ad4558bfd5f14975e94b256f57b3b602a3d","tarball":"https://registry.npmjs.org/@budarin/use-media-query/-/use-media-query-1.0.2.tgz","fileCount":8,"integrity":"sha512-4hIeNpSp5Dn3WGVqvZzfgASWsrJyTyBK3TLFRgTN8hR7pWCRKcPgqKkc2Lj45c9s5WPdIzgXl5DUN9XvPGtSUA==","signatures":[{"sig":"MEQCIH7ph/lpaLKwu4izdFb87j2AMXrTsAJU6lwyMcy3ZXsTAiBd3HvVI8ZYqqYyDiSzt4X79BEebAn0EnXaq7qMEMK9LA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":16412},"main":"dist/index.js","type":"module","_from":"file:budarin-use-media-query-1.0.2.tgz","types":"dist/index.d.ts","scripts":{"build":"tsc","pnpm-install":"pnpm install","publish-package":"pnpm build && pnpm publish --access=public","upgrade-dependencies":"pnpm upgrade -i"},"_npmUser":{"name":"budarin","email":"budarin-vv@yandex.ru"},"_resolved":"C:\\Users\\Vadim\\AppData\\Local\\Temp\\2c7983a236c3526b87a8273459a115d9\\budarin-use-media-query-1.0.2.tgz","_integrity":"sha512-4hIeNpSp5Dn3WGVqvZzfgASWsrJyTyBK3TLFRgTN8hR7pWCRKcPgqKkc2Lj45c9s5WPdIzgXl5DUN9XvPGtSUA==","repository":{"url":"git+https://github.com/budarin/useMediaQuery.git","type":"git"},"_npmVersion":"11.6.0","description":"React hook for media queries","directories":{},"_nodeVersion":"24.8.0","_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.0","prettier":"^3.6.2","typescript":"^5.9.3","@types/react":"^19.2.2"},"peerDependencies":{"react":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/use-media-query_1.0.2_1761320240880_0.6470945190366233","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@budarin/use-media-query","version":"1.0.3","description":"React hook for media queries","main":"dist/index.js","types":"dist/index.d.ts","type":"module","keywords":["react","hook","media","query"],"author":{"name":"Vadim Budarin"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/budarin/useMediaQuery.git"},"bugs":{"url":"https://github.com/budarin/useMediaQuery/issues"},"homepage":"https://github.com/budarin/useMediaQuery#readme","peerDependencies":{"react":">=18.0.0"},"devDependencies":{"@types/react":"^19.2.2","prettier":"^3.6.2","react":"^19.2.0","typescript":"^5.9.3"},"scripts":{"build":"tsc","pnpm-install":"pnpm install","upgrade-dependencies":"pnpm upgrade -i","publish-package":"pnpm build && pnpm publish --access=public"},"_id":"@budarin/use-media-query@1.0.3","_integrity":"sha512-4hkdZ1ImbCUZ+qXVXW007ZKalHUBImbMTyF3a+tZp0Vlkg7tDQFiIK+aC67IlJycatQFMVJmnx+vCu3QiP6nkw==","_resolved":"/private/var/folders/3d/my733tj9449d7jbbq3h3395w0000gn/T/ae28172cd88a7caa4f584a8fd3c80bd4/budarin-use-media-query-1.0.3.tgz","_from":"file:budarin-use-media-query-1.0.3.tgz","_nodeVersion":"24.8.0","_npmVersion":"11.6.0","dist":{"integrity":"sha512-4hkdZ1ImbCUZ+qXVXW007ZKalHUBImbMTyF3a+tZp0Vlkg7tDQFiIK+aC67IlJycatQFMVJmnx+vCu3QiP6nkw==","shasum":"f618be93708a3cf50bfb67069e57fc0f53dc39b2","tarball":"https://registry.npmjs.org/@budarin/use-media-query/-/use-media-query-1.0.3.tgz","fileCount":8,"unpackedSize":16612,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDT23BULCd4GjwFIzc3KJTmDsuQRkj3qs+/IqV7m2BqDwIhANm0uAMUCpN7eORZG56/IO+7QogAwdXUYSpM1U3nzJcx"}]},"_npmUser":{"name":"budarin","email":"budarin-vv@yandex.ru"},"directories":{},"maintainers":[{"name":"budarin","email":"budarin-vv@yandex.ru"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/use-media-query_1.0.3_1762555443898_0.5933047433626157"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-24T15:10:50.786Z","modified":"2025-11-07T22:44:04.320Z","1.0.0":"2025-10-24T15:10:51.120Z","1.0.1":"2025-10-24T15:33:46.346Z","1.0.2":"2025-10-24T15:37:21.045Z","1.0.3":"2025-11-07T22:44:04.111Z"},"bugs":{"url":"https://github.com/budarin/useMediaQuery/issues"},"author":{"name":"Vadim Budarin"},"license":"MIT","homepage":"https://github.com/budarin/useMediaQuery#readme","keywords":["react","hook","media","query"],"repository":{"type":"git","url":"git+https://github.com/budarin/useMediaQuery.git"},"description":"React hook for media queries","maintainers":[{"name":"budarin","email":"budarin-vv@yandex.ru"}],"readme":"# useMediaQuery\n\nСовременный React хук для медиа-запросов, построенный на `useSyncExternalStore` для оптимальной производительности и совместимости с SSR.\n\n> 🇺🇸 [English documentation](README.md)\n\n## Возможности\n\n- ✅ **SSR Безопасный** - Нет рассинхронизации при гидратации\n- ✅ **Оптимизированная производительность** - Построен на `useSyncExternalStore`\n- ✅ **Автоматические обновления** - Автоматически реагирует на изменение размера окна, смену ориентации и все обновления viewport\n- ✅ **Поддержка TypeScript** - Полные определения типов\n- ✅ **Современный React** - Совместим с React 18+\n- ✅ **Нулевые зависимости** - Легковесная реализация\n\n## Установка\n\n```bash\nnpm install @budarin/useMediaQuery\n# или\npnpm add @budarin/useMediaQuery\n# или\nyarn add @budarin/useMediaQuery\n```\n\n## Использование\n\n### Базовый пример\n\n```tsx\nimport { useMediaQuery } from '@budarin/useMediaQuery';\n\nfunction App() {\n    const isMobile = useMediaQuery('(max-width: 768px)');\n    const isDark = useMediaQuery('(prefers-color-scheme: dark)');\n\n    return (\n        <div>\n            <h1>{isMobile ? 'Мобильный вид' : 'Десктопный вид'}</h1>\n            <p>Тема: {isDark ? 'Темная' : 'Светлая'}</p>\n        </div>\n    );\n}\n```\n\n### Продвинутые примеры\n\n```tsx\nimport { useMediaQuery } from '@budarin/useMediaQuery';\n\nfunction ResponsiveComponent() {\n    const isSmall = useMediaQuery('(max-width: 640px)');\n    const isMedium = useMediaQuery(\n        '(min-width: 641px) and (max-width: 1024px)'\n    );\n    const isLarge = useMediaQuery('(min-width: 1025px)');\n    const isLandscape = useMediaQuery('(orientation: landscape)');\n    const prefersReducedMotion = useMediaQuery(\n        '(prefers-reduced-motion: reduce)'\n    );\n\n    return (\n        <div>\n            {isSmall && <MobileLayout />}\n            {isMedium && <TabletLayout />}\n            {isLarge && <DesktopLayout />}\n\n            {isLandscape && <LandscapeWarning />}\n\n            <div\n                style={{\n                    animation: prefersReducedMotion ? 'none' : 'fadeIn 0.3s',\n                }}\n            >\n                Контент\n            </div>\n        </div>\n    );\n}\n```\n\n### Пример с кастомным хуком\n\n```tsx\nimport { useMediaQuery } from '@budarin/useMediaQuery';\n\n// Создаем кастомные хуки для стандартных брейкпоинтов\nexport const useBreakpoints = () => {\n    const isMobile = useMediaQuery('(max-width: 767px)');\n    const isTablet = useMediaQuery(\n        '(min-width: 768px) and (max-width: 1023px)'\n    );\n    const isDesktop = useMediaQuery('(min-width: 1024px)');\n\n    return { isMobile, isTablet, isDesktop };\n};\n\n// Использование\nfunction MyComponent() {\n    const { isMobile, isTablet, isDesktop } = useBreakpoints();\n\n    return (\n        <div>\n            {isMobile && <MobileView />}\n            {isTablet && <TabletView />}\n            {isDesktop && <DesktopView />}\n        </div>\n    );\n}\n```\n\n## API\n\n### `useMediaQuery(query: string): boolean`\n\n**Параметры:**\n\n- `query` (string) - CSS медиа-запрос\n\n**Возвращает:**\n\n- `boolean` - Соответствует ли медиа-запрос\n\n## Почему следует использовать именно этот хук?\n\nЭтот хук построен на React `useSyncExternalStore` вместо традиционного паттерна `useState` + `useEffect` по нескольким причинам:\n\n**Проблемы:**\n\n- Рассинхронизация при гидратации между сервером и клиентом\n- Состояния гонки между `useState` и `useEffect`\n- Устаревшее состояние, если медиа-запрос изменился до монтирования компонента\n- Плохая совместимость с SSR\n- **Проблемы с concurrent рендерингом в React 18+** - Состояние может стать неконсистентным во время прерванных рендеров\n\n### ✅ Преимущества useSyncExternalStore\n\n- **Синхронная синхронизация** - Всегда актуальное состояние\n- **SSR безопасность** - Нет рассинхронизации при гидратации\n- **Нет состояний гонки** - Store всегда синхронизирован\n- **Лучшая производительность** - React оптимизирует подписки\n- **Готовность к будущему** - Построен для React 18+ concurrent функций\n- **Автоматическое отслеживание viewport** - Событие `MediaQueryList.change` автоматически срабатывает при изменении размера окна, смене ориентации и любых обновлениях viewport\n- **Безопасность concurrent рендеринга** - Нет неконсистентности состояния во время прерванных рендеров\n\n### 🚨 Критическая проблема React 18+\n\nС concurrent функциями React 18+ традиционный подход `useState` + `useEffect` может вызвать **неконсистентность состояния**:\n\n```tsx\n// ❌ Проблематично с concurrent рендерингом\nfunction useMediaQuery(query) {\n    const [matches, setMatches] = useState(\n        () => window.matchMedia(query).matches\n    );\n\n    useEffect(() => {\n        const mediaQuery = window.matchMedia(query);\n        const handler = (e) => setMatches(e.matches); // ⚠️ Может быть вызван во время прерванного рендера\n        mediaQuery.addEventListener('change', handler);\n        return () => mediaQuery.removeEventListener('change', handler);\n    }, [query]);\n\n    return matches; // ⚠️ Может вернуть устаревшее состояние во время concurrent обновлений\n}\n```\n\n**Проблема:**\n\n- React может прерывать рендеры в React 18+\n- Изменения медиа-запросов могут происходить во время прерванных рендеров\n- Обновления `useState` могут применяться не в том порядке\n- Компонент может отрендериться с неконсистентным состоянием\n\n**Решение:**\n\n- `useSyncExternalStore` гарантирует, что состояние всегда синхронизировано с внешним источником\n- Нет состояний гонки во время concurrent рендеринга\n- Гарантированная консистентность даже с прерванными рендерами\n\n## TypeScript\n\nПолная поддержка TypeScript включена. Дополнительные определения типов не нужны.\n\n```tsx\nimport { useMediaQuery } from '@budarin/useMediaQuery';\n\n// TypeScript автоматически выводит тип возвращаемого значения\nconst isMobile: boolean = useMediaQuery('(max-width: 768px)');\n```\n\n## Лицензия\n\nMIT\n\n## Автор\n\nVadim Budarin\n","readmeFilename":"README.ru.md"}