Ваша аудитория будет любить вас, если вы дадите им любящий опыт UX-in-Code.

«Как передать наше большое творческое послание и увеличить продажи на крошечных экранах телефонов - менее чем за 2 секунды?»

Плач маркетологов повсюду.

Брендам необходимо решать проблемы, с которыми им никогда раньше не приходилось сталкиваться. Проблемы, такие как разрешение экрана, разборчивость, удобство использования, жесты, касания, смахивания и многое другое…

Более того, посетители тратят слишком много времени на закрытие всплывающих окон, прокрутку, блокировку и недостаточно времени на просмотр вашего контента. Контент обещанный в платном объявлении.

На мобильных устройствах ваш сайт должен выглядеть как нативное приложение.

Цель состоит в том, чтобы затронуть и заинтересовать людей в их мире, а не заставлять их адаптироваться к нашему.

В этой части UX in ‹Code /› мы собираемся откусить крошечный кусок от общей технической картины и добавить много изюминки одним движением. Мы собираемся создать анимированную модель вкладок, которая будет предлагать ваш потрясающий контент в убедительной и интуитивно понятной форме.



Не стесняйтесь пересылать остальную часть информации своим партнерам по команде разработчиков.

Приступим к кодированию.

Во-первых, давайте установим пару вещей.

Я предполагаю, что у вас настроена среда разработки React, поэтому я пропущу эту часть .

Я пробовал несколько пакетов анимации React, и победителем стал react-spring. Он прост в использовании, хорошо документирован, имеет много примеров кода и имеет очень активное сообщество. Получите информацию и пример кода здесь.

Кроме того, поскольку мы ориентируемся на устройства с сенсорным экраном, нам потребуется установить пакет response-use-gesture. Получите информацию и пример кода здесь.

Установите оба с npm install react-spring react-use-gesture.

Небольшое примечание…

Эта статья не является руководством по созданию компонента пользовательского интерфейса вкладки. Скорее, мы собираемся сосредоточиться на перемещении ваших вкладок в сторону, когда ваша аудитория заинтересована вашим контентом!

В моем случае я решил настроить модуль вкладок UIKit. Однако существует тонна примеров вкладок React, так что вы должны использовать то, что вам нравится и с чем вам удобнее всего, это действительно не имеет значения.

Компонент «Вкладки».

Мы собираемся создать наши вкладки как компонент многократного использования, который можно будет импортировать в любой компонент или приложение. Начнем с создания нового файла с именем Tabs.js.

Вы видите, что я там делал? Мы используем хуки React для переключения нашего компонента между развернутым и свернутым положением. Мы также импортируем useSpring hook и animated из react-spring, чтобы сгенерировать нашу анимацию, и useGesture, чтобы запускать события касания. Но об этом позже.

Аргумент tabLabels - это список меток, которые будут отображаться в виде отдельных вкладок. Например, вы могли бы сделать это

["Sign Up", "Pricing", "Contact Us"]

Аргумент children позволяет нам включить содержимое вкладки в компонент, а ...props используется для передачи в компонент других вещей, например className или чего-нибудь еще, что нас интересует.

Затем мы устанавливаем useState(true) для инициализации расширенного состояния. Это означает, что когда кто-то попадает на веб-страницу, содержимое заголовка и вкладки расширяются, отображая большой заголовок, а также нашу навигацию по вкладкам.

На данный момент у нас есть только наш контейнер вкладок и заголовок. Если мы запустим этот код, мы не увидим ничего, кроме заголовка. Итак, давайте добавим наши кнопки вкладок!

Здесь довольно много всего происходит, так что давайте пройдемся по нему.

После заголовка мы добавили новый div для кнопок вкладок и включили его в className:

${tabsExpanded ? "tabs-default" : "tabs-collapsed"}

Это называется тернарный оператор, и он говорит:

  • ЕСЛИ tabsExpanded истина, тогда добавьте класс CSS "tabs-default"
  • или ИНАЧЕ, класс "tabs-collapsed".

Но откуда взялось tabsExpanded? Помните, выше мы добавили переменнуюuseState(true), установив для нашего tabsExpanded значение true? Ага, вот оно.

