Skip to content

UIModal

UIModal

A versatile modal dialog component that displays content in a layer above the page, requiring user interaction before continuing. It supports various sizes, animations, and content structures.

<template>
<div>
<UIButton @click="showModal = true">
Open Modal
</UIButton>
<UIModal
v-model:show="showModal"
:title="'Modal Title'"
:closable="true"
:maskClosable="true"
:width="500"
@ok="handleOk"
@cancel="handleCancel"
>
<template #default>
<div class="p-6">
<p>Modal content goes here...</p>
<UIForm :model="formData">
<UIFormItem label="Name">
<UIInput v-model="formData.name" />
</UIFormItem>
</UIForm>
</div>
</template>
<template #footer>
<div class="flex justify-end space-x-3">
<UIButton @click="handleCancel">
Cancel
</UIButton>
<UIButton
type="primary"
:loading="loading"
@click="handleOk"
>
Confirm
</UIButton>
</div>
</template>
</UIModal>
</div>
</template>
<script setup lang="ts">
const showModal = ref(false)
const loading = ref(false)
const formData = ref({
name: ''
})
const handleOk = async () => {
loading.value = true
try {
// Process form data
showModal.value = false
} finally {
loading.value = false
}
}
const handleCancel = () => {
showModal.value = false
}
</script>

Props

  • show (boolean): Control modal visibility
  • title (string): Modal title
  • width (number | string): Modal width
  • centered (boolean): Center modal vertically
  • closable (boolean): Show close button
  • maskClosable (boolean): Close on mask click
  • closeOnEsc (boolean): Close on Escape key
  • destroyOnClose (boolean): Destroy children when closed
  • footer (boolean): Show footer section
  • fullscreen (boolean): Show in fullscreen mode
  • afterClose (Function): Callback after closed
  • zIndex (number): Modal z-index
  • wrapClassName (string): Modal wrapper class name
  • maskStyle (Object): Mask style object
  • bodyStyle (Object): Modal body style object
  • mask (boolean): Show backdrop mask
  • keyboard (boolean): Support keyboard actions
  • animation (string): Custom animation name
  • transitionName (string): Custom transition name

Events

  • update:show: Modal visibility changed
  • ok: OK button clicked
  • cancel: Cancel button clicked
  • close: Modal closed
  • afterOpen: Called after modal opened
  • afterClose: Called after modal closed

Slots

  • default: Modal content
  • title: Custom title content
  • footer: Custom footer content
  • closeIcon: Custom close icon
  • mask: Custom mask content

Usage Examples

  1. Basic Modal:
<template>
<UIButton @click="openModal">
Open Modal
</UIButton>
<UIModal
v-model:show="visible"
title="Basic Modal"
>
<p>Some content...</p>
</UIModal>
</template>
<script setup>
const visible = ref(false)
const openModal = () => {
visible.value = true
}
</script>
  1. Confirmation Modal:
<template>
<UIButton @click="confirmDelete">
Delete Item
</UIButton>
</template>
<script setup>
import { useModal } from '@gohighlevel/ghl-ui'
const modal = useModal()
const confirmDelete = () => {
modal.confirm({
title: 'Are you sure?',
content: 'This action cannot be undone.',
okText: 'Delete',
okButtonProps: { type: 'error' },
onOk: () => {
// Delete item
}
})
}
</script>
  1. Custom Modal with Components:
<template>
<UIModal
v-model:show="showPreviewModal"
:footer="false"
:width="800"
>
<template #title>
<div class="flex items-center space-x-2">
<FileIcon class="w-5 h-5" />
<span>{{ file.name }}</span>
</div>
</template>
<UIPreview
:src="file.url"
:type="file.type"
class="h-[60vh]"
/>
</UIModal>
</template>
  1. Multi-step Modal:
<template>
<UIModal
v-model:show="showWizard"
:title="`Step ${currentStep} of ${totalSteps}`"
:width="600"
:maskClosable="false"
>
<template #default>
<div class="p-6">
<UISteps
:current="currentStep - 1"
:items="steps"
class="mb-6"
/>
<component
:is="currentComponent"
v-model="formData"
@next="nextStep"
@prev="prevStep"
/>
</div>
</template>
<template #footer>
<div class="flex justify-between">
<UIButton
:disabled="currentStep === 1"
@click="prevStep"
>
Previous
</UIButton>
<UIButton
type="primary"
@click="currentStep === totalSteps ? finish : nextStep"
>
{{ currentStep === totalSteps ? 'Finish' : 'Next' }}
</UIButton>
</div>
</template>
</UIModal>
</template>

Best Practices

  1. Content Organization:

    • Keep modal focused on a single task
    • Use clear, concise titles
    • Organize content logically
    • Limit modal height
  2. User Interaction:

    • Provide clear actions
    • Use descriptive button labels
    • Handle loading states
    • Preserve form data
  3. Accessibility:

    • Manage focus correctly
    • Support keyboard navigation
    • Add ARIA attributes
    • Ensure screen reader support
  4. Visual Design:

    • Maintain proper spacing
    • Use consistent sizing
    • Consider mobile views
    • Animate transitions smoothly
  5. Performance:

    • Avoid complex modals
    • Lazy load content when needed
    • Clean up on close
    • Handle resource disposal