🚀 Быстрый совет по Svelte: использование «действий» для интеграции с библиотеками JavaScript (подсказки Tippy)

Эта статья изначально была опубликована на моей странице Dev.to

👋 Привет, мир!

Одна из суперспособностей Svelte заключается в том, насколько чертовски легко интегрировать его с библиотеками JavaScript, отличными от Svelte, с помощью «действий».

Действия позволяют придавать элементам всевозможное интересное поведение с возможностью повторного использования без необходимости написания пользовательских компонентов Svelte. Они довольно аккуратные! 🤓

В этом посте мы узнаем, как использовать библиотеку всплывающих подсказок на простом JavaScript Tippy.js в вашем проекте Svelte с помощью пользовательского действия Svelte.

Я думаю, вы будете очень впечатлены тем, насколько это просто, особенно по сравнению с такими фреймворками, как React.

Поехали! 👇

Нетерпеливы? Оформите заказ Svelte REPL здесь

Кнопка

Допустим, у нас есть кнопка с атрибутом title, к которой мы хотим добавить всплывающую подсказку:

<button title="hello world">Hover me</button>

Теперь вместо того, чтобы делать что-то вроде создания компонента <Tooltip>, в который мы должны обернуть наши компоненты, давайте воспользуемся преимуществами действий!

Действие

Чтобы написать наше действие, мы будем использовать потрясающую библиотеку всплывающих подсказок на JavaScript Tippy.js, а не писать собственную библиотеку всплывающих подсказок (чего вы, вероятно, не захотите делать!).

Действие довольно простое и включает в себя только определение того, что показывать во всплывающей подсказке, создание экземпляра Tippy, присоединение его к элементу node, передачу ему некоторых реквизитов, а затем очистку при отключении от DOM:

// tooltip.js
module.exports = function tooltip(node, params = {}) {
  // Determine the title to show. We want to prefer
  //    the custom content passed in first, then the
  // HTML title attribute then the aria-label
  // in that order.
  const custom = params.content;
  const title = node.title;
  const label = node.getAttribute("aria-label");
  const content = custom || title || label;
  // Let's make sure the "aria-label" attribute
  // is set so our element is accessible:
  // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute
  if (!label) node.setAttribute("aria-label", content);
  // Clear out the HTML title attribute since
  // we don't want the default behavior of it
  // showing up on hover.
  node.title = "";
  // Support any of the Tippy props by forwarding all "params":
  // https://atomiks.github.io/tippyjs/v6/all-props/
  const tip = tippy(node, { content, ...params });
  return {
    // If the props change, let's update the Tippy instance:
    update: (newParams) => tip.setProps({ content, ...params }),
    // Clean up the Tippy instance on unmount:
    destroy: () => tip.destroy(),
  };
};

Не знаю, как вам, а мне кажется, что это очень круто! 🤯 🤩

Давайте пройдемся по этому:

Во-первых, мы определяем текст, который будет отображаться во всплывающей подсказке. В этом случае мы хотим сначала отдать предпочтение пользовательскому контенту, затем title, а затем aria-label, чтобы мы разумно относились к значению и допускали разумные значения по умолчанию. Затем мы устанавливаем атрибут aria-label, если он не установлен (выиграет автоматическая доступность! 🎉). Мы также очищаем поле title, чтобы оно не отображало поведение браузера по умолчанию, когда заголовок отображается при наведении.

Затем мы вызываем tippy(...) с текущим узлом. Текущее значение node — это то, что получит ваше действие, когда оно будет прикреплено к элементу. Второй аргумент — это любые параметры, которые мы хотим передать действию. В этом случае мы используем параметры, чтобы позволить нам передавать любые параметры, которые мы хотим, непосредственно в Типпи.

Мы присвоили экземпляру Tippy переменную, которую используем для обновления свойств Tippy, если они изменяются в update, и для безопасного удаления экземпляра Tippy, если компонент размонтирован, чтобы предотвратить утечку памяти, в destroy.

Вот и все!

Теперь давайте воспользуемся нашим новым изящным экшеном tooltip! 💃

Собираем это вместе

Импортировать действие

Во-первых, нам нужно импортировать действие tooltip в наш компонент Svelte:

<!--
App.svelte or whatever other component you want 
to use the tooltip in!
-->
<script>
  import tooltip from "./tooltip";
</script>

Включить Типпи CSS/JS

Теперь нам нужно импортировать код Tippy JS и CSS. Поскольку этот пример был создан для Svelte REPL, мы используем для этого CDN, но вы, вероятно, захотите вместо этого объединить эти активы в процесс сборки (что выходит за рамки этой статьи, см. Документацию Tippy) .

<svelte:head>
  <script src="https://unpkg.com/@popperjs/core@2"></script>
  <script src="https://unpkg.com/tippy.js@6"></script>
  <link rel="stylesheet" href="https://unpkg.com/tippy.js@6/themes/light.css" />
  <link
    rel="stylesheet"
    href="https://unpkg.com/tippy.js@6/themes/light-border.css"
  />
</svelte:head>

Используйте свое действие!

Использовать наше новое действие tooltip довольно просто, все, что нам нужно сделать, это применить директиву use: к любому элементу, и теперь у нас есть всплывающая подсказка:

<button use:tooltip title="hello world">Hover Me!</button>

Круто да!?

Теперь мы также можем передавать пользовательские реквизиты Типпи, если захотим:

<!-- using aria-label: -->
<button use:tooltip aria-label="Aria label!">
  With "aria-label"
</button>
<!-- custom tooltip content: -->
<button use:tooltip={{ content: "Hi there!" }}>
  Custom tooltip
</button>
<!-- setting a tooltip theme: -->
<button use:tooltip={{ theme: "light" }} title="Light theme!">
  Light theme
</button>

🛰 Идем дальше

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

На самом деле, я думаю, что этот код настолько прост, что его, вероятно, не стоит упаковывать в пакет npm, но если вы считаете, что стоит, дайте мне знать 🙏.

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

🎬 Плавник

Я думаю, что эта функция Svelte невероятно привлекательна, потому что она упрощает интеграцию с широким миром библиотек JavaScript, не привязывая вас напрямую к фреймворку, что в таких фреймворках, как React, не так просто.

За 6 с лишним лет использования React я обнаружил, что часто не использую обширную вселенную библиотек JS, которые работают напрямую с DOM, потому что это в некотором роде анти-шаблон в мире React. Кроме того, попытка интегрировать такие библиотеки в React часто более сложна и ненадежна.

Что Svelte дает нам здесь, так это возможность использовать всю экосистему невероятных JS-библиотек, которые многие из нас (по крайней мере, в мире React) склонны игнорировать. Черт, вы даже можете использовать библиотеки jQuery, если хотите 🙀!

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

И если вы еще не пишете приложения #svelte, подумайте о прыжках в бассейн, вода теплая! 🏖 🏊 🍻

Спасибо за чтение! Поставьте этому сообщению ❤️, 🦄 или 🔖, чтобы добавить его в закладки на будущее. 💕

Есть другие советы, идеи, отзывы или исправления? Дайте мне знать в комментариях! 🙋‍♂️

Не забудьте подписаться на меня на Dev.to (danawoodman), Twitter (@danawoodman) и/или Github (danawoodman)!

Фото автора Joshua Aragon на Unsplash