Logotipo de Zephyrnet

Creación de widgets interactivos de Figma

Fecha:

Figma siempre ha fomentado la colaboración entre desarrolladores y diseñadores. Se esfuerza en un tesoro interminable de complementos creados por la comunidad. ¿Necesita elementos 3D? Hay un complemento para eso. ¿Necesita SVG abstractos? Hay un complemento para eso también.

Dicho esto, la parte de diseño de Figma siempre ha sido relativamente estática, siempre trabajando con rectángulos inamovibles conectados entre sí a través de interacciones de usuario predefinidas. Pero, ¿y si te dijera que tus diseños podrían cobrar vida de repente, que podrían ser animados, interactivos e incluso con estado? Entonces, ¿qué separaría el concepto de la implementación?

Figma anunciado en junio que está trayendo widgets basados ​​en JavaScript a la mesa. ¡Ahora, los diseñadores pueden buscar e implementar componentes basados ​​en lógica directamente en Figma!

Da la bienvenida a la API de widgets! ¿Quieres saber qué es y cómo usarlo? Eso es exactamente lo que vamos a hacer juntos en este post.

Los widgets de Figma abren toneladas de posibilidades

Imagine que está trabajando día y noche con su socio para diseñar una gran aplicación para restaurantes. Ambos ya están colaborando en el mismo tablero de Figma; ambos están compartiendo exactamente el mismo documento con cambios que ocurren sobre la marcha.

Seguramente, ya sabes que la colaboración implica más que solo el proceso de diseño:

  • gestión de proyectos,
  • organizar encuestas para reunir votos,
  • importar y visualizar datos simulados,
  • y tal vez incluso jugar un juego multijugador para refrescarse después de muchas horas de trabajo.

Solo necesitamos una persona para administrar todo y enviar enlaces a otros miembros del grupo. Pero, oh, eso no es muy eficiente, ¿verdad?

Bueno, ahí es donde entran en juego los widgets. Es posible que podamos hacer todo eso, sí, todo, sin tener que salir de Figma.

Estas son solo algunas de las formas en que podría querer usar widgets en Figma:

la lista va nosotros y nosotros. Como puede ver, ya hay una gran cantidad de widgets que puede usar libremente en sus documentos. De hecho, puede agregar Widgets directamente a su tablero desde el menú Widgets (Shift+I).

Pero no estamos aquí para aprender a usar widgets, porque eso es fácil. Hagamos lo que mejor sabemos hacer: ¡vamos a crear nuestro propio widget de Figma! Este estará inspirado en Sitio web de citas de diseño de Chris Coyier. Tomaremos la API, la introduciremos en el widget y luego mostraremos citas de diseño aleatorias directamente en Figma.

Esto es lo que necesitamos

No me gusta ser el portador de malas noticias, pero para poder desarrollar widgets, debes estar en Windows o Mac. Usuarios de Linux, lo siento, pero no tienen suerte. (Todavía podrías usar una máquina virtual si quieres seguir adelante.)

Nosotros vamos a descargar Figma Desktop solicitud. La forma más sencilla de comenzar es generar una plantilla de widget, directamente desde la aplicación.

Vamos a crear un nuevo tablero abriendo el menú de widgets (ShiftI), cambiando a la Desarrollo pestaña y creando un nuevo elemento.

Después de eso, Figma le pedirá que nombre el nuevo widget y decida si está más adaptado a tableros de diseño o tableros FigJam también. La primera opción es suficiente para los efectos de este artículo.

Y la personalización no termina aquí; Figma también le dará la opción de comenzar con un widget de contador prefabricado o una alternativa habilitada para iFrame que también le brinda acceso a las API Canvas y Fetch (así como a todas las demás API del navegador). Iremos con la opción simple "Vacío", pero eventualmente la modificaremos nosotros mismos para hacer uso de la API Fetch.

Luego se le pedirá que guarde su nuevo proyecto de widget en un directorio especial en su sistema. Una vez hecho esto, inicie su terminal y diríjalo a esa carpeta. No ejecute ningún comando todavía; lo haremos más tarde y obtendremos un error a propósito con el objetivo de obtener más información sobre la API de Widgets.

Diseñando el widget

Estamos sacando el diseño directamente de Sitio web de citas de diseño de Chris Coyier. Entonces, vayamos allí y profundicemos activando DevTools.

