Библиотека фронтендера | Frontend, JS, JavaScript, React.js, Angular.js, Vue.js
21.8K subscribers
2.78K photos
192 videos
42 files
5.11K links
Все самое полезное для фронтенда в одном канале.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/77178ed4

Для обратной связи: @proglibrary_feeedback_bot

РКН: https://gosuslugi.ru/snet/67a5b6884689c2151c820bb4
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
🕺 AnimatiSS — коллекция CSS-анимаций

Библиотека готовых keyframe-анимаций: bounce, fade, shake, blur, jello и другие эффекты.

Можно посмотреть демо на странице и скопировать код нужной анимации. Всё на чистом CSS, легковесно.

📎 Ссылка

🐸 Библиотека фронтендера

#readme #css
Please open Telegram to view this post
VIEW IN TELEGRAM
9🤩2👍1
🧩 Как исправить любой баг — когда даже ИИ сдался

Классическая история: всё работает, пока не добавишь один невинный fetch().

Claude несколько раз уверенно объявлял: «готово, всё исправил» — но баг оставался. Так родилась статья о настоящем процессе отладки:

📍 Как находить минимальный репро,
📍 Когда стоит менять подход,
📍 И почему без «well-founded recursion» в отладке можно застрять навсегда.

Карточки выше — краткий конспект, а оригинал обязательно стоит прочитать 📎

🐸 Библиотека фронтендера

#blueprint
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥53🥱2🔥1
🫥 Как я перестал бороться с TypeScript

После того случая я перестал спорить с TypeScript. Решил внедрить его хотя бы частично — просто чтобы понять, действительно ли он чего-то стоит. И вот тут началось самое интересное.

🧽 На проекте был модуль оплаты. Мелочь: функция принимала price, а я случайно передал туда строку из инпута. JS, конечно, не возмутился — просто сложил две строки:


function calcTotal(price) {
return price + 2000
}

calcTotal("4000") // "40002000»


На проде чек вырос в два раза, клиент — в гневе. А я — с новыми седыми волосами.

С TypeScript такого бы не случилось:


function calcTotal(price: number) {
return price + 2000
}
// Argument of type 'string' is not assignable to parameter of type 'number’


После этого я посмотрел на TS по-другому. Он не просто проверяет типы — он ловит ошибки до того, как они становятся проблемами.

Поначалу раздражает:

«Зачем всё это?»
«Слишком строго!»
«Лишний бойлерплейт!»


А потом замечаешь: автодополнение стало умнее, рефакторинг — безопаснее, новые разработчики быстрее разбираются в коде.

🤨 Теперь я воспринимаю TypeScript не как обузу, а как коллегу, который делает код-ревью мгновенно и честно.

🐸 Библиотека фронтендера

#code_battle
Please open Telegram to view this post
VIEW IN TELEGRAM
🥰82👍1
This media is not supported in your browser
VIEW IN TELEGRAM
📕 Библиотека UI-компонентов

Коллекция из 4000+ готовых элементов интерфейса: кнопки, карточки, инпуты, чекбоксы, лоадеры. Всё на чистом CSS или Tailwind.

🎥 Каждый элемент сделан сообществом, открыт по MIT-лицензии. Копируете код в один клик, вставляете в проект.

🔗 Ссылка

🐸 Библиотека фронтендера

#readme #ui
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍2
😓 Роутинг в SPA — боль

Классика: слушаем click, ставим preventDefault(), делаем history.pushState(), потом ловим popstate и рендерим контент.
Работает, но это куча бойлерплейта и расхождений между состоянием, URL и историей.

Почему так:

History API не создавался под SPA. Он не умеет централизованно управлять всеми типами навигации и не даёт понять, когда переход «завершён», чтобы безопасно менять UI и скролл.

🔤 Нормальное решение — Navigation API (эксперимент, Chrome 102+):

• navigate — единое событие для всех переходов
• event.intercept() — перехват и свой обработчик (загрузили данные, отрисовали, проверили доступ)
• event.scroll() — нативный скролл
• { committed, finished } — когда менять URL и когда переход реально завершён
• entries() и currentEntry — история как нормальные объекты со state


Fallback:

Если window.navigation нет, остаёмся на старом pushState.


if ('navigation' in window) {
navigation.addEventListener('navigate', (event) => {
if (shouldNotIntercept(event)) return;
const url = new URL(event.destination.url);

event.intercept({
async handler() {
renderSkeleton();
const html = await fetchPage(url.pathname);
render(html);
event.scroll();
},
});
});

const { committed, finished } = navigation.navigate('/profile');
committed.then(() => showLoading());
finished.finally(() => hideLoading());
}


📦 Поддержка:

Chromium 102+, Safari (новые версии), Firefox — пока нет.
API экспериментальный, используйте feature-detect.

📎 Официальная спецификация

🐸 Библиотека фронтендера

#hotfix #js
Please open Telegram to view this post
VIEW IN TELEGRAM
🥰53🔥1