# Scrivere un componente Flow: un file HTML

> Un componente Flow è un unico file HTML con una parte Node.js, un modulo di impostazioni e un design. Costruiscine uno che cambia il testo di un messaggio, scopri le parti del file e come testarlo.

Framework: flow
Product: Flow (flow@11.1)
Language: it
Content-SHA256: fa502ee0552281dedc15e9cf581abce88a7792c1cd5947879cd1e8f2103069af
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: 
Review: not-recorded

Un componente è **un file `.html`**. Flow legge il file, esegue la sua parte Node.js dentro il flusso e mostra il suo design nell’editor. I componenti ufficiali di [il repository](/en/flow/the-components-repository/) usano tutti questo formato, quindi puoi leggerne uno qualsiasi come esempio.

## Un esempio: `shout.html`

Riceve un messaggio, converte il testo in maiuscolo, aggiunge un suffisso e lo inoltra.

```html
<script total>

	exports.id = 'shout';
	exports.name = 'Shout';
	exports.group = 'Common';
	exports.version = '1';
	exports.icon = 'ti ti-speakerphone';
	exports.author = 'Forge';
	exports.config = { suffix: '!' };
	exports.inputs = [{ id: 'input', name: 'Input' }];
	exports.outputs = [{ id: 'output', name: 'Output' }];

	exports.make = function(instance, config) {

		let count = 0;

		instance.message = function($) {
			count++;
			instance.status({ shouted: count });
			$.data = String($.data).toUpperCase() + config.suffix;
			$.send('output');
		};

	};

</script>

<settings>
	<div class="padding">
		<ui-component name="input" path="?.suffix" config="maxlength:10">Suffix</ui-component>
	</div>
</settings>

<readme>
The component converts the text of a message to upper case and adds a suffix.
</readme>

<body>
	<header>
		<i class="ICON"></i>NAME
	</header>
	<footer>
		<div class="padding">Shouted: <b><ui-bind path="STATUS.shouted" config="text:value||0"></ui-bind></b></div>
	</footer>
</body>
```

## Le parti del file

| Parte | A cosa serve |
|---|---|
| `<script total>` | il codice Node.js del componente, eseguito nel processo del flusso |
| `<settings>` | il modulo di configurazione, con i componenti dell’interfaccia utente (`ui-component`, i percorsi che iniziano con `?.` puntano al `config` del componente) |
| `<readme>` | la guida mostrata nell’editor |
| `<body>` | il riquadro nel diagramma: un `<header>` con i segnaposto `ICON` e `NAME`, e facoltativamente un `<footer>` o un corpo, dove `<ui-bind path="STATUS.x">` mostra lo stato e `CONFIG.x` la configurazione |
| `<style>` | il CSS del riquadro; `.CLASS` viene sostituito con una classe univoca del componente |
| `<script>` (secondo) | JavaScript facoltativo dell’editor, per i pulsanti nel riquadro (può inviare `{ TYPE: 'trigger', id: ... }` al flusso) |

## Gli `exports` della parte Node.js

| Export | Significato |
|---|---|
| `id`, `name`, `group`, `version`, `icon`, `author` | l’identità del componente e dove compare nell’elenco |
| `config` | la configurazione predefinita; il modulo di `<settings>` la modifica |
| `inputs`, `outputs` | l’elenco dei connettori `{ id, name }`. Un componente senza `inputs` è una sorgente |
| `kind` | facoltativo: il ruolo del componente nel catalogo (`trigger`, `action` oppure `output`) |
| `make(instance, config)` | chiamato una volta per ogni riquadro che inserisci nel diagramma |

## L’`instance`

Dentro `make` definisci il comportamento assegnando funzioni all’istanza:

| Funzione | Chiamata quando |
|---|---|
| `instance.message = function($) {}` | arriva un messaggio. `$.data` sono i dati, `$.send('output')` li inoltra ai connettori di quell’uscita, `$.destroy()` lo termina senza inviarlo |
| `instance.configure = function() {}` | cambia la configurazione, e una volta all’inizio |
| `instance.trigger = function() {}` | lo richiede il pulsante dell’editor o il codice |
| `instance.pause = function(is) {}` | il flusso viene messo in pausa o ripreso |
| `instance.close = function() {}` | il riquadro viene rimosso o il flusso si ferma: pulisci qui i tuoi timer |

E chiami `instance.send('output', data)` per creare un messaggio tuo (come fa `timer`), `instance.status(object)` per mostrare uno stato nel riquadro (`delay.html` passa un tempo in millisecondi come secondo argomento per aggiornarlo) e `instance.throw(error)` per segnalare un errore.

## Provalo

1. Metti `shout.html` in un catalogo e scrivi il suo indirizzo nell’impostazione `components2` (vedi [il repository](/en/flow/the-components-repository/)), oppure importa un flusso che lo contiene nei suoi `components`.
2. Aggiungi accanto un `timer` e un `print` nell’editor, collegali e avvia il flusso.
3. Apri lo stato del riquadro: il contatore cresce a ogni messaggio.

Per testare un componente senza l’editor, il repository ha un piccolo tester, vedi [il repository dei componenti](/en/flow/the-components-repository/).