Los dos atajos de teclado que estoy usando aquí son Ctrl+Shift+C (o Cmd+Shift+C) para alternar la herramienta "Elegir elemento", y Shift+Click para cambiar el formato de color a código HEX. Estamos haciendo esto para obtener información sobre los colores, las fuentes, los pesos de las fuentes y los tamaños de las fuentes que se utilizan en el sitio web de Chris. Toda esta información es fundamental para crear un widget muy parecido a Figma, ¡que será nuestro próximo paso! Puedes agarrar el componente diseñado y úsalo en tu propio lienzo.

No entraré en muchos detalles aquí, ya que el tema principal de este artículo es crear widgets escribiendo código. Pero no puedo enfatizar lo suficiente lo importante que es cuidar bien de su estilo de widgets… CSS-Tricks ya tiene una plétora de tutoriales de Figma orientados al diseño; no te arrepentirás de agregarlos a tu lista de lectura.

Creando el diseño para nuestro widget

Con el diseño fuera del camino, es hora de sacar nuestros dedos de programación y comenzar a construir los engranajes de nuestro widget.

Es muy interesante cómo Figma traduce sus componentes básicos de diseño en componentes similares a React. Los elementos del marco con la función de diseño automático, por ejemplo, se representan como el  componente en el código. Además de eso, usaremos dos componentes más:  y .

Echa un vistazo a mi tablero de Figma… Precisamente te pido que te concentres en el árbol de objetos. Es lo que necesitamos para poder traducir el diseño de nuestro widget a código JSX.

Como puede ver, nuestro widget de cotizaciones de diseño exige que se importen tres componentes. Esa es una cantidad decente de componentes considerando que el API completa solo contiene ocho nodos basados ​​en capas. Pero como pronto verá, estos módulos son más que suficientes para crear todo tipo de diseños.

// code.tsx
const { widget } = figma;
const { AutoLayout, Text, SVG } = widget;

Y con esto, tenemos todo lo que necesitamos para seguir adelante y construir el esqueleto de nuestro widget como lo haríamos en React:

function QuotesWidget() {
  const quote = `...`;
  const author = `...`;

  return (
    
      
      
        {quote}
        — {author}
      
      
    
  );
}

widget.register(QuotesWidget);

Este código es muy confuso, por decir lo menos. En este momento, no podemos diferenciar las capas de diseño. Afortunadamente, podemos resolver este problema fácilmente mediante el uso de la name propiedad.


  
  
    {quote}
    — {author}
  
  
;

Y, por supuesto, todavía no podemos ver nuestros SVG de comillas, así que trabajemos para solucionarlo. los  componente aceptar un srcpropiedad que toma el código fuente de un elemento SVG. No hay mucho que decir sobre esto, así que hagámoslo simple y regresemos directamente al código:

const leftQuotationSvgSrc = `<svg width="117" height="103" viewBox="0 0 117 103" fill="none" xmlns="">
  // shortened for brevity
`;
const rightQuotationSvgSrc = `<svg width="118" height="103" viewBox="0 0 118 103" fill="none" xmlns="">
// shortened for brevity
`;

function QuotesWidget() {
  return (
    
    
  );
}

¡Creo que todos podemos estar de acuerdo en que todo está mucho más claro ahora! Cuando nombramos cosas, su propósito de repente se vuelve mucho más obvio para los lectores de nuestro código.

Vista previa de nuestro widget en tiempo real

Figma ofrece una excelente experiencia de desarrollador al crear widgets, incluidos (entre otros) recarga en caliente. Con esta función, podemos codificar y obtener una vista previa de los cambios en nuestro widget en tiempo real.

Comience abriendo el menú de widgets (Shift+I), cambiando a la pestaña de desarrollo y haciendo clic o arrastrando su nuevo widget al tablero. ¿No puede localizar su widget? No se preocupe, simplemente haga clic en el menú de tres puntos e importe los widgets manifest.json expediente. ¡Sí, eso es todo lo que se necesita para devolverlo a la existencia!

Espera, ¿recibiste un mensaje de error en la parte inferior de la pantalla?

Si es así, investiguemos. Haga clic en "Consola abierta” y lea lo que tiene que decir. Si el Consola abierta el botón se ha ido, hay una forma alternativa de abrir la consola de depuración. Haga clic en el logotipo de Figma, salte a la categoría de widgets y revele el menú de desarrollo.