Полагаю, вы понимаете, к чему мы клоним. Мы будем использовать useState с нашей setTabsExpanded переменной для переключения положения наших вкладок!

Последнее, что мы добавили в этот фрагмент кода, - это tabLabels.map(), который выполняет итерацию по массиву tabLabels, создавая кнопки табуляции. Итак, вот небольшое объяснение того, почему мы делаем это таким образом ...

Мы хотим, чтобы наш компонент вкладок можно было импортировать везде!

Это означает, что мы должны иметь возможность передавать переменную, чтобы информировать наши вкладки о том, какой контент они должны загружать , когда кто-то нажимает на них. В противном случае нам придется копировать и вставлять код на каждую страницу, где используются вкладки. Это ужасно.

Итак, вместо этого мы будем действительно супер-умными и просто передадим кучу ярлыков, чтобы затем мы могли использовать их в качестве идентификаторов для загрузки контента, который нам нужен для каждой вкладки. Возьми? Понятно? Хороший!

Вот краткий обзор того, чего мы уже достигли:

  1. Мы создали компонент "Вкладки" многократного использования.
  2. В компоненте «Вкладки» мы используем useState для инициализации расширенного представления вкладок по умолчанию.
  3. И мы используем .map() для циклического перебора массива ярлыков вкладок для создания кнопок вкладок и определения содержимого, которое мы хотим загрузить, когда кто-то нажимает кнопку.

Вау, это большой прогресс для такого маленького кода.

Настройка сенсорных жестов.

Теперь, когда мы отображаем наши вкладки, нам нужно заставить их работать с помощью жестов сенсорного экрана. То есть мы хотим, чтобы наш контейнер вкладок сворачивался, когда пользователи смахивают вверх, и расширялся, когда они смахивают вниз. Мы можем сделать это с помощью useGesture, вот так:

Хорошо, эти 7 строк кода немного сложны, поэтому давайте прочитаем их построчно:

onDrag: ({ down, direction: [, y], delta: [yDelta] }) => {

Присоедините событие onDrag для захвата жестов смахивания и добавьте встроенные аргументы down, direction и delta. Поскольку нас интересуют только смахивания вверх и вниз, нам просто нужны y-axis направление и yDelta.

const trigger = Math.abs(yDelta) >= 1;

Установите переменную trigger для запуска анимации. Код говорит: «Если абсолютное значение yDelta больше или равно 1, то значение trigger будет истинным».

const dir = y > 0 ? -1 : 1;

Установите переменную направления dir. Этот тернарный оператор говорит: «если пользователь проводит пальцем вниз по экрану (y > 0), тогда dir равно -1, иначе dir равно 1 при смахивании вверх». Да, это немного неинтуитивно, но знаете, как угодно.

Это строка, которая заставляет все это работать:

if (!down && trigger) dir < 0 ? setTabsExpanded(true) : setTabsExpanded(false);

Этот кусок кода говорит:

  • «ЕСЛИ жест НЕ является простым касанием (!down) и trigger имеет значение true (смахивание превышает заданное нами yDelta),
  • «Затем проверьте, находится ли dir смахните вниз (dir < 0).
  • «ЕСЛИ проведите пальцем по экрану вниз, установите контейнер вкладок в развернутое состояние, setTabsExpanded(true),
  • "Или Иначе установите контейнер вкладок в свернутый: setTabsExpanded(false)."

Вау, я просто прочитал это пару раз и посмеялся. Надеюсь, для вас это достаточно ясно. Если нет, дайте мне знать, пожалуйста!

Давайте оживимся.

Пока что мы не добавили ни одного крутого анимационного эффекта, и наши вкладки все еще довольно скучные. Хорошая новость в том, что с помощью react-spring это очень упрощается. Давайте добавим код нашей анимации с useSpring, например:

Это должно быть понятно, но вот небольшое пошаговое руководство:

Мы используем обработчик useSpring, чтобы установить набор стилей CSS, которые переключаются в зависимости от того, является ли наша переменная tabsExpanded истинной или ложной.

Например, вы видите эту строку marginTop: tabsExpanded ? 0 : -60? Это линия, которая заставляет наши вкладки двигаться вверх и вниз. Код говорит:

  • «ЕСЛИ tabsExpanded истина, то верхняя позиция компонента - 0 пикселей (развернутая),
  • «Или ИНАЧЕ верхняя позиция -60 пикселей».

Также обратите внимание на строку с надписью fontSize: tabsExpanded ? "1em": "0em". Это тот, который заставляет наш заголовок анимироваться от большого к маленькому.

Вы можете добавить больше стилей, которые хотите оживить. В моем случае другие анимации, которые мне нужны, - это цвет шрифта и изменение цвета фона контейнера вкладок.

Вот и все, все остальное сделает react-spring! (реакция-весна… так здорово)

Прикрепите наши функции анимации к вкладкам.

Мы почти там! Во-первых, краткий обзор того, чего мы уже достигли:

  1. Мы создали компонент "Вкладки" многократного использования.
  2. Мы настроили наш код для отслеживания жестов смахивания вверх / вниз.
  3. Мы настраиваем стили, которые хотим анимировать, когда пользователи проводят пальцем по экрану.

Теперь нам просто нужно соединить все это вместе, прикрепив наше событие жеста и анимацию к нашим вкладкам. Мы сделаем это, обновив разметку в нашем return() заявлении.

Мы делаем здесь несколько вещей. Во-первых, мы обновляем divs, чтобы пометить их как "анимированные" с помощью <animated.div />. Делая это, мы просто даем response-spring знать, что это divs, на которые следует обратить внимание.

Что еще интереснее, вы увидите, что мы добавили {...bind()} в родительский / контейнер div. Здесь мы прикрепляем нашу bind функцию, которую мы создали выше, с событием onDrag и обработчиком useGesture. Это настраивает наш контейнер div, чтобы он отслеживал, когда пользователи проводят пальцем вверх или вниз для запуска анимации.

Чуть ниже мы добавили style={tabStyle} в контейнер вкладок, ссылаясь на tabStyle функцию, которую мы создали выше, выполняя анимацию, которую мы хотим запускать, когда пользователи проводят пальцем вверх или вниз.

Вот весь код.

Чтобы получить всего 64 строки кода, пришлось много писать! Вот как теперь может выглядеть ваш последний компонент Tabs:

CSS, чтобы заставить его работать

CSS, который я использую, субъективен. В моем случае у меня были очень конкретные требования к UX и взаимодействию для этого приложения.

Ключевой вывод заключается в том, что .tab-container будет анимироваться вверх (сворачиваться), когда пользователь проводит пальцем вверх, и анимироваться вниз, когда пользователь проводит пальцем вниз. Я выбрал хакерское решение flexbox, но его эффективность может варьироваться в зависимости от потребностей вашего пользовательского интерфейса.

Теперь, если вы запустите код на сенсорном устройстве, вы сможете смахивать вверх или вниз и с удовольствием наблюдать за анимацией вкладок.

Это все хорошо, но как насчет более крупных устройств и настольных браузеров?

Очевидно, что нам не нужно, и мы не хотим, чтобы наши вкладки сворачивались, когда кто-то посещает наш PWA с большого устройства, такого как браузер планшета или настольного компьютера. Скорее, мы хотим, чтобы страница прокручивалась интуитивно, как и любой другой веб-сайт, чтобы наши пользователи получали ожидаемое поведение. Хорошо для нас, для этого есть действительно простое решение:

Теперь на больших устройствах и в настольных браузерах ваш сайт будет прокручиваться в соответствии с ожиданиями пользователей. Идеально!

Как использовать это в своем приложении

Теперь, когда у нас есть многоразовый компонент Tabs - наряду с отслеживанием жестов и классной анимацией - мы можем поместить его в любой компонент или приложение, когда захотим!

Закрытие, спасибо,

Для чтения до конца страницы. Надеюсь, вам понравился UX / Code-ing, чтобы создать довольно крутой компонент React!

Мне бы хотелось услышать ваши вопросы, откровения и оскорбления, так что не стесняйтесь обращаться к нам.

Также получите код на GitHub.