Web Overflow 🇺🇦
4.42K subscribers
380 photos
40 videos
3 files
518 links
Затишний блог про веб-розробку і не тільки 💛

Чат: @web_overflow_chat
Співпраця: @web_overflow_support
Автори: @lluchkaa & @anastasiia_tarasenko
加入频道
Framer Motion 🖼️

Щось ця бібліотека для React останнім часом часто зʼявляється у різних блогах чи рекомендаціях. З її допомогою можна легко реалізувати роботу анімації чи обробку жестів з гарною продуктивністю.

Досвіду використання даної бібліотеки в нас немає, адже на нашому проєкті анімації нечасто використовуються. Тому, це точно не рекомендація, а швидше ділимось чимось цікавим, на що варто звернути увагу.

Якщо ви раніше використовували цю бібліотеку чи дуже полюбляєте анімувати веб-сторінки, діліться своїм враженням.

👉 Відкрити документацію

#library
👍6🔥1
Tailwind Variants 🧣
#post_from @vova_taras

Tailwind Variants - бібліотека, яка з допомогою Tailwind класів дозволяє будувати API для різних варіацій стилів. Вона має різний функціонал, як, наприклад, розширення стилів чи розділення їх на слоти.

👉 Відкрити посилання

#library
👍53👀1
sherif 👮

Якщо ви працюєте з monorepo, то вважаємо, що цей пакет може стати вам як ніколи в нагоді.