Es probable que ese error se deba al hecho de que aún no hemos compilado nuestro TypeScript a JavaScript. Podemos hacer eso en la línea de comando ejecutando npm install y npm run watch. (o yarn y yarn watch ). ¡Sin errores esta vez!

Un obstáculo más que podría encontrar es que el widget no se vuelve a renderizar cada vez que se cambia el código. Podemos forzar fácilmente nuestro widget para que se actualice usando el siguiente comando del menú contextual: Widgets → Widget de volver a renderizar.

Aplicar estilo al widget

En su forma actual, el miradas de nuestros widgets todavía están bastante lejos de nuestro objetivo final.

Entonces, ¿cómo diseñamos los componentes de Figma a partir del código? ¿Quizás con CSS como lo haríamos en un proyecto React? Negativo. Con widgets Figma, todos el estilo pasa a través de un conjunto de accesorios bien documentados. Por suerte para nosotros, estos artículos se nombran casi idénticamente a sus contrapartes en Figma.

Comenzaremos configurando nuestros dos  componentes Como puede ver en la infografía anterior, los nombres de los accesorios son bastante descriptivos de su propósito. Esto nos facilita saltar directamente al código y comenzar a hacer algunos cambios. No volveré a mostrar el código completo, así que confíe en los nombres de los componentes para guiarlo a dónde pertenecen los fragmentos.


  
;

¡Acabamos de progresar mucho! Guardemos y regresemos a Figma para ver cómo se ve nuestro widget. ¿Recuerdas cómo Figma recarga los widgets automáticamente con los nuevos cambios?

Pero aún no ha llegado. También debemos agregar un color de fondo al componente raíz:

Nuevamente, eche un vistazo a su tablero de Figma y observe cómo los cambios se pueden reflejar casi inmediatamente en el widget.

Avancemos a lo largo de esta guía y diseñemos el  componentes.

Después de echar un vistazo al Documentación de la API de widgets, nuevamente está claro que los nombres de las propiedades son casi idénticos a sus contrapartes en la aplicación Figma, como se puede ver en la infografía anterior. También usaremos valores de la última sección donde inspeccionamos el sitio web de Chris.

{quote}

— {author}

Agregar estado al widget

Nuestro widget actualmente muestra la misma cotización, pero queremos extraer de todo el grupo de cotizaciones al azar. debemos agregar estado a nuestro widget, que todos los desarrolladores de React saben que es una variable cuyo cambio activa la nueva representación de nuestro componente.

Con Figma, el estado se crea con el useSyncedState gancho; es bastante Reaccionar useState, pero requiere que los programadores especifiquen una clave única. Este requisito surge del hecho de que Figma debe sincronizar el estado de nuestro widget en todos clientes que pueden estar viendo el mismo tablero de diseño, pero a través de diferentes computadoras.

const { useSyncedState } = widget;

function QuotesWidget() {
  const [quote, setQuote] = useSyncedState("quote-text", "");
  const [author, setAuthor] = useSyncedState("quote-author", "");
}

Ese es todo el cambio que necesitamos por ahora. En la siguiente sección, descubriremos cómo obtener datos de Internet. Alerta de spoiler: no es tan simple como parece.

Obtener datos de la red

Recuerde cuando Figma nos dio la opción de comenzar con un widget habilitado para iFrame. Aunque no elegimos esa opción, aún debemos implementar algunas de sus características. Déjame explicarte por qué no podemos simplemente llamar fetch() dentro de nuestro código de widget.

Cuando usa un widget, está ejecutando código JavaScript en su propia computadora que está escrito por otra persona. Si bien el personal de Figma revisa minuciosamente todos los widgets, sigue siendo un gran agujero de seguridad, ya que todos sabemos cuánto el daño puede ser creado por incluso una línea de JavaScript.

Como resultado, Figma no puede simplemente eval() cualquier código de widget escrito por programadores anónimos. Para resumir, el equipo decidió que la mejor solución era ejecutar código de terceros en un entorno de espacio aislado estrechamente protegido. Y como habrás adivinado, las API del navegador no están disponibles en dicho entorno.

