Skip to content

Modal

Terminal-style modal dialog with overlay, header, body, footer, and keyboard support.

Modal

Demo

vue
<script setup lang="ts">
import { ref } from 'vue'
import { ButtonTui, Modal } from '@herdrate/vue'
const open = ref(false)
</script>

<template>
  <ButtonTui @click="open = true" color="primary">Abrir modal</ButtonTui>
  <Modal v-model:open="open" title="Example Modal" closable>
    This is the modal body content.
    <template #footer>
      <ButtonTui @click="open = false">OK</ButtonTui>
      <ButtonTui @click="open = false">Cancel</ButtonTui>
    </template>
  </Modal>
</template>

Props

title

Título mostrado en la cabecera del modal. Cuando está vacío, no se muestra espacio reservado.

vue
<script setup lang="ts">
import { ref } from 'vue'
import { ButtonTui, Modal } from '@herdrate/vue'
const open = ref(false)
</script>

<template>
  <ButtonTui @click="open = true" color="primary">Abrir modal</ButtonTui>
  <Modal v-model:open="open" title="Modal con título" closable>
    Contenido del modal.
    <template #footer>
      <ButtonTui @click="open = false">Cerrar</ButtonTui>
    </template>
  </Modal>
</template>

color

Color semántico del título en el header.

vue
<script setup lang="ts">
import { ref } from 'vue'
import { ButtonTui, Modal } from '@herdrate/vue'
const openPrimary = ref(false)
const openSuccess = ref(false)
const openDanger = ref(false)
</script>

<template>
  <div style="display: flex; gap: 0.5rem;">
    <ButtonTui @click="openPrimary = true" color="primary">Primary</ButtonTui>
    <ButtonTui @click="openSuccess = true" color="success">Success</ButtonTui>
    <ButtonTui @click="openDanger = true" color="danger">Danger</ButtonTui>
  </div>
  <Modal v-model:open="openPrimary" title="Primary" color="primary" closable>
    Modal con color primary.
    <template #footer>
      <ButtonTui @click="openPrimary = false" color="primary">Cerrar</ButtonTui>
    </template>
  </Modal>
  <Modal v-model:open="openSuccess" title="Success" color="success" closable>
    Modal con color success.
    <template #footer>
      <ButtonTui @click="openSuccess = false" color="success">Cerrar</ButtonTui>
    </template>
  </Modal>
  <Modal v-model:open="openDanger" title="Danger" color="danger" closable>
    Modal con color danger.
    <template #footer>
      <ButtonTui @click="openDanger = false" color="danger">Cerrar</ButtonTui>
    </template>
  </Modal>
</template>

width

Ancho del modal. Acepta cualquier valor CSS: ch, px, rem, %.

vue
<script setup lang="ts">
import { ref } from 'vue'
import { ButtonTui, Modal } from '@herdrate/vue'
const openNarrow = ref(false)
const openWide = ref(false)
</script>

<template>
  <div style="display: flex; gap: 0.5rem;">
    <ButtonTui @click="openNarrow = true" color="primary">40ch</ButtonTui>
    <ButtonTui @click="openWide = true" color="primary">80ch</ButtonTui>
  </div>
  <Modal v-model:open="openNarrow" title="Estrecho (40ch)" width="40ch" closable>
    Contenido del modal con ancho 40ch.
    <template #footer>
      <ButtonTui @click="openNarrow = false" color="primary">Cerrar</ButtonTui>
    </template>
  </Modal>
  <Modal v-model:open="openWide" title="Ancho (80ch)" width="80ch" closable>
    Contenido del modal con ancho 80ch.
    <template #footer>
      <ButtonTui @click="openWide = false" color="primary">Cerrar</ButtonTui>
    </template>
  </Modal>
</template>

closable

Muestra u oculta el botón de cierre (×) en la cabecera.

vue
<script setup lang="ts">
import { ref } from 'vue'
import { ButtonTui, Modal } from '@herdrate/vue'
const openWithClose = ref(false)
const openWithoutClose = ref(false)
</script>

<template>
  <div style="display: flex; gap: 0.5rem;">
    <ButtonTui @click="openWithClose = true" color="primary">Con cierre</ButtonTui>
    <ButtonTui @click="openWithoutClose = true" color="primary">Sin cierre</ButtonTui>
  </div>
  <Modal v-model:open="openWithClose" title="Cerrable" closable>
    Puedes cerrar con ×, Escape o el botón de abajo.
    <template #footer>
      <ButtonTui @click="openWithClose = false" color="primary">Cerrar</ButtonTui>
    </template>
  </Modal>
  <Modal v-model:open="openWithoutClose" title="No cerrable" :closable="false">
    Solo puedes cerrar con Escape o el botón de abajo.
    <template #footer>
      <ButtonTui @click="openWithoutClose = false" color="primary">Cerrar</ButtonTui>
    </template>
  </Modal>
</template>

Slots

default (cuerpo)

Contenido principal del modal. Puede incluir cualquier HTML o componente Vue.

vue
<script setup lang="ts">
import { ref } from 'vue'
import { ButtonTui, Modal } from '@herdrate/vue'
const open = ref(false)
</script>

<template>
  <ButtonTui @click="open = true" color="primary">Abrir modal</ButtonTui>
  <Modal v-model:open="open" title="Contenido variado" closable>
    <p>Este es el cuerpo del modal.</p>
    <ul>
      <li>Elemento 1</li>
      <li>Elemento 2</li>
      <li>Elemento 3</li>
    </ul>
    <template #footer>
      <ButtonTui @click="open = false" color="primary">OK</ButtonTui>
    </template>
  </Modal>
</template>

Área de acciones del modal. Típicamente contiene botones de confirmación o cancelación.

vue
<script setup lang="ts">
import { ref } from 'vue'
import { ButtonTui, Modal } from '@herdrate/vue'
const open = ref(false)
</script>

<template>
  <ButtonTui @click="open = true" color="primary">Abrir modal</ButtonTui>
  <Modal v-model:open="open" title="Confirmación" closable>
    ¿Estás seguro de realizar esta acción?
    <template #footer>
      <ButtonTui @click="open = false" color="primary">Cancelar</ButtonTui>
      <ButtonTui @click="open = false" color="primary">Confirmar</ButtonTui>
    </template>
  </Modal>
</template>

API

PropTipoDefaultDescripción
openbooleanfalseControl de visibilidad
titlestring''Título del modal
colorColor'primary'Color del título
closablebooleantrueMuestra botón de cierre (×)
widthstring'60ch'Ancho del modal
EventoDescripción
closeSe emite al cerrar el modal
update:openSe emite con false al cerrar (soporta v-model:open)
SlotDescripción
defaultCuerpo del modal
footerPie del modal (área de acciones)

Tokens usados

--bg, --bg-panel, --border, --text, --font-mono, --color-{color}