Sherif - це лінтер, який допоможе вам знайти потенційні проблеми поміж ваших пакетів. Наприклад, він повідомить вас, якщо на проекті встановлені різні версії одного модуля у кількох ваших пакетах. Або може підказати вам перемістити @types/* у devDependencies.

👉 Відкрити посилання

#library
👍11
TailwindCSS container queries 🥡

Колись давно ми розповідали про Container Query в CSS. За даними Can I use майже 91% девайсів користувачів зможуть використовувати цей функціонал.

TailwindCSS з коробки не підтримує Container Query, але вони розробили окремий плагін, який дозволяє використовувати цей функціонал, майже так само, як ви використовуєте media-query.

👉 Відкрити посилання

#library
👍42
next-intl 🌐

Якщо ви працюєте з Next.js і вам потрібна багатомовність, зверніть увагу на бібліотеку next-intl. Вона підтримує форматування, має хорошу інтеграцію з TypeScript, роботу з датами та числами, а також підтримує обидва роутери: pages і app.

Ми зараз додаємо її до проєкту та поки всім задоволені! 💛

👉 Відкрити посилання

#library
👍9🔥5
Driver.js 🚖
#post_from @vova_taras

На багатьох веб-сайтах можна побачити підказки у вигляді інтерактивних підсвічувань кнопок чи форм. Такий гід по сайту може значно полегшити ознайомлення з функціоналом.

Driver.js — бібліотека, яка дозволяє легко створити подібний тур по вашому продукту, підкреслюючи ключові елементи. Краще один раз побачити, ніж десять разів прочитати, тож перегляньте демо-тур на офіційному сайті driver.js.

👉Відкрити посилання

#library
👍145🔥3
Nice Modal 💅
#post_from @vova_taras

Робота з модальними вікнами в React може бути доволі дратівливою. Потрібно тримати стан (isOpen) і продумати способи закривання (як із зовнішньої компоненти, так і всередині самого вікна).

@ebay/nice-modal-react використовує трохи інший підхід до роботи з модальними вікнами. Ви можете просто викликати функцію show та передати в неї компонент із пропсами. Це не зовсім декларативний метод, але, на нашу думку, значно зручніший.

Також великим плюсом є робота через Promise. Якщо у вас коли-небудь було модальне вікно для підтвердження, і потрібно було передавати колбеки для onConfirm та onCancel, тепер можна просто повернути значення з функції виклику.

const modal = useModal(ConfirmationModal)

const onDelete = async () => {
const confirmed = await modal.show({text: "Are you sure?"})

if (confirmed) {
...
}
}


👉 Відкрити посилання

#library
👍12🔥32
Query Key Factory 🏭

Останнім часом у нашому проєкті активно використовуємо Tanstack Query. Загалом, багато продуктів Tanstack виглядають дуже цікаво. Але сьогодні хочемо поговорити саме про Query, а точніше — про queryKey.

Все наче доволі просто - ключ до наших даних. Ми завжди прописували його прямо в useQuery:
const usePokemon = (id: string) => 
useQuery({
queryKey: ["pokemons", id],
queryFn: () => PokemonService.getById(id),
})


Якщо ж у нас є окремий хук для оновлення, після успішного завершення можна "змусити" useQuery перевантажити дані за певним ключем:
const useUpdatePokemon = (id: string) => {
const client = useQueryClient()

return useMutation({
mutationFn: (name: string) => PokemonService.update(id, { name }),
onSuccess: () => {
client.invalidateQueries({ queryKey: ['pokemons', id] })
},
})
}


При виклику invalidateQueries потрібно передати queryKey. Якщо ми хочемо оновити конкретного покемона, потрібно вказати той самий ключ.

Схожа ситуація виникає, коли ви викликаєте prefetchQuery у серверній компоненті, щоб швидко завантажити дані для користувача.

Як це можна покращити? Одне з рішень - створювати та зберігати queryKey у певному обʼєкті. На сторінці Community Projects ми знайшли бібліотеку @lukemorales/query-key-factory. Вона містить кілька допоміжних функцій, які допоможуть організувати параметри для useQuery.

👉 Відкрити посилання

#library
👍83
UAParser.js 🧑‍💻

Іноді буває корисно дізнатися трохи більше про відвідувача вашого веб-сайту: який у нього браузер, операційна система чи навіть сам пристрій. Багато такої інформації міститься у User-Agent, і її можна отримати як на клієнті, так і з HTTP-заголовків запиту.

Але навряд чи ви захочете вручну розбирати щось таке:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36

Бібліотека UAParser.js допоможе вам розібрати User-Agent і витягти інформацію про браузер, процесор, пристрій та операційну систему.

👉 Відкрити посилання

#library
👍111
TanStack Form 📋

Ми вже багато розповідали про продукти від TanStack — у них уже сформувалася ціла екосистема. Нещодавно вони представили ще один інструмент — TanStack Form.

Його створення мотивували відсутністю вбудованих засобів для роботи з формами у багатьох фреймворках. Через це розробникам доводиться або писати власні рішення, або використовувати сторонні бібліотеки. TanStack Form має на меті вирішити проблеми продуктивності (згадуємо redux-form), складної валідації та композиції форм.

Ось простий приклад використання TanStack Form:
const form = useForm({
defaultValues: { ... },
onSubmit: async ({ value }) => { ... },
})

...

<form.Field
name="firstName"
validators={{
onChange: ({ value }) => !value ? 'A first name is required' : undefined,
}}
children={(field) => (
<>
<label htmlFor={field.name}>First Name:</label>
<input
id={field.name}
name={field.name}
value={field.state.value}
onBlur={field.handleBlur}
onChange={(e) => field.handleChange(e.target.value)}
/>
<FieldInfo field={field} />
</>
)}
/>


Завдяки використанню form.Field тут є гарна підтримка TypeScript, а також можна пропускати деякі пропси (аналогічно до <Controller control /> у react-hook-form).

Валідація підтримується як для всієї форми (через useForm, зокрема зі схемами типу zod), так і для окремих полів.

Що одразу привертає увагу - підхід через children. Полю передається функція, а не JSX-елементи. Команда TanStack у коментарях зазначає, що render-пропси - "great". А що думаєте ви?

👉 Відкрити посилання

#library
👍81🔥1
Radashi ⚙️

Колись ми розповідали про Radash — легку й корисну бібліотеку, яка містила багато зручних методів і могла стати альтернативою Lodash. Вона була оптимізованою для TypeScript мала меншу вагу, що робило її привабливим вибором для багатьох розробників.

Проте з часом підтримку Radash припинили. На щастя, з’явилася її дочірня бібліотека, яка продовжує розвиток проєкту та зберігає ключові переваги попередника. Вона, як і раніше, пропонує безліч утиліт, які можуть стати в пригоді в будь-якому проєкті. Тому, якщо ви шукали сучасну й легку альтернативу Lodash, варто звернути на неї увагу.

👉 Відкрити посилання

#library
👍62