Skip to content

Поддержка браузеров ​

wmkit поставляется в ES2022 (target: es2022 в tsup), ESM + CJS, без полифиллов и без рантайм-зависимостей. Нижнюю планку задают платформенные API, которых касается каждый слой, а не синтаксис, — поэтому ответ зависит от того, какую часть пакета вы на самом деле импортируете.

Поддерживаемые минимальные версии ​

Что вы импортируетеChrome / EdgeSafariFirefoxЧем задано
ядро (машина состояний) без именованных раскладок9415.493целевая платформа сборки ES2022
ядро с saveLayout / getLayout / setLayout9815.494structuredClone; старые движки копируют раскладки через JSON, см. ниже
attachDesktop (перетаскивание, ресайз, снэп, клавиатура, a11y)9815.494по-прежнему определяют ES2022 и structuredClone
themes/glass.css, themes/light.css11116.2113color-mix() в превью снэпа
themes/retro.css9815.494только обычные рамки и градиенты
@surdeddd/wmkit/persist9815.494как у ядра; если localStorage нет или он бросает исключения, плагин ничего не делает
@surdeddd/wmkit/popout9815.494всплывающее окно window.open везде; для picture-in-picture нужны Chrome/Edge 116+ или Firefox 151+
@surdeddd/wmkit/dock9815.494как у attachDesktop; MutationObserver помечает поздние окна

Адаптеры добавляют только то, что требует их фреймворк: React >= 18, Vue >= 3.3, Svelte >= 4, Solid >= 1.8, Angular >= 16.

DOM API, которые нужны контроллеру, — захват указателя, ResizeObserver, requestAnimationFrame — появились за годы до целевой ES2022, поэтому на практике планку они никогда не задают.

Если коротко: библиотека работает во всех браузерах начиная с начала 2022 года; импорт встроенной стеклянной темы поднимает планку до весны 2023-го. Стилизуйте окна сами — и строка про темы исчезнет совсем.

Платформенные API и что бывает без них ​

APIКто используетЧто без него
Pointer Events + setPointerCapturesrc/dom/drag.ts, src/dom/resize.ts, разделители панелейнет перетаскивания и ресайза; управление с клавиатуры и ядро продолжают работать
ResizeObserverотслеживание вьюпорта в attachDesktopпроверяется наличие — рабочий стол измеряется один раз при привязке; когда его размер меняется, вызывайте wm.setViewport() сами
requestAnimationFrameгруппировка ввода указателя по кадрам при перетаскивании и ресайзеобязателен
structuredCloneименованные раскладки в src/core/manager.tsраскладки копируются через JSON: функции в meta пропадают, Date превращаются в строки, а Infinity — в null; остальные методы ядра не затронуты
Element.animateFLIP-призраки при сворачивании и восстановлениипроверяется наличие — анимация пропускается, состояние всё равно меняется
Element.moveBeforeпересборка скина в src/dom/controller.tsпроверяется наличие — контент переносится через append, поэтому iframe внутри пересобранного окна перезагружается (в Chromium 133+ он продолжает работать)
matchMediaопределение грубого указателя и reduced motionпроверяется наличие — откат к значениям по умолчанию для точного указателя
localStorageхранилище persist по умолчаниючитается внутри try/catch; плагин перестаёт что-либо делать, или передайте своё хранилище
reportErrorошибки persist, когда нет onErrorпроверяется наличие — ошибка молча отбрасывается
CSSStyleSheet.replaceSync (constructable stylesheets)<wm-desktop>.styles, теневые скины из @surdeddd/wmkit/chrome<wm-desktop>.styles пропускает CSS-строки (Safari до 16.4); теневой скин переходит на элемент <style>
document.adoptedStyleSheetsкопирование стилей в popoutпроверяется наличие — копируются только document.styleSheets
documentPictureInPicturepopout (target: 'pip', и 'auto', когда он есть)'auto' откатывается на всплывающее окно; isPopoutSupported('pip') возвращает false
window.openpopout (target: 'window')isPopoutSupported() возвращает false, когда нет ни того, ни другого; popout() отклоняется с понятной ошибкой
getScreenDetails (Window Management API)опция screen в popout, listScreens()проверяется наличие — всплывающее окно открывается там, где браузер ставит его по умолчанию, а listScreens() разрешается в null; то же самое происходит, когда в разрешении отказано

Ничто в src/core не трогает window или document, поэтому менеджер можно создавать, менять, сериализовать и восстанавливать через hydrate во время SSR. Документ нужен только attachDesktop и хелперам привязки из адаптеров — вызывайте их после монтирования.

Возможности CSS во встроенных темах ​

ВозможностьГдеЗапасной вариант
color-mix()заливка и рамка превью снэпа (glass.css, light.css)превью рисуется без стилей; переопределите [data-wm-snap-preview] статическим цветом
backdrop-filterразмытие окна и тайтлбарадеградирует до плоской полупрозрачной панели
contain: layout styleэлемент окнатолько подсказка для производительности
отдельные свойства translate / scaleкейфреймы открытия и блокировки модалкойанимация пропускается
prefers-reduced-motionкаждая темаанимаций меньше, но никогда не больше

Все темы — это чистые кастомные свойства поверх атрибутов data-wm-*, так что, заменив тему своим CSS, вы снимаете все требования из этой таблицы.

Тестовая матрица ​

CI на каждый push прогоняет полный набор end-to-end тестов в:

  • Chromium (Playwright Desktop Chrome)
  • Firefox (Playwright Desktop Firefox)
  • WebKit (Playwright Desktop Safari)
  • мобильном Chromium (Playwright Pixel 7, тач и грубый указатель)

Юнит-тесты идут в Node, а смоук-тесты адаптеров и DOM — в jsdom.

Тач и указатель ​

Грубые указатели (pointer: coarse) автоматически получают более крупные хит-зоны ресайза (16 px по краям и 24 px в углах вместо 8 и 12), более широкий порог снэпа (20 px вместо 12), более крупные угловые зоны снэпа (96 px вместо 64) и порог магнетизма 12 px вместо 8. Любое из этого переопределяется через hitAreas, snap и magnetism в attachDesktop.

Контекстное меню тайтлбара срабатывает и на правый клик, и на долгое нажатие, поэтому onTitlebarContextMenu одинаково работает с обоими типами ввода.

Известные пробелы ​

  • popout открывает всплывающее окно в любом движке; picture-in-picture есть в Chrome и Edge 116+ и Firefox 151+, и только в десктопных браузерах. Проверяйте isPopoutSupported(), прежде чем показывать кнопку: браузер может отключить и то, и другое.
  • Без structuredClone именованные раскладки копируются через JSON, а при этом пропадают функции и Date превращаются в строки. Держите meta и расширения JSON-безопасными, подключите полифилл или храните вывод serialize() сами.
  • Эталоны визуальной регрессии генерируются на macOS и в CI пропускаются, поэтому различия в рендеринге ловятся вручную, а не пайплайном.