Пол Геберт в блоге написал о чрезмерно переусложнённых радио-кнопках в Shadcn. Это библиотека готовых компонентов для React, которая построена на базе Radix UI, использует Tailwind и работает по принципу «copy-paste» кода в проект.
Предположим, что в проекте нужны радио-кнопки. В HTML это решается добавлением
<input type="radio">. В Shadcn для этого нужно 3 импорта, 45 строк кода, сторонняя библиотека иконок для кружка, 30 классов Tailwind.Если залезать под капот импортируемого
RadioGroupPrimitive, там ещё 215 строк кода и 7 импортов. Неужели для радио-кнопок нужно столько кода? Но это ладно. Какой результат получается в браузере при отрисовке этого всего?<button
id="debit"
class="классы Tailwind"
type="button"
role="radio"
aria-checked="true"
data-state="checked"
value="debit"
tabindex="0"
data-radix-collection-item
>
<span
class="классы Tailwind"
data-state="checked"
>
<svg
class="классы Tailwind"
xmlns="..."
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<circle cx="12" cy="12" r="10">
</circle>
</svg>
</span>
</button>
<input
aria-hidden="true"
style="..."
tabindex="-1"
type="radio"
value="debit"
checked
name="credit-or-debit"
>
Радио-кнопка в Shadcn — это кнопка с ARIA-атрибутами для имитации радио-кнопки, SVG-круг, скрытый
<input type="radio">, который нужен для работы форм и классы Tailwind. Всё может быть гораздо проще, если использовать стандартный HTML:<input
type="radio"
name="credit-or-debit"
value="debit"
checked
>
Применение
appearance: none к флажкам и радио-кнопкам сбрасывает их стандартный внешний вид. После этого можно задавать размеры, фон, рамку, тень, закругление и так далее. Маркеры можно сделать при помощи псевдо-элементов.<input
type="radio"
name="credit-or-debit"
value="debit"
checked
>
<style>
input[type="radio"] {
--color: currentColor;
appearance: none;
display: inline-grid;
place-content: center;
width: 24px;
height: 24px;
border: 2px solid var(--color);
border-radius: 50%;
margin: 0;
&::before {
content: '';
width: 12px;
height: 12px;
border-radius: 50%;
background-color: transparent;
transition: background-color .3s;
}
&:checked::before {
background-color: var(--color);
}
@media (forced-colors: active) {
--color: ButtonText;
}
}
</style>
Задумка Shadcn и Radix, по всей видимости, в надёжности стилизации. С
<input> дела обстоят хуже, чем с <button>. Но всё же решение с appearance работает сегодня во всех актуальных браузерах. Тогда к чему весь этот оверинжиниринг?#html #css #ui