# Tipos Especiais de UI

Existem certos tipos especiais de entidade que permitem alguns tipos especiais de interações.

## Dropdown

Criar um `Dropdown` entidade para permitir que os usuários expandam e selecione um item de uma lista.

Uma `Dropdown` entidade deve ter pelo menos as seguintes propriedades:

* `options`: Quais valores exibir quando o dropdown estiver expandido. Forneça um objeto contendo um array com um valor string para cada opção. O primeiro valor no array é exibido como a opção padrão.
* `onChange`: Uma função que é executada toda vez que um valor é selecionado no dropdown, usando

Você também pode configurar outros componentes do `Dropdown` entidade, como um `uiTransform`, como em outras entidades de UI.

***arquivo ui.tsx:***

```tsx
import { UiEntity, Label, Dropdown, ReactEcs } from '@dcl/sdk/react-ecs'
import { Color4 } from '@dcl/sdk/math'
import { Color4Type } from '@dcl/sdk/ecs'

function selectOption(index: number) {
  switch (index) {
    case 0:
      textColor = Color4.Red()
      break
    case 1:
      textColor = Color4.Blue()
      break
    case 2:
      textColor = Color4.Green()
      break
  }
}

let textColor: Color4Type = Color4.Red()

export const uiMenu = () => (
    <UiEntity
      uiTransform={{
        width: '200px',
        height: '100px',
        alignContent: 'auto',
        flexDirection: 'column',
        alignSelf: 'center',
      }}
    >
      <Label
        value="Select a color"
        fontSize={18}
        color={textColor}
        uiTransform={{
          width: '140px',
          height: '40px',
        }}
      />
      <Dropdown
        options={[`Red`, `Blue`, `Green`]}
        onChange={selectOption}
        uiTransform={{
          width: '100px',
          height: '40px',
        }}
      />
    </UiEntity>
)
```

***arquivo index.ts:***

```ts
import { ReactEcsRenderer } from '@dcl/sdk/react-ecs'
import { uiMenu } from './ui'

export function main() {
    ReactEcsRenderer.setUiRenderer(uiMenu, { virtualWidth: 1920, virtualHeight: 1080 })
}
```

{% hint style="warning" %}
**📔 Nota**: Todos os trechos seguintes nesta página assumem que você tem um `.ts` semelhante ao acima, executando o `ReactEcsRenderer.setUiRenderer()` função.
{% endhint %}

## Texto de entrada

Criar um `Input` entidade para permitir que os usuários digitem texto. Os jogadores devem primeiro clicar nesta caixa antes de poderem escrever nela.

O comportamento da `Input` entidade é gerenciado pelas seguintes propriedades:

* `onSubmit`: Uma função que é executada quando o jogador aperta Return/Enter, usando o texto fornecido como entrada. O campo de texto é limpo quando isso acontece.
* `onChange`: Uma função que é executada toda vez que um valor no texto de entrada é alterado. À medida que o jogador digita na caixa, essa função é executada uma vez para cada caractere adicionado ou removido. Ela também é chamada quando o jogador aperta Return/Enter e o texto é limpo.
* `disable`: Se *true*, o jogador não poderá interagir com a entidade de input.

O exemplo a seguir usa `onSubmit` para registrar o texto fornecido no console.

```tsx
import { UiEntity, Input, ReactEcs } from '@dcl/sdk/react-ecs'
import { Color4 } from '@dcl/sdk/math'


export const uiMenu = () => (
  <UiEntity
    uiTransform={{
      width: 400,
      height: 300,
      positionType: 'absolute',
      position: {
        left: '35%',
        top: '40%',
      },
    }}
    uiBackground={{
      color: Color4.Gray(),
    }}
  >
    <Input
      onSubmit={(value) => {
        console.log('submitted value: ' + value)
      }}
      fontSize={35}
      placeholder={'type something'}
      placeholderColor={Color4.Black()}
      uiTransform={{
        width: '400px',
        height: '80px',
      }}
    ></Input>
  </UiEntity>
)
```

É uma boa prática fornecer tanto um botão para submissão quanto tratar o `onSubmit` evento quando o jogador pressiona a tecla Enter/Return. O exemplo a seguir mostra como você pode fazer isso.

