#codepen дня
Я, стыдно признаться, очень мало работал с горячими клавишами в вебе. И до недавнего времени даже не мог сказать, в чём отличие which, code и key.
Но для моего пет-проекта пришлось немного покурить тему. И в итоге я наткнулся на прекрасный пример, поясняющий за всю хурму: https://codepen.io/denilsonsa/pen/epmoma
И key, и code, и repeat, и модификаторы, и, собственно, события. Прекрасно.
Конечно же стоит обратить внимание и на MDN: key, code. Там тоже есть интерактивные примеры.
А в пет-проекте было просто прекрасное. Я разрабатываю расширение для Chrome DevTools и никак не мог понять, почему я не могу перехватить стандартные клавиатурные сочетания. Даже чёртов Esc открывал консоль.
А всё оказалось просто: я привык вешать слушатели на window или document, а ребята из Chrome повесили их на document.body. Просто прекрасно.
Впрочем, победить получилось и теперь моё расширение управляется с клавиатуры на ура.
#key #code #js #javascript #hotkeys #keyboard
Я, стыдно признаться, очень мало работал с горячими клавишами в вебе. И до недавнего времени даже не мог сказать, в чём отличие which, code и key.
Но для моего пет-проекта пришлось немного покурить тему. И в итоге я наткнулся на прекрасный пример, поясняющий за всю хурму: https://codepen.io/denilsonsa/pen/epmoma
И key, и code, и repeat, и модификаторы, и, собственно, события. Прекрасно.
Конечно же стоит обратить внимание и на MDN: key, code. Там тоже есть интерактивные примеры.
А в пет-проекте было просто прекрасное. Я разрабатываю расширение для Chrome DevTools и никак не мог понять, почему я не могу перехватить стандартные клавиатурные сочетания. Даже чёртов Esc открывал консоль.
А всё оказалось просто: я привык вешать слушатели на window или document, а ребята из Chrome повесили их на document.body. Просто прекрасно.
Впрочем, победить получилось и теперь моё расширение управляется с клавиатуры на ура.
#key #code #js #javascript #hotkeys #keyboard
#фишка дня
Потребовалось мне как-то сделать анимацию по скроллу. Достаточно сложную, но более не интерактивную. WebGL было тащить максимально глупо.
В голову пришло два варианта: просто перебор кадров или... видео. И вышло так, что видео не весило уж критично больше, зато вот было лишено всех проблем с предварительной подгрузкой изображений.
Сказано — сделано. Проигрываем видео по скроллу сдвигая таймлайн. То есть, устанавливая currentTime на requestAnimationFrame, 30 раз в секунду.
Ну а сейчас я просто покажу небольшой побочный эффект.
Как проиграть видео назад? Ну или быстро скипнуть вперёд?
Техника точно та же: https://codepen.io/alinaki/pen/vYeKXON
Если кому интересно решение оригинальной задачи — оставляйте ваши комментарии. Вообще, с видео можно много крутого делать.
#video #javascript
Потребовалось мне как-то сделать анимацию по скроллу. Достаточно сложную, но более не интерактивную. WebGL было тащить максимально глупо.
В голову пришло два варианта: просто перебор кадров или... видео. И вышло так, что видео не весило уж критично больше, зато вот было лишено всех проблем с предварительной подгрузкой изображений.
Сказано — сделано. Проигрываем видео по скроллу сдвигая таймлайн. То есть, устанавливая currentTime на requestAnimationFrame, 30 раз в секунду.
Ну а сейчас я просто покажу небольшой побочный эффект.
Как проиграть видео назад? Ну или быстро скипнуть вперёд?
Техника точно та же: https://codepen.io/alinaki/pen/vYeKXON
Если кому интересно решение оригинальной задачи — оставляйте ваши комментарии. Вообще, с видео можно много крутого делать.
#video #javascript
#заметка дня
Я тут сделал свой первый ESLint-плагин! Ну и, соответственно, ввёл в наши сборки новое правило. Но обо всём по порядку.
У «моей» среды исполнения JS — Google AppsScript — есть одна неприятная особенность. А именно: в глобальный скоуп попадают все переменные, объявленные на уровне модуля. Ну и, соответственно, они друг-друга могут перезаписать.
Вообще, про забавности в разных средах JS можно целую презентацию подготовить.
Проблему можно решить используя любой бандлер, но огромную базу легаси-кода перетащить в бандлер та ещё задача, плюс, надо соблюсти условия по видимости API, поскольку в среде есть свои соглашения по приватным и публичным методам.
Потому было решено проблему видимости исключить на корню: если тебе нужен полноценный модуль, используй классы и свойства класса соответственно. Если нет — убирай свои константы в функцию. Короче говоря, понадобилось запрещающее переменные на уровне модулей правило.
С плагинами для линтера есть одна проблема: почему-то нет возможности написать своё локальное правило, в рамках репозитория проекта. Надо обязательно создавать npm-пакет… но я не хочу. По крайней мере, не сейчас.
На помощь пришёл другой плагин: eslint-plugin-local-rules.
Великолепная штука, создал eslint-local-rules.js и поехали.
Но это всё было бы гораздо сложнее разрабатывать, если бы не ещё один инструмент: https://astexplorer.net/
Abstract Syntax Tree explorer: обозреватель абстрактного синтаксического дерева. Грубо говоря, ваш код разбивается на узлы и связи между ними: вот это — оператор, это — скобка, это — определение переменной, это — присвоение значения и так далее.
Анализируя это дерево (ну и конечно, документацию ESLint и исходники других плагинов) можно вполне себе быстро реализовать задачу.
Пишите плагины для ESLint, котаны. Это не больно.
…больно разгребать глупые баги :)
#eslint #javascript #ast
Я тут сделал свой первый ESLint-плагин! Ну и, соответственно, ввёл в наши сборки новое правило. Но обо всём по порядку.
У «моей» среды исполнения JS — Google AppsScript — есть одна неприятная особенность. А именно: в глобальный скоуп попадают все переменные, объявленные на уровне модуля. Ну и, соответственно, они друг-друга могут перезаписать.
Вообще, про забавности в разных средах JS можно целую презентацию подготовить.
Проблему можно решить используя любой бандлер, но огромную базу легаси-кода перетащить в бандлер та ещё задача, плюс, надо соблюсти условия по видимости API, поскольку в среде есть свои соглашения по приватным и публичным методам.
Потому было решено проблему видимости исключить на корню: если тебе нужен полноценный модуль, используй классы и свойства класса соответственно. Если нет — убирай свои константы в функцию. Короче говоря, понадобилось запрещающее переменные на уровне модулей правило.
С плагинами для линтера есть одна проблема: почему-то нет возможности написать своё локальное правило, в рамках репозитория проекта. Надо обязательно создавать npm-пакет… но я не хочу. По крайней мере, не сейчас.
На помощь пришёл другой плагин: eslint-plugin-local-rules.
Великолепная штука, создал eslint-local-rules.js и поехали.
Но это всё было бы гораздо сложнее разрабатывать, если бы не ещё один инструмент: https://astexplorer.net/
Abstract Syntax Tree explorer: обозреватель абстрактного синтаксического дерева. Грубо говоря, ваш код разбивается на узлы и связи между ними: вот это — оператор, это — скобка, это — определение переменной, это — присвоение значения и так далее.
Анализируя это дерево (ну и конечно, документацию ESLint и исходники других плагинов) можно вполне себе быстро реализовать задачу.
Пишите плагины для ESLint, котаны. Это не больно.
…больно разгребать глупые баги :)
#eslint #javascript #ast
#ссылка дня
Чем отличается
Как же я задолбался форматирование применять.
Да весь фронтенд это нагромождение похожих по написанию или даже по сути вещей. Как разобраться?
И тут нам поможет проект https://thisthat.dev/. Он буквально проходится по таким скользким определениям или сущностям и разбирает каждый из них.
Проект открытый, предлагайте ваши
#javascript #html #css #this
Чем отличается
alt
от title
? А border
от outline
? А *.d.ts
от *.ts
? А for..in
от for..of
? А display: none
от visibility: hidden
? А slice
от splice
?Как же я задолбался форматирование применять.
Да весь фронтенд это нагромождение похожих по написанию или даже по сути вещей. Как разобраться?
И тут нам поможет проект https://thisthat.dev/. Он буквально проходится по таким скользким определениям или сущностям и разбирает каждый из них.
Проект открытый, предлагайте ваши
==
и ===
.#javascript #html #css #this
#инструмент дня
Миграции с JavaScript на TypeScript часто заходят не туда. Или не заканчиваются. Или откатываются. Зачастую в лучшем случае весь новый код начинает писаться на TypeScript и всё на этом.
Да, ещё не факт, что оно вам надо вообще, но это тема иной беседы.
Итак, с чего же начать вашу миграцию если автоматизированные средства, расставляющие везде any, вам не подходят, а
Начните с модулей с наибольшим числом зависимостей, говорит нам Matt Pocock, а он в общем-то в курсе, о чём утверждает, он учит людей тайпскрипту фулл-тайм :)
А как найти эти самые модули? Очень просто, возьмите построитель диаграмм зависимостей. Madge вполне подойдёт: https://github.com/pahen/madge
Ну и никто не мешает весь новый код писать сразу на TS.
#typescript #javascript #ts #js #diagram #deps
Миграции с JavaScript на TypeScript часто заходят не туда. Или не заканчиваются. Или откатываются. Зачастую в лучшем случае весь новый код начинает писаться на TypeScript и всё на этом.
Да, ещё не факт, что оно вам надо вообще, но это тема иной беседы.
Итак, с чего же начать вашу миграцию если автоматизированные средства, расставляющие везде any, вам не подходят, а
//@ts-nocheck
— для быдла?Начните с модулей с наибольшим числом зависимостей, говорит нам Matt Pocock, а он в общем-то в курсе, о чём утверждает, он учит людей тайпскрипту фулл-тайм :)
А как найти эти самые модули? Очень просто, возьмите построитель диаграмм зависимостей. Madge вполне подойдёт: https://github.com/pahen/madge
Ну и никто не мешает весь новый код писать сразу на TS.
#typescript #javascript #ts #js #diagram #deps
#драма дня
Итак, сообщество опять бомбит. Вот вы спите, а там происходит ого-го какая драма!
Короче, TL;DR: Создатель Ruby on Rails, Давид Хейнемейер Ханссон (David Heinemeier Hansson) заявил, что TypeScript не нужен.
Подробнее: https://world.hey.com/dhh/turbo-8-is-dropping-typescript-70165c01
Суть ситуации в том, что (в основном в мире RoR) есть фреймворк Turbo. По факту, он успешно конкурирует с Astro, HTMX и прочими React Server Components и просит ещё. Бесшовная интеграция фронтенда с бакендом через передачу HTML различными способами: https://turbo.hotwired.dev/
Идея не нова, что-то похожее есть и в Drupal, и в October CMS, можно повторить и в Laravel и так далее.
Так вот Turbo до 7 версии включительно был написан на TypeScript, а сейчас Давид психанул. Из его сообщения можно сделать вывод, что ООП (а Turbo пишется в ООП-стиле) в современном JS вполне себе развилось до состояния, в котором с ним можно работать.
Но ещё явно прослеживается, что он просто устал воевать со сложными типами. Многим знакомо это ощущение, когда типы разрастаются до невероятных размеров и сложности, особенно когда схема передаваемых данных очень сложна.
Сообщество бурлит, ссылается на State of JS 2023, мол, 70% разработчиков использует TS. Проблема только в том, что не 70% разработчиков, а 70% поучаствовавших в опросе.
К слову, ситуация не нова. React как был на JS написан, так и остаётся. Правда, без громких заявлений.
Upd. там фейсбучный Flow, про который я забыл совсем. И определения TS-типов поставляются в отдельном пакете.
Ну и ещё лично я замечал, когда мне надо поэкспериментировать, я точно не выберу TS: в экспериментах типобезопасность это последнее, что меня волнует, а в рантайме тебя TS не особо спасает от дурацких решений (inb4 гигиена, тайпгарды и и контракты).
Интересно, скоро ли появится turbo.d.ts в пакете types? По-моему, Давид и определения поставлять не собирается. Что-то это уже ну такое 🙂
А как ваши дела с TS, котаны?
P. S. мне тут напомнили, что самая мякотка-то происходит в обсуждении PR с удалением TS: https://github.com/hotwired/turbo/pull/971
Там просто полыхают костры из ягодиц.
#typescript #javascript #ruby
Итак, сообщество опять бомбит. Вот вы спите, а там происходит ого-го какая драма!
Короче, TL;DR: Создатель Ruby on Rails, Давид Хейнемейер Ханссон (David Heinemeier Hansson) заявил, что TypeScript не нужен.
Подробнее: https://world.hey.com/dhh/turbo-8-is-dropping-typescript-70165c01
Суть ситуации в том, что (в основном в мире RoR) есть фреймворк Turbo. По факту, он успешно конкурирует с Astro, HTMX и прочими React Server Components и просит ещё. Бесшовная интеграция фронтенда с бакендом через передачу HTML различными способами: https://turbo.hotwired.dev/
Идея не нова, что-то похожее есть и в Drupal, и в October CMS, можно повторить и в Laravel и так далее.
Так вот Turbo до 7 версии включительно был написан на TypeScript, а сейчас Давид психанул. Из его сообщения можно сделать вывод, что ООП (а Turbo пишется в ООП-стиле) в современном JS вполне себе развилось до состояния, в котором с ним можно работать.
Но ещё явно прослеживается, что он просто устал воевать со сложными типами. Многим знакомо это ощущение, когда типы разрастаются до невероятных размеров и сложности, особенно когда схема передаваемых данных очень сложна.
Сообщество бурлит, ссылается на State of JS 2023, мол, 70% разработчиков использует TS. Проблема только в том, что не 70% разработчиков, а 70% поучаствовавших в опросе.
К слову, ситуация не нова. React как был на JS написан, так и остаётся. Правда, без громких заявлений.
Upd. там фейсбучный Flow, про который я забыл совсем. И определения TS-типов поставляются в отдельном пакете.
Ну и ещё лично я замечал, когда мне надо поэкспериментировать, я точно не выберу TS: в экспериментах типобезопасность это последнее, что меня волнует, а в рантайме тебя TS не особо спасает от дурацких решений (inb4 гигиена, тайпгарды и и контракты).
Интересно, скоро ли появится turbo.d.ts в пакете types? По-моему, Давид и определения поставлять не собирается. Что-то это уже ну такое 🙂
А как ваши дела с TS, котаны?
P. S. мне тут напомнили, что самая мякотка-то происходит в обсуждении PR с удалением TS: https://github.com/hotwired/turbo/pull/971
Там просто полыхают костры из ягодиц.
#typescript #javascript #ruby
#ссылка дня
Чем отличается
Как же я задолбался форматирование применять.
Да весь фронтенд это нагромождение похожих по написанию или даже по сути вещей. Как разобраться?
И тут нам поможет проект https://thisthat.dev/. Он буквально проходится по таким скользким определениям или сущностям и разбирает каждый из них.
Проект открытый, предлагайте ваши
#javascript #html #css #this #бородач
Чем отличается
alt
от title
? А border
от outline
? А *.d.ts
от *.ts
? А for..in
от for..of
? А display: none
от visibility: hidden
? А slice
от splice
?Как же я задолбался форматирование применять.
Да весь фронтенд это нагромождение похожих по написанию или даже по сути вещей. Как разобраться?
И тут нам поможет проект https://thisthat.dev/. Он буквально проходится по таким скользким определениям или сущностям и разбирает каждый из них.
Проект открытый, предлагайте ваши
==
и ===
.#javascript #html #css #this #бородач
#статья дня
Давно не было интерактивных статей от кого-то, кроме Шадида и Комо :)
Время исправлять.
Сегодня — статья про концепцию и варианты реализации Drag&Drop-интерфейсов от Амита Пателя и Red Blob Games: https://www.redblobgames.com/making-of/draggable/
Давайте сразу: Red Blob Games это не компания, это сайт, собственно, Амита, где он объясняет используемые в играх и интерфейсах концепции: от поиска пути и генерации шестиугольной карты, до простейшего ИИ для игр.
Так вот, возвращаясь к статье: рассмотрены варианты реализации на мыши, тач-девайсах, скроллинг и различные сопутствующие проблемы (ну чтобы вам не пришлось разбираться, как, например, отключить выделение текста, пока тащишь элемент).
Прекрасная статья и проект вообще, моя горячая рекомендация.
#javascript #games #drag #drop
Давно не было интерактивных статей от кого-то, кроме Шадида и Комо :)
Время исправлять.
Сегодня — статья про концепцию и варианты реализации Drag&Drop-интерфейсов от Амита Пателя и Red Blob Games: https://www.redblobgames.com/making-of/draggable/
Давайте сразу: Red Blob Games это не компания, это сайт, собственно, Амита, где он объясняет используемые в играх и интерфейсах концепции: от поиска пути и генерации шестиугольной карты, до простейшего ИИ для игр.
Так вот, возвращаясь к статье: рассмотрены варианты реализации на мыши, тач-девайсах, скроллинг и различные сопутствующие проблемы (ну чтобы вам не пришлось разбираться, как, например, отключить выделение текста, пока тащишь элемент).
Прекрасная статья и проект вообще, моя горячая рекомендация.
#javascript #games #drag #drop
#фишка дня
Что, котан, поймал ошибку CORS aka Cross-origin resource sharing error? В переводе на русский — ошибка совместного использования ресурсов между разными источниками.
Поздравляю, ты только что перешёл на следующий уровень в разработке.
В Википедии очень простое и понятное объяснение, что это такое. А нам же с тобой нужно как-то эту проблему обойти, пусть и временно.
Весь прикол ситуации в том, что отношения между сервером и браузером построены на доверии одного другому. CORS нужен не для защиты сервера, а для защиты клиента.
Кстати, именно поэтому первым решением проблемы с CORS могут быть специальные прокси: https://nordicapis.com/10-free-to-use-cors-proxies/
Если хотите, я подробнее потом о них расскажу. И о CORS тоже.
Но что делать если использование прокси не представляется возможным?
Всё просто, открываем Chrome DevTools и меняем заголовок Access-Control-Allow-Origin на *, нажав на карандашик рядом.
Естественно, таким образом можно менять и добавлять любые заголовки.
А ещё можно создать файлик с заранее прописанными заголовками — .headers — и включить его как правило через Add overrrde rule в Sources 👉 Overrides.
Всем безоблачной разработки, котаны!
#javascript #network #cors
Что, котан, поймал ошибку CORS aka Cross-origin resource sharing error? В переводе на русский — ошибка совместного использования ресурсов между разными источниками.
Поздравляю, ты только что перешёл на следующий уровень в разработке.
В Википедии очень простое и понятное объяснение, что это такое. А нам же с тобой нужно как-то эту проблему обойти, пусть и временно.
Весь прикол ситуации в том, что отношения между сервером и браузером построены на доверии одного другому. CORS нужен не для защиты сервера, а для защиты клиента.
Кстати, именно поэтому первым решением проблемы с CORS могут быть специальные прокси: https://nordicapis.com/10-free-to-use-cors-proxies/
Если хотите, я подробнее потом о них расскажу. И о CORS тоже.
Но что делать если использование прокси не представляется возможным?
Всё просто, открываем Chrome DevTools и меняем заголовок Access-Control-Allow-Origin на *, нажав на карандашик рядом.
Естественно, таким образом можно менять и добавлять любые заголовки.
А ещё можно создать файлик с заранее прописанными заголовками — .headers — и включить его как правило через Add overrrde rule в Sources 👉 Overrides.
Всем безоблачной разработки, котаны!
#javascript #network #cors
#заметка дня
Иногда полезно спорить с мэтрами по поводу разных штук. Не стоит всё подряд принимать на веру.
Вот, например, Кори Хаус, весьма известный консультант по React, предложил буквально следующее: чтобы не запутаться в бесконечных хуках useEffect в React, вместо неименованной функции передавайте именованную.
То бишь, вместо:
Предлагается
На первый взгляд выглядит разумно, не правда ли?
Самодокументирующийся код без комментариев, хорошо видно намерение, сразу понятно, используется или нет.
Так вот, товарищи. Это далеко не самое лучшее решение, да ещё и многословное. Гораздо более разумно будет создать свой собственный хук.
Что такое свой собственный хук? Вы не поверите, это буквально тот же самый useEffect, но вынесенный в функцию:
Да, внутри функции кастомного хука можно держать useState, обращаться к внешним источникам данных и возвращать что угодно. Это, например, рекомендуемый способ использования того же React Query и официальная рекомендация команды React для переиспользования логики: https://react.dev/learn/reusing-logic-with-custom-hooks
Почему такой подход лучше?
Потому что, обладая всеми преимуществами варианта, предложенного Кори, он не только сокращает размер основного компонента но и легко тестируется!
Да, представьте себе, вы задолбаетесь правильно тестировать компонент с даже двумя-тремя встроенными хуками. А вынесенные отдельно — не только легко мокаются и подменяются, но и прекрасно тестируются сами по себе.
Так что команда React могла бы назвать раздел документации не "как переиспользовать", а "как тестировать". Это важнее.
В общем, не забываем про голову, котаны. Готов выслушать ваши сомнения, впрочем 🙂
#react #javascript #hooks
Иногда полезно спорить с мэтрами по поводу разных штук. Не стоит всё подряд принимать на веру.
Вот, например, Кори Хаус, весьма известный консультант по React, предложил буквально следующее: чтобы не запутаться в бесконечных хуках useEffect в React, вместо неименованной функции передавайте именованную.
То бишь, вместо:
useEffect(() => {
// do stuff
}, [...deps]);
Предлагается
useEffect(function doSomething() {
// do stuff
}, [...deps]);
На первый взгляд выглядит разумно, не правда ли?
Самодокументирующийся код без комментариев, хорошо видно намерение, сразу понятно, используется или нет.
Так вот, товарищи. Это далеко не самое лучшее решение, да ещё и многословное. Гораздо более разумно будет создать свой собственный хук.
Что такое свой собственный хук? Вы не поверите, это буквально тот же самый useEffect, но вынесенный в функцию:
function useDoSomething(deps) {
useEffect(() => {
// some effect
}, [...deps]);
}
Да, внутри функции кастомного хука можно держать useState, обращаться к внешним источникам данных и возвращать что угодно. Это, например, рекомендуемый способ использования того же React Query и официальная рекомендация команды React для переиспользования логики: https://react.dev/learn/reusing-logic-with-custom-hooks
Почему такой подход лучше?
Потому что, обладая всеми преимуществами варианта, предложенного Кори, он не только сокращает размер основного компонента но и легко тестируется!
Да, представьте себе, вы задолбаетесь правильно тестировать компонент с даже двумя-тремя встроенными хуками. А вынесенные отдельно — не только легко мокаются и подменяются, но и прекрасно тестируются сами по себе.
Так что команда React могла бы назвать раздел документации не "как переиспользовать", а "как тестировать". Это важнее.
В общем, не забываем про голову, котаны. Готов выслушать ваши сомнения, впрочем 🙂
#react #javascript #hooks
#фишка дня
Как получить последний элемент массива?
Можно посчитать длину массива минус один, чтобы получить нужный индекс.
Можно сделать array.slice(-1) и взять нулевой элемент получившегося массива.
А можно воспользоваться сравнительно новым методом Array.prototype.at! Ну, уже два года как в продакшене. И полифилл давно есть.
Весьма удобно, я считаю.
#javascript #array
Как получить последний элемент массива?
Можно посчитать длину массива минус один, чтобы получить нужный индекс.
Можно сделать array.slice(-1) и взять нулевой элемент получившегося массива.
А можно воспользоваться сравнительно новым методом Array.prototype.at! Ну, уже два года как в продакшене. И полифилл давно есть.
Весьма удобно, я считаю.
#javascript #array
This media is not supported in your browser
VIEW IN TELEGRAM
#библиотека дня
Сегодня не самая обычная библиотека, решающая, впрочем, достаточно сложную задачу.
Компания Evil Martians и Андрей Ситник конкретно известны своим скурпулёзным подходом к интерфейсам и их оптимизации. Если кто-то ещё не в курсе существования их блога, настоятельно рекомендую: https://evilmartians.com/chronicles
Ну конкретно по теме канала — тег Frontend, конечно же.
Так вот, одной из их достаточно новых специализаций является разработка интерфейсов профессиональных утилит, в том числе для десктопа. Например, UI для HTTPie.
А без чего нельзя представить себе профессиональное приложение? Правильно, без хоткеев. Да и вообще нынче доступность без хоткеев — не доступность вовсе.
И вот Андрей Ситник на днях выкатил обновление своей библиотеки KeyUX: https://github.com/ai/keyux
Пример её работы на видео. А что умеет?
1. Добавлять горячие клавиши по aria-keyshortcuts
2. Возвращает на место :active у кнопок при использовании клавиатуры
3. Превращает списки в навигационные элементы
4. Правильно отрабатывает стрелки, табуляцию и Esc.
5. Показывает подсказки если нужно.
В общем, мне кажется, это всё должно было быть в браузерах по-умолчанию.
#javascript #a11y #hotkeys
Сегодня не самая обычная библиотека, решающая, впрочем, достаточно сложную задачу.
Компания Evil Martians и Андрей Ситник конкретно известны своим скурпулёзным подходом к интерфейсам и их оптимизации. Если кто-то ещё не в курсе существования их блога, настоятельно рекомендую: https://evilmartians.com/chronicles
Ну конкретно по теме канала — тег Frontend, конечно же.
Так вот, одной из их достаточно новых специализаций является разработка интерфейсов профессиональных утилит, в том числе для десктопа. Например, UI для HTTPie.
А без чего нельзя представить себе профессиональное приложение? Правильно, без хоткеев. Да и вообще нынче доступность без хоткеев — не доступность вовсе.
И вот Андрей Ситник на днях выкатил обновление своей библиотеки KeyUX: https://github.com/ai/keyux
Пример её работы на видео. А что умеет?
1. Добавлять горячие клавиши по aria-keyshortcuts
2. Возвращает на место :active у кнопок при использовании клавиатуры
3. Превращает списки в навигационные элементы
4. Правильно отрабатывает стрелки, табуляцию и Esc.
5. Показывает подсказки если нужно.
В общем, мне кажется, это всё должно было быть в браузерах по-умолчанию.
#javascript #a11y #hotkeys