Figma ha sempre incoraggiato la collaborazione tra sviluppatori e designer. Si impegna su un tesoro infinito di plugin creati dalla comunità. Hai bisogno di elementi 3D? C'è un plugin per questo. Hai bisogno di SVG astratti? C'è un plugin per questo, Anche.
Detto questo, la parte progettuale di Figma è sempre stata relativamente statica, lavorando sempre con rettangoli immobili collegati tra loro tramite interazioni utente predefinite. Ma cosa succederebbe se ti dicessi che i tuoi progetti potrebbero improvvisamente prendere vita, che potrebbero essere animati, interattivi e persino con stato? Allora, cosa separerebbe il concetto dall’implementazione?
Figma annunciato a giugno che sta portando sul tavolo widget basati su JavaScript. Ora, i progettisti possono sfogliare e implementare componenti guidati dalla logica direttamente in Figma!
Ciao a dire l'API dei widget! Vuoi sapere cos'è e come usarlo? Questo è esattamente ciò che faremo insieme in questo post.
I widget Figma aprono tantissime possibilità
Immagina di lavorare 24 ore su 24 con il tuo partner per progettare un'applicazione per un ristorante di grandi dimensioni. State già collaborando entrambi alla stessa bacheca Figma; entrambi condividete esattamente lo stesso documento con modifiche che avvengono al volo.
Sicuramente sai già che la collaborazione implica qualcosa di più del semplice processo di progettazione:
- gestione di progetto,
- ospitare sondaggi per raccogliere voti,
- importare e visualizzare dati simulati,
- e magari anche giocare a un gioco multiplayer per rinfrescarsi dopo molte ore di lavoro.
Richiediamo solo che una persona gestisca tutto e invii collegamenti ad altri membri del gruppo. Ma oh, non è molto efficiente, vero?
Bene, è qui che entrano in gioco i widget. Possiamo plausibilmente fare tutto questo - sì, tutto - senza mai lasciare Figma.
Ecco solo alcuni dei modi in cui potresti voler utilizzare i widget in Figma:
L'elenco continua ancora e ancora. Come puoi vedere, c'è già una miriade di widget che puoi utilizzare liberamente nei tuoi documenti. Infatti, puoi aggiungere widget direttamente alla tua bacheca dal menu Widget (Shift
+I
).
Ma non siamo qui per imparare come usare i widget, perché è facile. Facciamo quello che sappiamo fare meglio: creeremo il nostro widget Figma! Questo sarà ispirato da Il sito web delle citazioni di design di Chris Coyier. Prenderemo l'API, la inseriremo nel widget, quindi visualizzeremo citazioni di design casuali direttamente in Figma.
Ecco cosa ci serve
Non mi piace essere portatore di cattive notizie, ma per sviluppare widget devi essere su Windows o Mac. Utenti Linux, mi dispiace, ma siete sfortunati. (Potresti ancora utilizzare una VM se vuoi seguirmi.)
Lo faremo scarica il desktop Figma applicazione. Il modo più semplice per iniziare è generare un modello di widget direttamente dall'app.
Creiamo una nuova bacheca aprendo il menu widget (Shift
+ I
), passando a Mercato scheda e creando un nuovo elemento.
Successivamente, Figma ti chiederà di nominare il nuovo widget e decidere se è più adatto schede di progettazione o schede FigJam pure. Ai fini del presente articolo è sufficiente la prima opzione.
E la personalizzazione non finisce qui; Figma ti darà anche la possibilità di iniziare con un widget contatore predefinito o un'alternativa abilitata per iFrame che ti dà anche accesso alle API Canvas e Fetch (così come a tutte le altre API del browser). Utilizzeremo la semplice opzione "Vuoto", ma alla fine la modificheremo noi stessi per utilizzare l'API Fetch.
Ti verrà quindi richiesto di salvare il tuo nuovo progetto widget in una directory speciale nel tuo sistema. Una volta fatto, avvia il tuo terminale e indirizzalo a quella cartella. Non eseguire ancora alcun comando: lo faremo più tardi e riceveremo intenzionalmente un errore con l'obiettivo di saperne di più sull'API Widget.
Progettare il widget
Stiamo estraendo il design direttamente da Il sito web delle citazioni di design di Chris Coyier. Quindi, andiamo lì e tuffiamoci avviando DevTools.
Le due scorciatoie da tastiera che sto usando qui sono Ctrl
+Shift
+C
(o Cmd
+Shift
+C
) per attivare/disattivare lo strumento “Seleziona elemento” e Shift
+Click
per modificare il formato del colore in codice HEX. Lo stiamo facendo per conoscere i colori, i caratteri, i pesi e le dimensioni dei caratteri utilizzati nel sito web di Chris. Tutte queste informazioni sono fondamentali per costruire un widget molto simile in Figma, che sarà il nostro prossimo passo! Puoi prendi il componente progettato e usalo nella tua tela.
Non entrerò nei dettagli qui poiché l'argomento principale di questo articolo è la creazione di widget scrivendo codice. Ma non posso sottolineare abbastanza quanto sia importante prendersi cura di te lo stile dei widget… CSS-Tricks ne ha già moltissimi tutorial Figma orientati al design; non ti pentirai di averli aggiunti alla tua lista di lettura.
Creazione del layout per il nostro widget
Con la progettazione fuori mano, è tempo di togliere le dita dalla programmazione e iniziare a costruire gli ingranaggi del nostro widget.
È molto interessante il modo in cui Figma traduce i suoi elementi costitutivi del design in componenti simili a React. Gli elementi frame con la funzione di layout automatico, ad esempio, sono rappresentati come <AutoLayout />
componente nel codice. Oltre a ciò, utilizzeremo altri due componenti: <Text />
ed <SVG />.
Dai un'occhiata alla mia tavola Figma…ti chiedo proprio di concentrarti sull’albero degli oggetti. È ciò di cui abbiamo bisogno per poter tradurre il design del nostro widget in codice JSX.
Come puoi vedere, il nostro widget dei preventivi di progettazione richiede l'importazione di tre componenti. Si tratta di un numero decente di componenti considerando che il API completa contiene solo otto nodi basati su livelli. Ma come vedrai presto, questi moduli sono più che sufficienti per realizzare tutti i tipi di layout.
// code.tsx
const { widget } = figma;
const { AutoLayout, Text, SVG } = widget;
E con questo, abbiamo tutto ciò che ci serve per procedere e costruire lo scheletro del nostro widget come faremmo in React:
function QuotesWidget() {
const quote = `...`;
const author = `...`;
return (
<AutoLayout>
<SVG />
<AutoLayout>
<Text>{quote}</Text>
<Text>— {author}</Text>
</AutoLayout>
<SVG />
</AutoLayout>
);
}
widget.register(QuotesWidget);
Questo codice è a dir poco molto confuso. Al momento, non possiamo distinguere i livelli di progettazione. Per fortuna, siamo in grado di risolvere facilmente questo problema attraverso l'uso di name
proprietà.
<AutoLayout name={"Quote"}>
<SVG name={"LeftQuotationMark"} />
<AutoLayout name={"QuoteContent"}>
<Text name={"QuoteText"}>{quote}</Text>
<Text name={"QuoteAuthor"}>— {author}</Text>
</AutoLayout>
<SVG name={"RightQuotationMark"} />
</AutoLayout>;
E, naturalmente, non riusciamo ancora a vedere i nostri SVG con virgolette, quindi lavoriamo per risolverlo. IL <SVG/>
componente accettare a src
proprietà che accetta il codice sorgente per un elemento SVG. Non c’è molto da dire su questo, quindi manteniamo le cose semplici e torniamo direttamente al codice:
const leftQuotationSvgSrc = `<svg width="117" height="103" viewBox="0 0 117 103" fill="none" xmlns="<http://www.w3.org/2000/svg>">
// shortened for brevity
</svg>`;
const rightQuotationSvgSrc = `<svg width="118" height="103" viewBox="0 0 118 103" fill="none" xmlns="<http://www.w3.org/2000/svg>">
// shortened for brevity
</svg>`;
function QuotesWidget() {
return (
<SVG name={"LeftQuotationMark"} src={leftQuotationSvgSrc} />
<SVG name={"RightQuotationMark"} src={rightQuotationSvgSrc} />
);
}
Penso che siamo tutti d'accordo sul fatto che ora è tutto molto più chiaro! Quando diamo un nome alle cose, il loro scopo diventa improvvisamente molto più ovvio per i lettori del nostro codice.
Anteprima del nostro widget in tempo reale
Figma offre un'ottima esperienza per gli sviluppatori durante la creazione di widget, inclusi (ma non limitati a) ricarica a caldo. Con questa funzione, siamo in grado di codificare e visualizzare in anteprima le modifiche al nostro widget in tempo reale.
Inizia aprendo il menu dei widget (Shift
+I
), passando alla scheda sviluppo e facendo clic o trascinando il nuovo widget sulla scheda. Non riesci a individuare il tuo widget? Non preoccuparti, fai semplicemente clic sul menu a tre punti e importa i tuoi widget manifest.json
file. Sì, basta questo per riportarlo in vita!
Aspetta, hai ricevuto un messaggio di errore nella parte inferiore dello schermo?
Se è così, investighiamo. Clicca su "Consolle aperta" e leggi cosa ha da dire. Se la Consolle aperta non c'è più, c'è un modo alternativo per aprire la console di debug. Fai clic sul logo Figma, passa alla categoria dei widget e rivela il menu di sviluppo.
Questo errore è probabilmente dovuto al fatto che non abbiamo ancora compilato il nostro TypeScript in JavaScript. Possiamo farlo nella riga di comando eseguendo npm install
ed npm run watch
. (o yarn
ed yarn watch
). Nessun errore questa volta!
Un altro ostacolo che potresti incontrare è che il widget non riesce a eseguire nuovamente il rendering ogni volta che il codice viene modificato. Possiamo facilmente forzare l'aggiornamento del nostro widget utilizzando il seguente comando del menu contestuale: widget → Widget di nuovo rendering.
Applicare uno stile al widget
Allo stato attuale, il sguardi dei nostri widget sono ancora piuttosto lontani dal nostro obiettivo finale.
Quindi, come stiliamo i componenti Figma dal codice? Magari con i CSS come faremmo in un progetto React? Negativo. Con i widget Figma, contro tutti i lo styling avviene attraverso una serie di oggetti di scena ben documentati. Fortunatamente per noi, questi articoli hanno un nome quasi identicamente alle loro controparti in Figma.
Inizieremo configurando i nostri due <AutoLayout />
componenti. Come puoi vedere nell'infografica qui sopra, i nomi degli oggetti di scena sono piuttosto descrittivi del loro scopo. Ciò ci consente di passare direttamente al codice e iniziare ad apportare alcune modifiche. Non mostrerò di nuovo l'intero codice, quindi fai affidamento sui nomi dei componenti per guidarti dove appartengono gli snippet.
<AutoLayout
name={"Quote"}
direction={"horizontal"}
verticalAlignItems={"start"}
horizontalAlignItems={"center"}
spacing={54}
padding={{
horizontal: 61,
vertical: 47,
}}
>
<AutoLayout
name={"QuoteContent"}
direction={"vertical"}
verticalAlignItems={"end"}
horizontalAlignItems={"start"}
spacing={10}
padding={{
horizontal: 0,
vertical: 0,
}}
></AutoLayout>
</AutoLayout>;
Abbiamo appena fatto molti progressi! Salviamo e torniamo a Figma per vedere come appare il nostro widget. Ricordi come Figma ricarica automaticamente i widget in caso di nuove modifiche?
Ma non è ancora del tutto arrivato. Dobbiamo anche aggiungere un colore di sfondo al componente root:
<AutoLayout name={"Quote"} fill={"#ffffff"}>
Ancora una volta, dai un'occhiata alla tua scheda Figma e nota come le modifiche possono riflettersi quasi immediatamente nel widget.
Procediamo lungo questa guida e diamo uno stile al <Text>
componenti.
Dopo aver dato un'occhiata al file Documentazione dell'API dei widget, è ancora una volta chiaro che i nomi delle proprietà sono quasi identici alle loro controparti nell'app Figma, come si può vedere nell'infografica sopra. Utilizzeremo anche i valori dell'ultima sezione in cui abbiamo esaminato il sito web di Chris.
<Text name={'QuoteText'}
fontFamily={'Lora'}
fontSize={36}
width={700}
fill={'#545454'}
fontWeight={'normal'}
>{quote}</Text>
<Text name={'QuoteAuthor'}
fontFamily={'Raleway'}
fontSize={26}
width={700}
fill={'#16B6DF'}
fontWeight={'bold'}
textCase={'upper'}
>— {author}</Text>
Aggiunta dello stato al widget
Il nostro widget attualmente mostra la stessa citazione, ma vogliamo estrarre l'intero pool di virgolette in modo casuale. Dobbiamo aggiungere stato al nostro widget, che tutti gli sviluppatori React sanno essere una variabile la cui modifica attiva il re-rendering del nostro componente.
Con Figma lo stato viene creato con il useSyncedState
gancio; è praticamente Reagire useState
, ma richiede ai programmatori di specificare una chiave univoca. Questo requisito deriva dal fatto che Figma deve sincronizzare lo stato del nostro widget contro tutti i client che potrebbero visualizzare la stessa scheda di progettazione, ma tramite computer diversi.
const { useSyncedState } = widget;
function QuotesWidget() {
const [quote, setQuote] = useSyncedState("quote-text", "");
const [author, setAuthor] = useSyncedState("quote-author", "");
}
Questo è tutto il cambiamento di cui abbiamo bisogno per ora. Nella prossima sezione, scopriremo come recuperare dati da Internet. Avviso spoiler: non è così semplice come sembra.
Recupero dati dalla rete
Ricordiamo quando Figma ci ha dato la possibilità di iniziare con un widget abilitato per iFrame. Anche se non abbiamo scelto questa opzione, dobbiamo comunque implementare alcune delle sue funzionalità. Lasciami spiegare perché non possiamo semplicemente chiamare fetch()
all'interno del nostro codice widget.
Quando utilizzi un widget, esegui sul tuo computer un codice JavaScript scritto da qualcun altro. Sebbene tutti i widget siano esaminati attentamente dallo staff di Figma, è ancora un enorme buco di sicurezza poiché sappiamo tutti quanto il danno può essere creato anche da una sola riga di JavaScript.
Di conseguenza, Figma non può semplicemente eval()
qualsiasi codice widget scritto da programmatori anonimi. Per farla breve, il team ha deciso che la soluzione migliore era eseguire codice di terze parti in un ambiente sandbox attentamente protetto. E come avrai intuito, le API del browser non sono disponibili in un ambiente di questo tipo.
Ma non preoccuparti, la soluzione di Figma a questo secondo problema è <iframe>
S. Qualsiasi codice HTML che scriviamo in un file, preferibilmente chiamato ui.html
, avrà accesso a tutte le API del browser. Forse ti starai chiedendo come possiamo attivare questo codice dal widget, ma lo esamineremo più tardi. Adesso torniamo al codice:
// manifest.json
{
"ui": "ui.html"
}
<!-- ui.html -->
<script>
window.onmessage = async (event) => {
if (event.data.pluginMessage.type === 'networkRequest') {
// TODO: fetch data from the server
window.parent.postMessage({
pluginMessage: {
// TODO: return fetched data
}
}, '*')
}
}
</script>
Questo è il modello generale per widget-to-iframe
comunicazione. Usiamolo per recuperare i dati dal server:
<!-- ui.html -->
<script>
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
}
}, '*')
}
}
</script>
Stiamo tralasciando la gestione degli errori per mantenerlo semplice e pertinente. Torniamo al codice del widget e vediamo come accedere alle funzioni definite nel file <iframe>
:
function fetchData() {
return new Promise<void>(resolve => {
figma.showUI(__html__, {visible: false})
figma.ui.postMessage({type: 'networkRequest'})
figma.ui.onmessage = async ({authorName, quoteContent}) => {
setAuthor(authorName)
setQuote(quoteContent)
resolve()
}
})
}
Come puoi vedere, stiamo prima dicendo a Figma di esporre l'accesso al nostro file hidden <iframe>
e per attivare un evento con il nome "networkRequest"
. Stiamo gestendo questo evento nel ui.html
file controllando event.data.pluginMessage.type === 'networkRequest',
e quindi reinserire i dati nel widget.
Ma non è ancora successo nulla... Non abbiamo ancora chiamato il fetchData()
funzione. Se lo chiamiamo direttamente nella funzione componente, nella console si verifica il seguente errore:
Cannot use showUI during widget rendering.
Figma ci sta dicendo di non chiamare showUI
direttamente nel corpo della funzione… Allora dove lo mettiamo? La risposta è un nuovo hook e una nuova funzione: useEffect
ed waitForTask
. Potresti già avere familiarità con useEffect
se sei uno sviluppatore React, ma lo useremo qui per recuperare i dati dal server quando viene montato il componente widget.
const { useEffect, waitForTask } = widget;
function QuotesWidget() {
useEffect(() => {
waitForTask(fetchData());
});
}
Ma ciò risulterà in un altro "errore" in cui il nostro widget continuerà a essere nuovamente visualizzato con una nuova citazione, per sempre. Questo accade perché useEffect
, per definizione, si attiva nuovamente ogni volta che cambia lo stato del widget, anzi quando chiamiamo fetchData
. E mentre c'è una tecnica solo chiamare useEffect
una volta in React, non funziona sull'implementazione di Figma. Dai documenti di Figma:
A causa del modo in cui vengono eseguiti i widget,
useEffect
dovrebbe gestire l'essere chiamati più volte con lo stesso stato.
Per fortuna, esiste una semplice soluzione alternativa di cui possiamo trarre vantaggio e chiamare useEffect
solo una volta quando il componente viene montato per la prima volta, ed è controllando se i valori dello stato sono ancora vuoti o meno:
function QuotesWidget() {
useEffect(() => {
if (!author.length & !quote.length) {
waitForTask(fetchData());
}
});
}
Potresti incappare in una situazione spaventosa”accesso alla memoria fuori limite” errore. Suo abbastanza comune da vedere nello sviluppo di plugin e widget. Riavvia semplicemente Figma e non sarà più lì.
Potresti aver notato che a volte il testo della citazione contiene caratteri strani.
È prodotto in Caratteri Unicode e dobbiamo formattarli correttamente nel codice:
<!-- ui.html -->
<script>
window.onmessage = async (event) => {
// ...
const quoteContent = decodeEntities(data[0].yoast_head_json.og_description);
};
// <https://stackoverflow.com/a/9609450>
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(/<script[^>]*>([Ss]*?)</script>/gim, "");
str = str.replace(/</?w(?:[^"'>]|"[^"]*"|'[^']*')*>/gim, "");
element.innerHTML = str;
str = element.textContent;
element.textContent = "";
}
return str;
}
return decodeHTMLEntities;
})();
</script>
E altre ancora… voilà, il nostro widget recuperava un preventivo di design completamente nuovo ogni volta che veniva aggiunto alla scheda di progettazione.
Aggiunta di un menu delle proprietà al nostro widget
Sebbene il nostro widget recuperi una nuova citazione al momento dell'istanziazione, sarebbe molto più pratico se potessimo ripetere questo processo ma senza eliminarlo. Questa sezione sarà breve poiché la soluzione è davvero notevole. Con menu delle proprietà, possiamo aggiungere interattività al nostro widget con una singola chiamata al file usePropertyMenu
gancio.
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="<http://www.w3.org/2000/svg>">
<!-- Shortened for brevity -->
</svg>`,
},
],
() => fetchData()
);
}
Con un semplice aggancio possiamo creare un pulsante che appare vicino al nostro widget quando è selezionato. Questo era l'ultimo tassello che dovevamo aggiungere per completare questo progetto.
Pubblicare il nostro widget al pubblico
Non è di grande utilità creare un widget se, beh, nessuno usa Esso. E mentre Figma garantisce alle organizzazioni la possibilità di avviare un bagno widget per uso interno, è molto più comune rilasciare questi piccoli programmi al mondo.
Figma prevede un delicato processo di revisione dei widget che può richiedere dai 5 ai 10 giorni lavorativi. E mentre il widget delle citazioni di design che abbiamo creato insieme lo è già nella libreria dei widget, Dimostrerò comunque come è arrivato fin lì. Non tentare di ripubblicare nuovamente questo widget poiché ciò comporterà solo la rimozione. Ma se hai apportato modifiche significative, vai avanti e condividi il tuo widget con la community!
Inizia facendo clic sul menu dei widget (Shift
+I
) e passare a Mercato scheda per visualizzare il nostro widget. Fare clic sul menu con tre punti e premere Pubblica.
Figma ti chiederà di inserire alcuni dettagli sul tuo widget, come un titolo, una descrizione e alcuni tag. Avremo bisogno anche di un'immagine icona 128×128 e di un'immagine banner 1920×960.
Dopo aver importato tutte queste risorse, abbiamo ancora bisogno di uno screenshot del nostro widget. Chiudi la modalità di pubblicazione (non preoccuparti, non perderai i tuoi dati) e fai clic con il pulsante destro del mouse sul widget per visualizzare un interessante menu contestuale. Trovare il Copia/Incolla comecategoria e seleziona Copia come PNG.
Fatto ciò, torniamo alla modalità di pubblicazione e incolliamo lo screenshot del widget:
Scorri verso il basso e infine pubblica la tua modale. Celebrare! 🎉
Figma ti contatterà tra un paio di giorni sullo stato della revisione della tua modale. In caso di rifiuto ti verrà dato il possibilità di apportare modifiche e inviare nuovamente.
Conclusione
Abbiamo appena creato un widget Figma da zero! Ci sono molte cose non trattate qui, come ad esempio fare clic su eventi, moduli di inpute molto di piu. Puoi scavare nel codice sorgente completo del widget in questo repository GitHub.
A coloro che aspirano a portare le proprie abilità Figma a livelli più alti, suggerisco di esplorare la comunità dei widget e di utilizzare ciò che attira la tua attenzione come ispirazione. Continua a costruire più widget, continua ad affinare le tue abilità in React e, prima ancora che tu te ne accorga, mi insegnerai come fare tutto questo.
Ulteriori risorse
Ho dovuto fare riferimento a molta documentazione mentre creavo questo widget. Ho pensato di condividere ciò che ho trovato per aiutare di più.