Appearance
usePopup Composable
javascript
import { ref, computed } from 'vue'
// Global state for popup
const popup = ref(null)
const config = ref({
closeOnOverlayClick: true,
showCloseIcon: true,
enableAnimation: true
})
export function usePopup() {
// Generate unique ID for each popup
const generateId = () => window.crypto.randomUUID()
// Show popup
const showPopup = (options) => {
const {
title = '',
content = '',
component = null,
componentProps = {},
buttonConfig = [],
showCloseIcon = config.value.showCloseIcon,
closeOnOverlayClick = config.value.closeOnOverlayClick,
showMandatoryFieldsError = false,
showMandatoryFieldsErrorMsg = 'Please fill mandatory fields',
customClass = '',
onClose = null,
onFooterClick = null
} = options
// Create popup object
const newPopup = {
id: generateId(),
title,
content,
component,
componentProps,
buttonConfig,
showCloseIcon,
closeOnOverlayClick,
showMandatoryFieldsError,
showMandatoryFieldsErrorMsg,
customClass,
onClose,
onFooterClick,
createdAt: Date.now()
}
// Set the popup (replaces any existing popup)
popup.value = newPopup
return newPopup
}
// Close popup
const closePopup = (reason = 'manual') => {
if (popup.value?.onClose) {
popup.value.onClose(reason)
}
popup.value = null
}
// Convenience methods for common popup types
const confirm = (title, content, options = {}) => {
const defaultButtons = [
{
buttonText: 'Cancel',
classNames: ['secondary-button-v2'],
action: () => {
closePopup('cancel')
options.onCancel?.()
}
},
{
buttonText: 'Confirm',
classNames: ['primary-button'],
action: () => {
closePopup('confirm')
options.onConfirm?.()
}
}
]
return showPopup({
title,
content,
buttonConfig: options.buttonConfig || defaultButtons,
showCloseIcon: options.showCloseIcon ?? true,
...options
})
}
const alert = (title, content, options = {}) => {
const defaultButtons = [
{
buttonText: 'OK',
classNames: ['primary-button'],
action: () => {
closePopup('ok')
options.onOk?.()
}
}
]
return showPopup({
title,
content,
buttonConfig: options.buttonConfig || defaultButtons,
showCloseIcon: options.showCloseIcon ?? true,
...options
})
}
const prompt = (title, content, options = {}) => {
return showPopup({
title,
content,
component: 'PromptInput', // You can create this component
componentProps: options.componentProps || {},
buttonConfig: options.buttonConfig || [],
showCloseIcon: options.showCloseIcon ?? true,
...options
})
}
const custom = (component, props = {}, options = {}) => {
return showPopup({
title: options.title || '',
component,
componentProps: props,
buttonConfig: options.buttonConfig || [],
showCloseIcon: options.showCloseIcon ?? false,
...options
})
}
// Configuration methods
const setCloseOnOverlayClick = (value) => {
config.value.closeOnOverlayClick = value
}
const setShowCloseIcon = (value) => {
config.value.showCloseIcon = value
}
const setEnableAnimation = (value) => {
config.value.enableAnimation = value
}
// Handle overlay click
const handleOverlayClick = (event, reason = 'overlayClick') => {
if (popup.value?.closeOnOverlayClick) {
closePopup(reason)
}
}
// Handle footer click
const handleFooterClick = (event) => {
if (popup.value?.onFooterClick) {
popup.value.onFooterClick(event)
}
}
// Computed properties
const isPopupOpen = computed(() => popup.value !== null)
const currentPopup = computed(() => popup.value)
return {
// State
popup: currentPopup,
config: computed(() => config.value),
// Computed
isPopupOpen,
// Methods
showPopup,
closePopup,
handleOverlayClick,
handleFooterClick,
// Convenience methods
confirm,
alert,
prompt,
custom,
// Configuration
setCloseOnOverlayClick,
setShowCloseIcon,
setEnableAnimation
}
}