Skip to content

Основные концепции

Формат конфига: MediaQueryConfig

Каждый брейкпоинт описывается через MediaQueryConfig — массив условий, объединённых через AND, либо вложенный массив групп, объединённых через OR.

AND (плоский массив)

ts
// (min-width: 768px) and (max-width: 1023px)
;[
  { type: 'min-width', value: 768 },
  { type: 'max-width', value: 1023 },
]

OR (вложенный массив)

ts
// (max-width: 600px), (orientation: portrait) and (max-width: 1024px)
;[
  [{ type: 'max-width', value: 600 }],
  [
    { type: 'orientation', value: 'portrait' },
    { type: 'max-width', value: 1024 },
  ],
]

Сырой тип медиа

Используйте type: 'raw', чтобы вставить значение как есть — полезно для типов медиа вроде print или screen:

ts
// Совпадает с типом медиа 'print'
;[{ type: 'raw', value: 'print' }][
  // screen and (max-width: 600px)
  ({ type: 'raw', value: 'screen' }, { type: 'max-width', value: 600 })
]

Поддерживаемые типы условий

typeПример значенияСгенерированный запрос
min-width768(min-width: 768px)
max-width1023(max-width: 1023px)
min-height600(min-height: 600px)
max-height900(max-height: 900px)
orientation'portrait'(orientation: portrait)
aspect-ratio'16/9'(aspect-ratio: 16/9)
prefers-color-scheme'dark'(prefers-color-scheme: dark)
prefers-reduced-motion'reduce'(prefers-reduced-motion: reduce)
prefers-contrast'more'(prefers-contrast: more)
hover'none'(hover: none)
pointer'coarse'(pointer: coarse)
forced-colors'active'(forced-colors: active)
resolution'2dppx'(resolution: 2dppx)
display-mode'standalone'(display-mode: standalone)
raw'print'print (как есть)

Глобальный синглтон

Библиотека экспортирует уже настроенный синглтон responsiveState, инициализированный конфигом ResponsiveConfig по умолчанию (mobile / tablet / desktop).

ts
import { responsiveState, setResponsiveConfig, getResponsiveMediaQueries } from 'responsive-media'

// Перенастраиваем синглтон
setResponsiveConfig(
  {
    sm: [{ type: 'max-width', value: 767 }],
    lg: [{ type: 'min-width', value: 1024 }],
  },
  {
    order: ['sm', 'lg'], // для isAbove / isBelow / between
    debounce: 50, // мс — троттлинг слушателей subscribe()
  },
)

// Читаем стабильный снапшот
const { sm, lg } = responsiveState.getState()

// Живой доступ через прокси (никогда не дебаунсится)
console.log(responsiveState.proxy.sm)

// Получаем сгенерированные CSS-строки
const mq = getResponsiveMediaQueries()
// { sm: '(max-width: 767px)', lg: '(min-width: 1024px)' }

Конфиг по умолчанию (ResponsiveConfig)

КлючДиапазон
mobile≤ 600px
tablet601 – 960px
desktop≥ 961px

createResponsiveState: изолированные экземпляры

Создавайте независимые экземпляры — полезно для SSR по-запросу, нескольких независимых контекстов или тестирования:

ts
import { createResponsiveState, TailwindPreset, TailwindOrder } from 'responsive-media'

const layoutState = createResponsiveState(TailwindPreset, {
  order: [...TailwindOrder],
})

const themeState = createResponsiveState({
  dark: [{ type: 'prefers-color-scheme', value: 'dark' }],
  reducedMotion: [{ type: 'prefers-reduced-motion', value: 'reduce' }],
})

layoutState.subscribe((s) => console.log('layout:', s))
themeState.subscribe((s) => console.log('theme:', s))

// Очистка по завершении (например, SSR по-запросу)
layoutState.destroy()

ContainerState: контейнерные запросы элемента

ContainerState отслеживает размеры элемента через ResizeObserver и вычисляет условия брейкпоинтов в JavaScript — та же концепция, что и CSS Container Queries, но в JS.

API идентичен ReactiveResponsiveState — все методы подписки работают так же.

ts
import { createContainerState } from 'responsive-media/container'
// или: import { createContainerState } from 'responsive-media';

const card = document.querySelector('.card')!

const cardState = createContainerState(
  card,
  {
    compact: [{ type: 'max-width', value: 300 }],
    normal: [
      { type: 'min-width', value: 301 },
      { type: 'max-width', value: 599 },
    ],
    wide: [{ type: 'min-width', value: 600 }],
  },
  {
    order: ['compact', 'normal', 'wide'],
  },
)

// Реактивное переключение классов
cardState.on('compact', (v) => card.classList.toggle('card--compact', v))

// Синхронизация CSS custom properties: --card-compact: 1; --card-wide: 0; …
cardState.syncCSSVars({ prefix: '--card-' })

// Получаем строки запросов, совместимые с @container
const strings = cardState.getMediaQueries()
// { compact: '(max-width: 300px)', wide: '(min-width: 600px)' }

// Очистка
cardState.destroy()

Поддерживаемые типы условий для ContainerState

max-width, min-width, max-height, min-height, orientation, aspect-ratio