Pero no se preocupe, la solución de Figma a este segundo problema es s. Cualquier código HTML que escribamos en un archivo, preferiblemente llamado ui.html, tendrá acceso a todas las API del navegador. Quizás se pregunte cómo podemos activar este código desde el widget, pero lo veremos más adelante. En este momento, volvamos al código:

// manifest.json
{
  "ui": "ui.html"
}


window.onmessage = async (event) => {
  if (event.data.pluginMessage.type === 'networkRequest') {
    // TODO: fetch data from the server

    window.parent.postMessage({
      pluginMessage: {
        // TODO: return fetched data
      }
    }, '*')
  }
}

Esa es la plantilla general para widget-to-iframe comunicación. Usémoslo para obtener datos del servidor:



window.onmessage = async (event) => {
  if (event.data.pluginMessage.type === 'networkRequest') {
    // Get random number from 0 to 100
    const randomPage = Math.round(Math.random() * 100)

    // Get a random quote from the Design Quotes API
    const res = await fetch(`https://quotesondesign.com/wp-json/wp/v2/posts/?orderby=rand&per_page=1&page=${randomPage}&_fields=title,yoast_head_json`)
    const data = await res.json()

    // Extract author name and quote content from response
    const authorName = data[0].title.rendered
    const quoteContent = data[0].yoast_head_json.og_description

    window.parent.postMessage({
      pluginMessage: {
        authorName,
        quoteContent
      }
    }, '*')
  }
}

Estamos omitiendo el manejo de errores para mantener esto simple y directo. Volvamos al código del widget y veamos cómo accedemos a las funciones definidas en el :

function fetchData() {
  return new Promise(resolve => {
    figma.showUI(__html__, {visible: false})
    figma.ui.postMessage({type: 'networkRequest'})

    figma.ui.onmessage = async ({authorName, quoteContent}) => {
      setAuthor(authorName)
      setQuote(quoteContent)

      resolve()
    }
  })
}

Como puede ver, primero le estamos diciendo a Figma que exponga el acceso a nuestro oculto  y para desencadenar un evento con el nombre "networkRequest". Estamos manejando este evento en el ui.html archivo comprobando event.data.pluginMessage.type === 'networkRequest', y luego publicar datos en el widget.

Pero nada está pasando todavía... Todavía no hemos llamado al fetchData() función. Si lo llamamos directamente en la función del componente, en la consola se presenta el siguiente error:

Cannot use showUI during widget rendering.

Figma nos dice que no llamemos showUI directamente en el cuerpo de la función… Entonces, ¿dónde deberíamos ponerlo? La respuesta a eso es un nuevo gancho y una nueva función: useEffect y waitForTask. Es posible que ya esté familiarizado con useEffect si es un desarrollador de React, pero lo usaremos aquí para obtener datos del servidor cuando se monte el componente del widget.

const { useEffect, waitForTask } = widget;

function QuotesWidget() {
  useEffect(() => {
    waitForTask(fetchData());
  });
}

Pero esto dará como resultado otro "error" en el que nuestro widget se volverá a representar con una nueva cotización, para siempre. Esto sucede porque useEffect, por definición, se activa de nuevo cada vez que cambia el estado del widget, no cuando llamamos fetchData. Y mientras hay una tecnica solo llamar useEffect una vez en React, no funciona en la implementación de Figma. De los documentos de Figma:

Debido a cómo funcionan los widgets, useEffect debe manejar ser llamado varias veces con el mismo estado.

Afortunadamente, hay una solución simple que podemos aprovechar y llamar useEffect solo una vez cuando el componente se monta por primera vez, y es verificando si los valores del estado todavía están vacíos o no:

function QuotesWidget() {
  useEffect(() => {
    if (!author.length & !quote.length) {
      waitForTask(fetchData());
    }
  });
}

Es posible que te encuentres con un aterrador "acceso a la memoria fuera de los límites” error. Es bastante común de ver en el desarrollo de complementos y widgets. Simplemente reinicie Figma y ya no estará allí.

Es posible que haya notado que, a veces, el texto de la cita contiene caracteres extraños.

Estos son procesos Caracteres Unicode y debemos formatearlas correctamente en código:



window.onmessage = async (event) => {
  // ...
  const quoteContent = decodeEntities(data[0].yoast_head_json.og_description);
};

