# Componentes Web

`@astroway/ui` é um conjunto de custom elements comuns: colocas a tag na página e ela desenha-se a si própria. Os mapas são desenhados por [`@astroway/render`](https://www.npmjs.com/package/@astroway/render), o mesmo código que está por trás de `/v1/render/*`, por isso a roda na tua página coincide com a roda que a API devolve.

O pacote está em **alfa** (`0.1.0-alpha.1`): os nomes dos atributos ainda podem mudar até à versão 1.0. Página do pacote: [npm](https://www.npmjs.com/package/@astroway/ui), código: [GitHub](https://github.com/astroway/astroway-ui).

## Instalação

A partir de uma CDN, sem build:

```html
<script type="module" src="https://cdn.jsdelivr.net/npm/@astroway/ui/dist/cdn/index.js"></script>
<aw-moon-phase></aw-moon-phase>
```

Ou com npm, importando todos os elementos ou apenas os necessários. O pacote ainda está em alfa, por isso pede esta tag:

```bash
npm install @astroway/ui@alpha
```

```js
```

## Três formas de dar dados ao elemento

**A. Os teus dados.** Fazes o pedido no teu servidor com a tua chave e passas o JSON ao elemento. O pedido não parte do browser do visitante, por isso serve uma chave de qualquer classe.

```js
document.querySelector('aw-natal-wheel').data = chart; // data з відповіді /v1/chart
```

Um template no servidor pode escrever o mesmo JSON num atributo:

```php
<aw-natal-wheel data='<?= htmlspecialchars(json_encode($chart), ENT_QUOTES) ?>'></aw-natal-wheel>
```

**B. Sem chave.** Os elementos em `/v1/public/*` não precisam de chave. Partilham o orçamento público do visitante, 30 unidades por hora a partir de um IP; quando se esgota, o elemento indica quanto tempo esperar.

```html
<aw-moon-phase lang="uk"></aw-moon-phase>
<aw-horoscope sign="leo" period="daily"></aw-horoscope>
<aw-tarot-spread spread="three-card"></aw-tarot-spread>
```

**C. Chave para o browser.** Os elementos em endpoints com chave aceitam uma chave `pk_`, criada para o teu site: a lista de domínios, o limite de créditos e o âmbito de endpoints são obrigatórios na criação. Vê a secção "Chaves para o browser" na página de [autenticação](/authentication/). A chave secreta `aw_` é rejeitada antes mesmo do pedido.

```html
<aw-natal-wheel api-key="pk_live_..." date="1990-05-15" time="14:30"
  latitude="50.45" longitude="30.52" timezone-offset="3"></aw-natal-wheel>
```

Para estes elementos, o âmbito da chave precisa de `chart`, e também de `chinese/zodiac/animal` se usares `aw-chinese-sign`. Os domínios são comparados pelo host: uma chave para `example.com` também funciona em `http://example.com:8080`.

## React e Next.js

O React 19 renderiza custom elements diretamente. Duas coisas diferem do HTML comum:

- O React fica com o `key` para si, por isso passa a chave como `api-key`.
- Numa página com renderização no servidor, passa os dados da forma A como string. O React descarta objetos durante a renderização no servidor e não os expõe durante a hidratação.

```tsx
'use client';

  return <aw-natal-wheel data={JSON.stringify(chart)} />;
}
```

Os módulos podem ser importados no servidor: a tag sai como HTML comum e desenha-se assim que o browser carrega o elemento.

## Elementos

| Elemento | Formas | Fonte |
|---|---|---|
| `aw-natal-wheel` | A/C | `/v1/chart` |
| `aw-aspect-grid` | A/C | `/v1/chart` |
| `aw-planet-table` | A/C | `/v1/chart` |
| `aw-moon-phase` | A/B | `/v1/public/moon-phase` |
| `aw-planet-of-day` | A/B | `/v1/public/planet-of-day` |
| `aw-horoscope` | A/B | `/v1/public/horoscope/{daily,weekly,monthly}` |
| `aw-tarot-card`, `aw-tarot-spread` | A/B | `/v1/public/tarot/*` |
| `aw-sign-matrix` | A/B | `/v1/public/compatibility/matrix` |
| `aw-synastry-score` | A/B | `/v1/public/synastry` |
| `aw-chinese-sign` | A/C | `/v1/chinese/zodiac/animal` + `/v1/public/chinese/zodiac/texts` |

Os elementos com um único mapa na página (roda, tabela e grelha com os mesmos dados de nascimento) fazem um único pedido para todos.

O `aw-aspect-grid` no seu tamanho próprio tem cerca de 560 px de largura. Numa coluna mais estreita encolhe, e as legendas dos orbes ficam pequenas; o atributo `scroll` mantém o tamanho completo com scroll horizontal.

## Idioma, tema, erros

- `lang` aceita qualquer um dos [21 idiomas](/languages/); por omissão usa o `<html lang>` da página. Os nomes vêm das tabelas `localized` da API.
- `theme="dark"` muda o desenho; as cores são definidas pelas variáveis CSS `--aw-accent`, `--aw-fg`, `--aw-bg`, `--aw-bg-soft`, `--aw-border`.
- Cada elemento emite um evento `aw-error` com `{ kind, message }`, onde `kind` é `error`, `rate-limited` ou `key`.
