Пишем компоненты с параметрами в styled-components

Всем привет!

Поступил свежий вопрос, в ответ на который и пишу данный топик. Задачка довольно тривиальная, но в реализации показывает преимущество использование styled-components в связке с TypeScript.

Что было и что стало?

Было выпадающее меню, в котором стили менялись в зависимости от состояния переменной citiesOpened.

Что здесь не так?

  1. На уровне TS здесь никак не задается, что свойство style::display обязательное.
  2. Лишняя заморочка с придумыванием className, чтобы оно точно не пересеклось с какими-нибудь другими стилями (Вдруг где-то еще прописаны стили для .dropdown-menu).
  3. Навозможность переиспользования кода (где-то же еще может понадобиться такое меню (хотя для этого в таком виде все равно его надо улучшать, но это уже другая история:)))

Что сделано. На всякий случай весь коммит: https://github.com/Pivkarta/pivkarta.ru-2/pull/2/commits/0277ad2d148046b519a1c6c11923385423868628

Простые HTML-теги были заменены на styled-components.

Корневой li на вот это: А ul на вот это

Соответственно в самом реакт-компоненте стало так:

В чем здесь выигрыш?

  1. TS будет ругаться, если обязательное свойство не указано.
  2. Не надо придумывать className. Здесь мы оперируем самими компонентами и их же можно использовать для расширения стилей. Пример:

Здесь я специально так сделал для наглядности, хотя в нашем случае это и не требовалось. В общем, в самом DropdownMenu указана максимальная высота 60vh, но в MainMenuStyled прописано, что вложенным компонентам DropdownMenu надо задать максимальную высоту 70vh. При этом вполне допускается и другие классические селекторы прописывать типа class, id и т.п. К примеру так:

А в реакт-компоненте прописать этот класс:

  1. Теперь это меню можно вынести в самостоятельный реакт-компонент и использовать его в других местах, при этом легко переопределять стили.

P.S. Я только тут свои же правила нейминга нарушил. В стилях такие компоненты надо писать с суффиксом Styled, то есть не DropdownMenu, а DropdownMenuStyled. Но это я сейчас отдельно коммит выкачу, статью уже не буду переписывать. Просто имейте это ввиду.