// 
var decodeEntities = (function () {
  // this prevents any overhead from creating the object each time
  var element = document.createElement("div");

  function decodeHTMLEntities(str) {
    if (str && typeof str === "string") {
      // strip script/html tags
      str = str.replace(/]*>([Ss]*?)/gim, "");
      str = str.replace(/]|"[^"]*"|'[^']*')*>/gim, "");
      element.innerHTML = str;
      str = element.textContent;
      element.textContent = "";
    }

    return str;
  }

  return decodeHTMLEntities;
})();

Y  voilá, nuestro widget obtuvo una nueva cotización de diseño cada vez que se agrega al tablero de diseño.

Agregar un menú de propiedades a nuestro widget

Si bien nuestro widget obtiene una nueva cotización al crear una instancia, sería mucho más práctico si pudiéramos realizar este proceso nuevamente pero sin eliminarlo. Esta sección será corta ya que la solución es bastante notable. Con menús de propiedades, podemos agregar interactividad a nuestro widget con una sola llamada al usePropertyMenu gancho.

Créditos: Documentos de Figma.
const { usePropertyMenu } = widget;

function QuotesWidget() {
  usePropertyMenu(
    [
      {
        itemType: "action",
        propertyName: "generate",
	tooltip: "Generate",
        icon: `<svg width="22" height="15" viewBox="0 0 22 15" fill="none" xmlns="">
          
        `,
      },
    ],
    () => fetchData()
  );
}

Con un simple enlace, podemos crear un botón que aparece cerca de nuestro widget cuando está seleccionado. Esa fue la última pieza que necesitábamos agregar para completar este proyecto.

Publicando nuestro widget al público

No sirve de mucho construir un widget si, bueno, nadie usos eso. Y mientras Figma otorga a las organizaciones la opción de lanzar privada widgets para uso interno, es mucho más común lanzar estos pequeños programas al mundo.

Figma tiene un delicado proceso de revisión de widgets que puede demorar de 5 a 10 días hábiles. Y aunque el widget de cotizaciones de diseño que construimos juntos es ya en la biblioteca de widgets, Todavía demostraré cómo llegó allí. No intente volver a publicar este widget nuevamente, ya que eso solo resultará en la eliminación.. Pero si le hiciste algunas modificaciones significativas, ¡adelante, comparte tu propio widget con la comunidad!

Comience haciendo clic en el menú de widgets (Shift+I) y cambiando a la Desarrollo pestaña para ver nuestro widget. Haga clic en el menú de tres puntos y presione Publicar.

Figma le pedirá que ingrese algunos detalles sobre su widget, como un título, una descripción y algunas etiquetas. También necesitaremos una imagen de icono de 128 × 128 y una imagen de banner de 1920 × 960.

Después de importar todos estos activos, todavía necesitamos una captura de pantalla de nuestro widget. Cierre el modal de publicación (no se preocupe, no perderá sus datos) y haga clic con el botón derecho en el widget para revelar un menú contextual interesante. Encuentra el Copiar/Pegar comocategoría y seleccione Copiar como PNG.

Una vez hecho esto, volvamos al modo de publicación y peguemos la captura de pantalla del widget:

Desplácese hacia abajo y finalmente publique su modal. ¡Celebrar! 🎉

Figma se comunicará con usted en un par de días sobre el estado de la revisión de su modal. En el caso de un rechazo, se le dará la oportunidad de hacer cambios y enviar de nuevo.

Conclusión

¡Acabamos de crear un widget de Figma desde cero! Hay muchas cosas que no se tratan aquí, como haga clic en eventosformularios de entradamucho más. Puede profundizar en el código fuente completo del widget en este repositorio de GitHub.

A aquellos que aspiren a llevar sus habilidades con Figma a niveles superiores, les sugiero explorar la comunidad de Widgets y usar lo que les llame la atención como inspiración. Siga creando más widgets, siga perfeccionando sus habilidades de React y, antes de que se dé cuenta, me estará enseñando cómo hacer todo esto.

Recursos adicionales

Tuve que consultar mucha documentación mientras hacía este widget. Pensé en compartir lo que encontré para ayudar más.

Cree más widgets:

Aprenda los widgets con mayor profundidad:

Widgets frente a complementos

punto_img

Información más reciente

punto_img

Habla con nosotros!

¡Hola! ¿Le puedo ayudar en algo?