{% hint style="warning" %}
**📔 Nota**: Não **not** vincular a `value` propriedade do `Input` diretamente ao que o jogador digita via `onChange`. Isso cria um vaivém entre a cena e o Explorer que faz com que caracteres sejam perdidos ao digitar rápido. Em vez disso, mantenha `value` como uma string vazia e só a altere quando quiser limpar o campo de entrada.
{% endhint %}

Para limpar o campo de entrada, defina `value` para `' '` (um espaço simples). O Explorer trata isso como vazio e reativa o texto do placeholder. Como a função de UI é executada a cada frame, use uma flag para aplicar a limpeza por apenas um frame.

```tsx
import { UiEntity, Input, Button, ReactEcs } from '@dcl/sdk/react-ecs'
import { Color4 } from '@dcl/sdk/math'

let inputText = ''
let clearInput = false

export const uiMenu = () => {
  const inputValue = clearInput ? ' ' : ''
  if (clearInput) clearInput = false

  return (
    <UiEntity
      uiTransform={{
        width: 400,
        height: 300,
        positionType: 'absolute',
        position: {
          left: '35%',
          top: '40%',
        },
        flexDirection: 'column',
      }}
      uiBackground={{
        color: Color4.Gray(),
      }}
    >
      <Input
        onSubmit={() => {
          console.log('submitted value: ' + inputText)
          inputText = ''
          clearInput = true
        }}
        fontSize={35}
        placeholder={'type something'}
        placeholderColor={Color4.Black()}
        value={inputValue}
        onChange={(value) => { inputText = value }}
        uiTransform={{
          height: '80px',
          margin: '15px',
        }}
      />
      <Button
        value="Submit text"
        variant="primary"
        uiTransform={{ alignSelf: 'center', padding: '25px' }}
        onMouseDown={() => {
          console.log('submitted value: ' + inputText)
          inputText = ''
          clearInput = true
        }}
      />
    </UiEntity>
  )
}
```

As seguintes propriedades também estão disponíveis para personalizar a aparência do campo de texto, a maioria delas semelhante às presentes em `Label` entidades:

* `placeHolder`: String para exibir antes que o jogador comece a digitar qualquer coisa. É útil fazer deste texto uma dica sobre o que ele deve escrever.
* `placeHolderColor`: A cor a ser usada para o texto do placeholder, como um [Color4](https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/essenciais-de-conteudo-3d/color-types).

{% hint style="info" %}
**💡 Dica**: Use um tom mais pálido da cor do texto que o jogador escreve.
{% endhint %}

* `fontSize`: O tamanho do texto, como um número.

  > OBS: O `fontSize` não é afetado pelo tamanho de sua entidade ou entidades pai.
* `color`: A cor do texto que o jogador escreve, como um [Color4](https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/essenciais-de-conteudo-3d/color-types).

{% hint style="warning" %}
**📔 Nota**: Certifique-se de usar uma cor diferente da `placeHolderColor`.
{% endhint %}

* `font`: A fonte a ser usada, tomando um valor do `Font` enum. Valores suportados são: - `F_SANS_SERIF` - `F_SERIF` *(padrão)* - `F_MONOSPACE`
* `textAlign`: Como o texto será alinhado com seu pai. Ele recebe um valor do \`TextAlignType\`. TextAlignType = 'top-left' | 'top-center' | 'top-right' | 'middle-left' | 'middle-center' | 'middle-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';

Você também pode configurar outros componentes do `Input` entidade, como um `uiTransform`, `OnMouseDown` como em outras entidades de UI.

```tsx
import { UiEntity, Input, Label, ReactEcs } from '@dcl/sdk/react-ecs'
import { Color4 } from '@dcl/sdk/math'

var currentTextString = ''

export const uiMenu = () => (
    <UiEntity
      uiTransform={{
        width: '50%',
        height: 150,
        flexDirection: 'column',
        alignContent: 'flex-start',
        margin: { left: 20, top: 20 },
        padding: { left: 10, top: 10, right: 10 },
        alignSelf: 'center',
      }}
      uiBackground={{ color: Color4.Gray() }}
    >
      <Input
        onChange={(e) => {
          currentTextString = 'you wrote: ' + e
        }}
        fontSize={35}
        placeholder={'type something'}
        placeholderColor={Color4.Gray()}
      />
      <Label value={currentTextString} fontSize={40} />
    </UiEntity>
)

```
