# Een Flow-component schrijven: één HTML-bestand

> Een Flow-component is één HTML-bestand met een Node.js-deel, een instellingenformulier en een ontwerp. Bouw er een die de tekst van een bericht verandert, leer de onderdelen van het bestand kennen en hoe je het test.

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

Een component is **één `.html`-bestand**. Flow leest het bestand, voert het Node.js-deel uit binnen de stream en toont het ontwerp in de editor. De officiële componenten van [de repository](/en/flow/the-components-repository/) gebruiken allemaal dit formaat, dus je kunt er elke als voorbeeld lezen.

## Een voorbeeld: `shout.html`

Het ontvangt een bericht, zet de tekst om in hoofdletters, voegt een achtervoegsel toe en stuurt het door.

```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>
```

## De onderdelen van het bestand

| Onderdeel | Waarvoor het dient |
|---|---|
| `<script total>` | de Node.js-code van de component, uitgevoerd in het proces van de stream |
| `<settings>` | het configuratieformulier, met de componenten van de gebruikersinterface (`ui-component`, paden die met `?.` beginnen wijzen naar de `config` van de component) |
| `<readme>` | de hulp die in de editor wordt getoond |
| `<body>` | het vak in het diagram: een `<header>` met de plaatshouders `ICON` en `NAME`, en optioneel een `<footer>` of een body, waar `<ui-bind path="STATUS.x">` de status toont en `CONFIG.x` de configuratie |
| `<style>` | de CSS van het vak; `.CLASS` wordt vervangen door een voor de component unieke klasse |
| `<script>` (tweede) | optioneel JavaScript van de editor, voor knoppen in het vak (het kan `{ TYPE: 'trigger', id: ... }` naar de stream sturen) |

## De `exports` van het Node.js-deel

| Export | Betekenis |
|---|---|
| `id`, `name`, `group`, `version`, `icon`, `author` | de identiteit van de component en waar hij in de lijst verschijnt |
| `config` | de standaardconfiguratie; het formulier van `<settings>` bewerkt haar |
| `inputs`, `outputs` | de lijst met connectoren `{ id, name }`. Een component zonder `inputs` is een bron |
| `kind` | optioneel: de rol van de component in de catalogus (`trigger`, `action` of `output`) |
| `make(instance, config)` | eenmaal aangeroepen voor elk vak dat je in het diagram plaatst |

## De `instance`

Binnen `make` definieer je het gedrag door functies aan de instantie toe te wijzen:

| Functie | Aangeroepen wanneer |
|---|---|
| `instance.message = function($) {}` | er een bericht binnenkomt. `$.data` zijn de gegevens, `$.send('output')` stuurt het door naar de connectoren van die uitgang, `$.destroy()` beëindigt het zonder te verzenden |
| `instance.configure = function() {}` | de configuratie verandert, en eenmaal bij de start |
| `instance.trigger = function() {}` | de knop van de editor of de code erom vraagt |
| `instance.pause = function(is) {}` | de stream wordt gepauzeerd of hervat |
| `instance.close = function() {}` | het vak wordt verwijderd of de stream stopt: ruim hier je timers op |

En je roept `instance.send('output', data)` aan om een eigen bericht te maken (zoals `timer` doet), `instance.status(object)` om een status in het vak te tonen (`delay.html` geeft een tijd in milliseconden als tweede argument mee om hem te verversen) en `instance.throw(error)` om een fout te melden.

## Probeer het

1. Zet `shout.html` in een catalogus en schrijf het adres ervan in de instelling `components2` (zie [de repository](/en/flow/the-components-repository/)), of importeer een stream die het in zijn `components` bevat.
2. Voeg er in de editor een `timer` en een `print` naast toe, verbind ze en start de stream.
3. Open de status van het vak: de teller groeit met elk bericht.

Om een component zonder de editor te testen heeft de repository een kleine tester, zie [de componentenrepository](/en/flow/the-components-repository/).
