# Campos, listas e abas

> Tudo o que se faz só com atributos no HTML: campos de todos os tipos, textos calculados, imagens, listas, abas e o que cada papel vê.

Página: https://docs.rpgdesk.com/fichas/campos/

O rpgdesk.js liga sozinho os atributos `data-…` da página, inclusive nos elementos que aparecem depois (os itens de uma lista, por exemplo). Uma ficha inteira pode ser feita sem JavaScript. A tabela completa está em [Atributos no HTML](https://docs.rpgdesk.com/referencia/atributos/).

A ficha abaixo usa quase tudo desta página: o retrato, os campos, os modificadores calculados, as abas, a lista do inventário e a aba do mestre. Troque o **Papel** na faixa do canto para ver o que cada um vê.

*Exemplo funcionando:* [D20 Genérico](https://docs.rpgdesk.com/exemplos/d20-generico.html)

## O documento e os caminhos

Cada ficha tem um **documento**: os campos e os valores dela, guardados na mesa. Cada campo tem um **caminho**:

- `nome`, `nivel`, `forca`: campos soltos;
- `atributos.forca`, `pv.atual`, `pv.max`: campos dentro de um grupo, separados por ponto.

As regras dos nomes:

- letras **sem acento**, números e `_`, começando por letra ou `_`: `forca`, não `força`;
- maiúsculas não contam: `Forca` e `forca` são o mesmo campo;
- até 64 caracteres por nome e 12 níveis de grupo;
- nomes que começam com `_rpgdesk` são do RPG Desk.

O verificador avisa de um nome errado antes de instalar. Veja [O verificador](https://docs.rpgdesk.com/referencia/verificador/).

## Campos: `data-field`

Vai num `<input>`, `<textarea>` ou `<select>`:

```html
<label>Nome <input data-field="nome"></label>
<label>Nível <input type="number" data-field="nivel" min="1"></label>
<label><input type="checkbox" data-field="inspirado"> Inspirado</label>
<label>Alinhamento
  <select data-field="alinhamento">
    <option>Leal</option>
    <option>Neutro</option>
    <option>Caótico</option>
  </select>
</label>
<label><input type="radio" name="tamanho" value="pequeno" data-field="tamanho"> Pequeno</label>
<label><input type="radio" name="tamanho" value="medio" data-field="tamanho"> Médio</label>
<textarea data-field="historia" placeholder="História"></textarea>
```

| Campo                                        | O que grava                                           |
| -------------------------------------------- | ----------------------------------------------------- |
| texto, `<textarea>`                          | o texto                                               |
| `type="number"`, `type="range"`              | um número (vazio apaga o campo)                       |
| `type="checkbox"`                            | verdadeiro ou falso                                   |
| `type="radio"`                               | o `value` do marcado (todos com o mesmo `data-field`) |
| `<select>`                                   | o `value` da opção escolhida                          |
| `type="date"`, `type="time"`, `type="color"` | o valor, como texto                                   |

- Texto e número gravam enquanto a pessoa escreve; as escolhas gravam na hora.
- O que outra pessoa escreve aparece na hora. Se você está escrevendo no mesmo campo, a mudança dela aparece quando você sai do campo.
- Quem não pode escrever vê o campo travado (a classe `rd-readonly` vai no campo). `data-readonly` trava o campo para todos: bom para mostrar um valor calculado num campo.

## Textos: `data-text`

Mostra o valor de um campo como texto, em qualquer elemento. É o jeito de mostrar um valor calculado:

```html
<p>Modificador: <b data-text="mod_forca"></b></p>
```

O valor de `mod_forca` vem do JavaScript, com `doc.compute`: veja [Campos calculados](https://docs.rpgdesk.com/fichas/javascript/#campos-calculados).

## Imagens: `data-image`

Num `<img>`, mostra a imagem guardada no campo. Clicar abre a escolha de imagem do RPG Desk (do computador ou das imagens da mesa) para quem pode escrever:

```html
<img class="retrato" data-image="retrato" alt="Retrato do personagem">
```

Sem imagem, aparece uma silhueta; um `src` próprio no `<img>` troca a silhueta. O campo guarda o identificador do arquivo, não a imagem.

## Listas: `data-list`

Inventário, magias, ataques: uma lista em que cada item tem os seus campos. O `<template>` dentro dela é o molde de cada item:

```html
<ul data-list="inventario">
  <template>
    <li class="rd-row">
      <input class="rd-grow" data-field="nome" placeholder="Item">
      <input type="number" data-field="qtd" min="0">
      <button data-roll="1d6 + {qtd}" data-label="{nome}">Rolar</button>
      <button data-list-remove>×</button>
    </li>
  </template>
</ul>
<button data-list-add="inventario">+ Item</button>
```

- Dentro do `<template>`, os caminhos são **do item**: `nome` é o nome do item, e `{qtd}`, a quantidade dele.
- `data-list-add="inventario"` acrescenta um item vazio no fim.
- `data-list-remove`, dentro do `<template>`, tira aquele item.
- Uma lista pode ter outra lista dentro de cada item.

Para pôr itens já preenchidos, reordenar ou contar os itens, use o JavaScript: veja [Listas](https://docs.rpgdesk.com/fichas/javascript/#listas).

## Abas: `data-tabs`

Uma ficha é uma página só. Para separar em partes, use abas:

```html
<nav data-tabs="ficha">
  <button data-tab="principal">Principal</button>
  <button data-tab="magias">Magias</button>
</nav>
<section data-tab-panel="principal">…</section>
<section data-tab-panel="magias">…</section>
```

- Só a seção da aba escolhida aparece. A primeira aba começa aberta.
- O nome em `data-tabs` (`"ficha"`) separa um grupo de abas de outro, se a página tiver mais de um.
- A aba escolhida fica guardada enquanto a ficha estiver aberta, mesmo se ela mudar de espaço.

## Quem vê: `data-role`

| Valor                | Quem vê o elemento           |
| -------------------- | ---------------------------- |
| `data-role="gm"`     | só os mestres                |
| `data-role="owner"`  | o dono da ficha e os mestres |
| `data-role="player"` | só os jogadores              |

> **data-role é aparência**
>
> `data-role` só esconde o elemento na tela: os dados continuam chegando a todos. Para um segredo de verdade (o que os jogadores não podem nem receber), use as [partes privadas](https://docs.rpgdesk.com/fichas/partes-privadas/).

## Elementos criados pelo JavaScript

O rpgdesk.js liga sozinho os elementos que entram na página. Se você monta um pedaço da página com `innerHTML` e ele não ligou, chame `RPGDesk.bind(elemento)`.
