Skip to content

feat(modal): [modal] enhance TINYModal functionality, add type definition andoption interface #3247

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 7, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 93 additions & 31 deletions packages/vue/src/modal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,88 @@ import { MsgQueue } from '@opentiny/vue-renderless/modal'
import TINYModal from './src/index'
import Popconfirm from '@opentiny/vue-popconfirm'
import { version } from './package.json'
import type { ComponentPublicInstance } from '@opentiny/vue-common'

// 定义Modal选项接口
interface ModalOptions {
id?: string
events?: {
hide?: (params: any) => void
confirm?: (params: any) => void
show?: (params: any) => void
}
componentType?: 'alert' | 'confirm' | 'message' | 'popconfirm'
message?: string
title?: string
showFooter?: boolean
type?: string
status?: string
mask?: boolean
lockView?: boolean
showHeader?: boolean
showClose?: boolean
[key: string]: any
}

// 定义ModalPromise接口,扩展Promise
interface ModalPromise extends Promise<string> {
vm?: ComponentPublicInstance
}

// 定义TINYModal接口
interface TINYModalInstance extends ComponentPublicInstance {
version: string
model: {
prop: string
event: string
}
tiny_mode?: boolean
tiny_theme?: string
installed: boolean
alert: (message: string | ModalOptions, title?: string, options?: ModalOptions) => ModalPromise
confirm: (message: string | ModalOptions, title?: string, options?: ModalOptions) => ModalPromise
message: (message: string | ModalOptions, title?: string, options?: ModalOptions) => ModalPromise
popconfirm: (message: string | ModalOptions, title?: string, options?: ModalOptions) => ModalPromise
install: (Vue: any) => void
}

// 定义setupComponent接口
interface SetupComponent {
TINYModal: {
install: (Vue: any) => void
init: (root: any) => void
}
}

// 扩展TINYModal类型
const TINYModalComponent = TINYModal as unknown as TINYModalInstance

TINYModal.version = version
TINYModalComponent.version = version

TINYModal.model = {
TINYModalComponent.model = {
prop: 'modelValue',
event: 'update:modelValue'
}

export function Modal(options) {
const modalPromise = new Promise((resolve) => {
export function Modal(options: ModalOptions): ModalPromise {
const modalPromise = new Promise<string>((resolve) => {
if (options && options.id && MsgQueue.some((comp) => comp.id === options.id)) {
resolve('exist')
} else {
let events = options.events || {}
let $modal
let $modal: ComponentPublicInstance
options.events = Object.assign({}, events, {
hide(params) {
hide(params: any) {
events.hide && events.hide.call(this, params)
if ($modal.beforeUnmouted) {
$modal.beforeUnmouted()
if ($modal && 'beforeUnmouted' in $modal) {
;($modal as any).beforeUnmouted()
}
resolve(params.type)
},
confirm(params) {
confirm(params: any) {
events.confirm && events.confirm.call(this, params)
},
show(params) {
show(params: any) {
events.show && events.show.call(this, params)
}
})
Expand All @@ -50,27 +105,30 @@ export function Modal(options) {
el: document.createElement('div'),
propsData: Object.assign(
{
'tiny_mode': TINYModal.tiny_mode,
'tiny_theme': TINYModal.tiny_theme
'tiny_mode': TINYModalComponent.tiny_mode,
'tiny_theme': TINYModalComponent.tiny_theme
},
options
),
component: options.componentType === 'popconfirm' ? Popconfirm : TINYModal
component: options.componentType === 'popconfirm' ? Popconfirm : TINYModalComponent
})

const open = $modal[options.componentType === 'popconfirm' ? 'show' : 'open']
const open = $modal[options.componentType === 'popconfirm' ? 'show' : 'open'] as Function
if (open) {
open()
}
setTimeout(() => (modalPromise.vm = $modal), 0)
setTimeout(() => {
;(modalPromise as ModalPromise).vm = $modal
}, 0)
}
})
}) as ModalPromise
return modalPromise
}
const modal = Modal
const types = ['alert', 'confirm', 'message', 'popconfirm']
const types = ['alert', 'confirm', 'message', 'popconfirm'] as const
type ModalType = (typeof types)[number]

const defOpts = {
const defOpts: Record<ModalType, Partial<ModalOptions>> = {
alert: {
showFooter: true,
type: 'alert'
Expand All @@ -91,8 +149,12 @@ const defOpts = {
}

types.forEach((type) => {
TINYModal[type] = Modal[type] = function (message, title, options) {
let opts
TINYModalComponent[type] = Modal[type] = function (
message: string | ModalOptions,
title?: string,
options?: ModalOptions
): ModalPromise {
let opts: Partial<ModalOptions> = {}

if (typeof message === 'object' && message !== null) {
opts = message
Expand All @@ -119,20 +181,20 @@ export const message = (Modal as any).message
export const confirm = (Modal as any).confirm
export const popconfirm = (Modal as any).popconfirm

TINYModal.installed = false
setupComponent.TINYModal = {
install(Vue) {
if (TINYModal.installed) return
TINYModalComponent.installed = false
;(setupComponent as SetupComponent).TINYModal = {
install(Vue: any) {
if (TINYModalComponent.installed) return
// vue3 或 vue2
const isVue2 = !!Vue.component
const tinyMode = isVue2 ? Vue.prototype.tiny_mode : Vue.config.globalProperties.tiny_mode
const tinyTheme = isVue2 ? Vue.prototype.tiny_theme : Vue.config.globalProperties.tiny_theme
const specifyPc = typeof process === 'object' ? process.env?.TINY_MODE : null
TINYModal.tiny_mode = specifyPc || (tinyMode && tinyMode.value)
TINYModal.tiny_theme = tinyTheme && tinyTheme.value
TINYModal.installed = true
TINYModalComponent.tiny_mode = specifyPc || (tinyMode && tinyMode.value)
TINYModalComponent.tiny_theme = tinyTheme && tinyTheme.value
TINYModalComponent.installed = true
},
init(root) {
init(root: any) {
let prefix = root.$TinyModalApiPrefix || root.$apiPrefix || '$'

root[`${prefix}alert`] = (Modal as any).alert
Expand All @@ -142,8 +204,8 @@ setupComponent.TINYModal = {
}
}

TINYModal.install = function (Vue) {
Vue.component(TINYModal.name, TINYModal)
TINYModalComponent.install = function (Vue: any) {
Vue.component(TINYModalComponent.name, TINYModalComponent)
}

export default TINYModal
export default TINYModalComponent
Loading