# ../../components

Componentes Vue 3 + TypeScript prontos para uso nas lojas do ecossistema Uappi.

## Instalação

Adicione ao seu projeto:

```bash
npm install @uappi/public-sdk
```

## Componentes Disponíveis

- [**PaymentHosted**](#PaymentHosted): Formulário de pagamento hospedado via iframe isolado (render.uappi).
- [**ColorTheme**](#colortheme): Aplica variáveis CSS de cor e fonte customizadas da loja no `document.documentElement`.
- [**SocialAuth**](#socialauth): Botões de login social (`GoogleAuth`, `FacebookAuth`) via OAuth em popup.
- [**Animations**](#animations): Utilitários de transição (`ExpandTransition`).

---

## [PaymentHosted](#PaymentHosted)

Renderiza o formulário de pagamento (cartão, etc.) dentro de um `<iframe>` isolado, servido pelo serviço `render.uappi`. Dados sensíveis (número do cartão, CVV, etc.) trafegam diretamente entre o iframe e o gateway, sem passar pela loja.

O componente busca um token de pagamento via `api.cart.paymentToken` ao montar, monta a URL do iframe com esse token, e escuta `postMessage` do iframe para emitir eventos de pagamento. Mensagens de janelas que não sejam o `contentWindow` do próprio iframe são ignoradas.

A altura do iframe tem um piso definido em CSS (`min-height`), mas se ajusta automaticamente ao conteúdo quando o `render.uappi` envia `postMessage({ type: 'UAPPI_PAYMENT_RESIZE', height })` (`height` em pixels, número do conteúdo real do formulário). Isso é necessário porque o iframe é cross-origin — o componente não tem acesso ao `contentDocument` para medir a altura sozinho. Sem esse evento, o iframe mantém apenas o `min-height` fixo.

```vue
<script setup lang="ts">
import { PaymentHosted } from '@uappi/public-sdk';
import type { PaymentSuccessData, PaymentRedirectData } from '@uappi/public-sdk';

function onSuccess(data: PaymentSuccessData) {
  // pedido criado, mesmo formato de api.cart.buy
}

function onRedirect(url: string, data: PaymentRedirectData) {
  // gateway pediu redirecionamento (ex: 3DS)
}

function onError(errorCode: string | undefined, message: string) {
  // falha reportada pelo render.uappi
}
</script>

<template>
  <PaymentHosted
    :option="selectedPaymentOption"
    cta-color="#FF0000"
    lang="pt-BR"
    country-code="BRA"
    @payment-ready="onReady"
    @payment-success="onSuccess"
    @payment-redirect="onRedirect"
    @payment-error="onError"
  />
</template>
```

### Props

| Prop | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| `option` | `PaymentOption` | Sim | Opção de pagamento selecionada (item retornado por `api.cart.listPayments`). |
| `ctaColor` | `string` | Não | Cor hex do botão CTA do iframe (com ou sem `#`). Padrão: cor do render.uappi. |
| `lang` | `string` | Não | Locale do formulário (`pt-BR`, `en-US`, `es-ES`, ...). Padrão: `pt-BR`. |
| `countryCode` | `string` | Não | Código Alpha-3 para pré-selecionar o DDI do telefone (`BRA`, `USA`, ...). Padrão: `BRA`. |
| `iframeHost` | `string` | Não | Host do serviço render.uappi. Sobrescreve `VITE_PAYMENT_IFRAME_HOST` quando informado. |

### Eventos

| Evento | Payload | Quando é emitido |
|---|---|---|
| `payment-ready` | — | Iframe carregou e está pronto para interação. |
| `payment-success` | `data: PaymentSuccessData` | Pagamento concluído; `data` tem o mesmo formato de `api.cart.buy`. |
| `payment-redirect` | `url: string, data: PaymentRedirectData` | Gateway exige redirecionamento (ex: autenticação 3DS). |
| `payment-error` | `errorCode: string \| undefined, message: string` | Falha ao processar o pagamento. |

---

## [ColorTheme](#colortheme)

Aplica cores e fonte customizadas da loja como variáveis CSS globais (`--primary-cta-text`, `--checkout-cta-default`, `--font-family`, etc.) assim que é montado. Não renderiza elementos próprios — repassa o slot padrão via `Fragment`.

```vue
<script setup lang="ts">
import { ColorTheme } from '@uappi/public-sdk';
import type { CSSVariables } from '@uappi/public-sdk';

const variables: CSSVariables = {
  font: { family: 'Inter', link: 'https://fonts.googleapis.com/css2?family=Inter' },
  colors: {
    CheckoutCTADefault: '#000000',
    CheckoutCTAHover: '#333333',
    CheckoutCTAText: '#FFFFFF',
    PrimaryCTAText: '#FFFFFF',
    PrimaryInteractiveDefault: '#000000',
    PrimaryInteractiveHover: '#333333',
    PrimaryInteractiveHoverLow: '#666666',
    PrimarySurfaceDisabled: '#CCCCCC',
    PrimarySurfaceLow: '#F5F5F5',
    PrimaryTextDecorative: '#000000',
  },
};
</script>

<template>
  <ColorTheme :variables="variables">
    <App />
  </ColorTheme>
</template>
```

---

## [SocialAuth](#socialauth)

- `GoogleAuth` / `FacebookAuth`: botão de login social que abre um popup OAuth via `api.thirdParty.oauthRedirect`.

```vue
<script setup lang="ts">
import { GoogleAuth, FacebookAuth } from '@uappi/public-sdk';
</script>

<template>
  <GoogleAuth uri="/conta" />
  <FacebookAuth uri="/conta" />
</template>
```

| Prop | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| `uri` | `string` | Sim | Prefixo de rota da loja usado para montar as URLs de callback (`{uri}/signin`, `{uri}/signup`). |

---

## [Animations](#animations)

- `ExpandTransition`: wrapper sobre `<Transition>` do Vue que anima altura e opacidade (expandir/colapsar), útil para acordeões e listas condicionais.

```vue
<script setup lang="ts">
import { ExpandTransition } from '@uappi/public-sdk';
</script>

<template>
  <ExpandTransition>
    <div v-if="open">Conteúdo</div>
  </ExpandTransition>
</template>
```

| Prop | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| `mode` | `BaseTransitionProps['mode']` | Não | Modo de transição do Vue (`in-out`, `out-in`, `default`). Padrão: `out-in`. |

## Contribuição

Contribuições são bem-vindas! Abra uma issue ou envie um pull request.

## Licença

ISC
