# Tipos especiales de UI

Existen ciertos tipos especiales de entidades que permiten ciertos tipos especiales de interacciones.

## Desplegable

Crear un `Desplegable` entidad para permitir a los usuarios expandir y seleccionar un elemento de una lista.

Una `Desplegable` entidad debe tener al menos las siguientes propiedades:

* `opciones`: Qué valores mostrar cuando el desplegable está expandido. Proporcione un objeto que contenga un arreglo con un valor de cadena para cada opción. El primer valor en el arreglo se muestra como la opción por defecto.
* `onChange`: Una función que se ejecuta cada vez que se selecciona un valor en el desplegable, usando

También puedes configurar otros componentes de la `Desplegable` entidad, como un `uiTransform`, como en otras entidades de UI.

***archivo 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="Selecciona un color"
        fontSize={18}
        color={textColor}
        uiTransform={{
          width: '140px',
          height: '40px',
        }}
      />
      <Dropdown
        options={[`Red`, `Blue`, `Green`]}
        onChange={selectOption}
        uiTransform={{
          width: '100px',
          height: '40px',
        }}
      />
    </UiEntity>
)
```

***archivo 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 los siguientes fragmentos en esta página asumen que tienes un `.ts` similar al anterior, ejecutando la `ReactEcsRenderer.setUiRenderer()` función.
{% endhint %}

## Texto de entrada

Crear un `Input` entidad para permitir a los usuarios escribir texto. Los jugadores deben primero hacer clic en este cuadro antes de poder escribir en él.

El comportamiento de la `Input` entidad se gestiona a través de las siguientes propiedades:

* `onSubmit`: Una función que se ejecuta cuando el jugador pulsa Return/Enter, usando el texto proporcionado como entrada. El campo de texto se borra cuando esto sucede.
* `onChange`: Una función que se ejecuta cada vez que se cambia un valor en el texto de entrada. Mientras el jugador escribe en el cuadro, esta función se ejecuta una vez por cada carácter que se añade o elimina. También se llama cuando el jugador pulsa Return/Enter y el texto se borra.
* `disable`: Si *true*, el jugador no podrá interactuar con la entidad de entrada.

El siguiente ejemplo usa `onSubmit` para registrar el texto proporcionado en la consola.

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

Es una buena práctica proporcionar tanto un botón para enviar como manejar el `onSubmit` evento cuando el jugador presiona la tecla Enter/Return. El siguiente ejemplo muestra cómo puedes hacer esto.

{% hint style="warning" %}
**📔 Nota**: No **not** vincular la `value` propiedad de la `Input` directamente a lo que el jugador escribe vía `onChange`. Esto crea un ida y vuelta entre la escena y el Explorer que provoca que se pierdan caracteres al teclear rápido. En su lugar, mantén `value` como una cadena vacía y solo cámbiala cuando quieras borrar el campo de entrada.
{% endhint %}

Para limpiar el campo de entrada, establece `value` a `' '` (un solo espacio). El Explorer trata esto como vacío y reactiva el texto del placeholder. Dado que la función de UI se ejecuta cada frame, usa una bandera para aplicar el borrado solo durante un 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="Enviar texto"
        variant="primary"
        uiTransform={{ alignSelf: 'center', padding: '25px' }}
        onMouseDown={() => {
          console.log('submitted value: ' + inputText)
          inputText = ''
          clearInput = true
        }}
      />
    </UiEntity>
  )
}
```

Las siguientes propiedades también están disponibles para personalizar la apariencia del campo de texto, la mayoría de ellas similares a las presentes en `Label` entidades:

* `placeHolder`: Cadena para mostrar antes de que el jugador empiece a introducir cualquier cosa. Es útil hacer que este texto sea una pista sobre lo que deberían escribir.
* `placeHolderColor`: El color a usar para el texto del placeholder, como un [Color4](https://docs.decentraland.org/creator/content-creator-es/scenes-sdk7/conceptos-esenciales-de-contenido-3d/color-types).

{% hint style="info" %}
**💡 Consejo**: Usa un tono más pálido del color del texto que escribe el jugador.
{% endhint %}

* `fontSize`: El tamaño del texto, como un número.

  > NOTA: El `fontSize` no se ve afectado por el tamaño de su entidad o entidades padre.
* `color`: El color del texto que escribe el jugador, como un [Color4](https://docs.decentraland.org/creator/content-creator-es/scenes-sdk7/conceptos-esenciales-de-contenido-3d/color-types).

{% hint style="warning" %}
**📔 Nota**: Asegúrate de usar un color diferente al `placeHolderColor`.
{% endhint %}

* `font`: La fuente a usar, tomando un valor del `Font` enum. Los valores compatibles son: - `F_SANS_SERIF` - `F_SERIF` *(predeterminado)* - `F_MONOSPACE`
* `textAlign`: Cómo se alineará el texto con su padre. Toma un valor de \`TextAlignType\`. TextAlignType = 'top-left' | 'top-center' | 'top-right' | 'middle-left' | 'middle-center' | 'middle-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';

También puedes configurar otros componentes de la `Input` entidad, como un `uiTransform`, `OnMouseDown` como en otras 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 = 'escribiste: ' + e
        }}
        fontSize={35}
        placeholder={'type something'}
        placeholderColor={Color4.Gray()}
      />
      <Label value={currentTextString} fontSize={40} />
    </UiEntity>
)

```
