import { makeComponentProps } from '@/composables/component' import { computed, ref, Transition } from 'vue' import ColorName from '@/types/colors' import { UIcon } from '@/components/UIcon/UIcon' import { UButton } from '@/components/UButton/UButton' import { UModalActions } from '@/components/UModal/UModalActions' import '@/components/UModal/transition.scss' import UntitledColorTypes from '@/types/untitledColorTypes' import { genericComponent, propsFactory, useRender } from '@/utils' export const makeUModalProps = propsFactory( { isActive: Boolean, prependIcon: String, iconColor: String, position: String, destructive: Boolean, dualAction: Boolean, checkboxControl: Boolean, smallActions: Boolean, unclosable: { type: Boolean, default: false }, text: String, supportingText: String, primaryButtonText: String, secondaryButtonText: String, checkboxText: String, ...makeComponentProps(), }, 'UModal' ) export type UModalSlots = { default: never header: never } export const UModal = genericComponent()({ name: 'UModal', props: makeUModalProps(), emits: { click: (e: MouseEvent) => true, close: () => true, check: (isChecked: boolean) => true, action: (isPrimary: boolean) => true, 'update:isActive': (isActive: boolean) => true, }, setup(props, { emit, slots }) { const modalContainer = ref(null) const modalContentContainer = ref(null) const onClick = (e: MouseEvent) => { emit('click', e) } const closeModal = () => { emit('update:isActive', false) emit('close') } const checkboxChange = (isChecked: boolean) => { emit('check', isChecked) } const actionsClick = (isPrimary: boolean) => { emit('action', isPrimary) } const backgroundClasses = computed( () => `modal-container absolute top-0 left-0 w-full h-full flex items-center justify-center backdrop-blur-[8px] px-4 bg-[#344054] bg-opacity-70` ) const contentClasses = computed( () => `box-border flex flex-col relative ${ props.position == 'horizontal' ? `max-w-[544px] items-center :sm:items-start` : `max-w-[400px] items-${props.position}` } bg-white p-6 rounded-md w-full sm:min-w-[400px]` ) const closeButtonClasses = computed( () => `absolute top-[24px] right-[24px]` ) const headerSlotClasses = computed( () => `w-full ${props.text || props.supportingText ? 'mb-[20px]' : ``}` ) const textContainerClasses = computed(() => `flex flex-col gap-2`) const modalActionsContainerClasses = computed(() => `w-full`) const defaultSlotClasses = computed( () => `${ props.prependIcon || props.text || props.supportingText ? 'mt-[20px]' : `` }` ) const iconTextClasses = computed( () => `${ props.position == 'horizontal' ? 'flex flex-col sm:flex-row gap-x-[28px] items-center sm:items-start' : `flex-col items-${props.position}` } flex items-${props.position}` ) const getIconColor = computed(() => { return props.destructive ? ('error-600' as ColorName) : ((props.iconColor + '-600') as ColorName) }) const iconClasses = computed( () => `w-[40px] h-[40px] flex shrink-0 items-center justify-center rounded-full ${props.destructive ? 'bg-error-100' : `bg-${props.iconColor}-100`} shadow-md-icon ${ props.destructive ? 'shadow-error-50' : `shadow-${props.iconColor}-50` } mb-4` ) const textClasses = computed( () => `text-text-lg font-semibold text-gray-900 ${ props.position == 'horizontal' ? 'text-center sm:text-left' : `text-${props.position}` }` ) const supportingTextClasses = computed( () => `text-text-sm text-${props.position} font-regular text-gray-600 ${ props.position == 'horizontal' ? 'text-center sm:text-left' : `text-${props.position}` }` ) useRender(() => ( {props.isActive ? (
props.unclosable === false && closeModal()} >
{props.prependIcon ? (
) : null} {slots.header ? (
{slots.header?.()}
) : null} {props.unclosable === false ? (
) : null} {props.text || props.supportingText ? (
{props.text ? (
{props.text}
) : null} {props.supportingText ? (
{props.supportingText}
) : null}
) : null} {slots.default ? (
{slots.default?.()}
) : null}
{props.primaryButtonText ? (
) : null}
) : null}
)) return { closeModal, } }, }) export type UModal = InstanceType