mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-03-01 13:36:55 +08:00
feat(modal): clsPrefix
This commit is contained in:
parent
979c3c4d98
commit
0af36ac95b
@ -1 +1,2 @@
|
||||
export { default as NModal } from './src/Modal'
|
||||
export type { ModalProps } from './src/Modal'
|
||||
|
@ -23,10 +23,9 @@ import { NDialog } from '../../dialog'
|
||||
import { NCard } from '../../card'
|
||||
import { getFirstSlotVNode, keep, warn } from '../../_utils'
|
||||
import { presetProps } from './presetProps'
|
||||
import type { ModalInjection } from './Modal'
|
||||
import { drawerBodyInjectionKey } from '../../drawer/src/interface'
|
||||
import { popoverBodyInjectionKey } from '../../popover/src/interface'
|
||||
import { modalBodyInjectionKey } from './interface'
|
||||
import { modalBodyInjectionKey, modalInjectionKey } from './interface'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ModalBody',
|
||||
@ -77,7 +76,8 @@ export default defineComponent({
|
||||
watch(toRef(props, 'show'), (value) => {
|
||||
if (value) displayedRef.value = true
|
||||
})
|
||||
const NModal = inject<ModalInjection>('NModal') as ModalInjection
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const NModal = inject(modalInjectionKey)!
|
||||
function styleTransformOrigin (): string {
|
||||
const { value: transformOriginX } = transformOriginXRef
|
||||
const { value: transformOriginY } = transformOriginYRef
|
||||
@ -139,7 +139,10 @@ export default defineComponent({
|
||||
provide(drawerBodyInjectionKey, null)
|
||||
provide(popoverBodyInjectionKey, null)
|
||||
return {
|
||||
NModal,
|
||||
mergedTheme: NModal.mergedThemeRef,
|
||||
appear: NModal.appearRef,
|
||||
isMounted: NModal.isMountedRef,
|
||||
cPrefix: NModal.cPrefixRef,
|
||||
bodyRef,
|
||||
scrollbarRef,
|
||||
displayed: displayedRef,
|
||||
@ -154,14 +157,14 @@ export default defineComponent({
|
||||
},
|
||||
render () {
|
||||
const {
|
||||
NModal,
|
||||
$slots,
|
||||
$attrs,
|
||||
handleEnter,
|
||||
handleAfterLeave,
|
||||
handleBeforeLeave,
|
||||
handleClickOutside,
|
||||
preset
|
||||
preset,
|
||||
cPrefix
|
||||
} = this
|
||||
let childNode: VNode | null = null
|
||||
if (!preset) {
|
||||
@ -172,7 +175,7 @@ export default defineComponent({
|
||||
}
|
||||
childNode.props = mergeProps(
|
||||
{
|
||||
class: 'n-modal'
|
||||
class: `${cPrefix}-modal`
|
||||
},
|
||||
$attrs,
|
||||
childNode.props || {}
|
||||
@ -180,18 +183,18 @@ export default defineComponent({
|
||||
}
|
||||
return this.displayDirective === 'show' || this.displayed || this.show
|
||||
? withDirectives(
|
||||
<div class="n-modal-body-wrapper">
|
||||
<div class={`${cPrefix}-modal-body-wrapper`}>
|
||||
<NScrollbar
|
||||
ref="scrollbarRef"
|
||||
theme={NModal.mergedTheme.peers.Scrollbar}
|
||||
themeOverrides={NModal.mergedTheme.peerOverrides.Scrollbar}
|
||||
contentClass="n-modal-scroll-content"
|
||||
theme={this.mergedTheme.peers.Scrollbar}
|
||||
themeOverrides={this.mergedTheme.peerOverrides.Scrollbar}
|
||||
contentClass={`${cPrefix}-modal-scroll-content`}
|
||||
>
|
||||
{{
|
||||
default: () => (
|
||||
<Transition
|
||||
name="n-fade-in-scale-up-transition"
|
||||
appear={NModal.appear ?? NModal.isMounted}
|
||||
appear={this.appear ?? this.isMounted}
|
||||
onEnter={handleEnter as any}
|
||||
onAfterLeave={handleAfterLeave}
|
||||
onBeforeLeave={handleBeforeLeave as any}
|
||||
@ -203,11 +206,11 @@ export default defineComponent({
|
||||
this.preset === 'dialog' ? (
|
||||
<NDialog
|
||||
{...this.$attrs}
|
||||
class="n-modal"
|
||||
class={`${cPrefix}-modal`}
|
||||
ref="bodyRef"
|
||||
theme={NModal.mergedTheme.peers.Dialog}
|
||||
theme={this.mergedTheme.peers.Dialog}
|
||||
themeOverrides={
|
||||
NModal.mergedTheme.peerOverrides.Dialog
|
||||
this.mergedTheme.peerOverrides.Dialog
|
||||
}
|
||||
{...keep(this.$props, dialogPropKeys)}
|
||||
>
|
||||
@ -217,10 +220,10 @@ export default defineComponent({
|
||||
<NCard
|
||||
{...this.$attrs}
|
||||
ref="bodyRef"
|
||||
class="n-modal"
|
||||
theme={NModal.mergedTheme.peers.Card}
|
||||
class={`${cPrefix}-modal`}
|
||||
theme={this.mergedTheme.peers.Card}
|
||||
themeOverrides={
|
||||
NModal.mergedTheme.peerOverrides.Card
|
||||
this.mergedTheme.peerOverrides.Card
|
||||
}
|
||||
{...keep(this.$props, cardBasePropKeys)}
|
||||
>
|
||||
|
@ -6,7 +6,6 @@ import {
|
||||
computed,
|
||||
defineComponent,
|
||||
provide,
|
||||
reactive,
|
||||
PropType,
|
||||
CSSProperties,
|
||||
toRef,
|
||||
@ -17,126 +16,125 @@ import { useIsMounted, useClicked, useClickPosition } from 'vooks'
|
||||
import { VLazyTeleport } from 'vueuc'
|
||||
import { dialogProviderInjectionKey } from '../../dialog/src/DialogProvider'
|
||||
import { useConfig, useTheme } from '../../_mixins'
|
||||
import type { ThemeProps, MergedTheme } from '../../_mixins'
|
||||
import { warn, keep, call } from '../../_utils'
|
||||
import type { ThemeProps } from '../../_mixins'
|
||||
import { warn, keep, call, ExtractPublicPropTypes } from '../../_utils'
|
||||
import type { MaybeArray } from '../../_utils'
|
||||
import { modalLight } from '../styles'
|
||||
import type { ModalTheme } from '../styles'
|
||||
import { presetProps, presetPropsKeys } from './presetProps'
|
||||
import NModalBodyWrapper from './BodyWrapper'
|
||||
import { modalInjectionKey } from './interface'
|
||||
import style from './styles/index.cssr'
|
||||
|
||||
export interface ModalInjection {
|
||||
getMousePosition: () => {
|
||||
x: number
|
||||
y: number
|
||||
} | null
|
||||
mergedTheme: MergedTheme<ModalTheme>
|
||||
isMounted: boolean
|
||||
appear: boolean | undefined
|
||||
const modalProps = {
|
||||
...(useTheme.props as ThemeProps<ModalTheme>),
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
unstableShowMask: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
maskClosable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
preset: String as PropType<'confirm' | 'dialog' | 'card'>,
|
||||
to: [String, Object] as PropType<string | HTMLElement>,
|
||||
displayDirective: {
|
||||
type: String as PropType<'if' | 'show'>,
|
||||
default: 'if'
|
||||
},
|
||||
...presetProps,
|
||||
// events
|
||||
// eslint-disable-next-line vue/prop-name-casing
|
||||
'onUpdate:show': [Function, Array] as PropType<
|
||||
MaybeArray<(value: boolean) => void>
|
||||
>,
|
||||
onUpdateShow: [Function, Array] as PropType<
|
||||
MaybeArray<(value: boolean) => void>
|
||||
>,
|
||||
// private
|
||||
dialog: Boolean,
|
||||
appear: {
|
||||
type: Boolean as PropType<boolean | undefined>,
|
||||
default: undefined
|
||||
},
|
||||
onBeforeLeave: Function as PropType<() => void>,
|
||||
onAfterLeave: Function as PropType<() => void>,
|
||||
onClose: Function as PropType<() => Promise<boolean> | boolean | any>,
|
||||
onPositiveClick: Function as PropType<() => Promise<boolean> | boolean | any>,
|
||||
onNegativeClick: Function as PropType<() => Promise<boolean> | boolean | any>,
|
||||
// deprecated
|
||||
overlayStyle: {
|
||||
type: [String, Object] as PropType<string | CSSProperties | undefined>,
|
||||
validator: () => {
|
||||
if (__DEV__) {
|
||||
warn(
|
||||
'modal',
|
||||
'`overlay-style` is deprecated, please use `style` instead.'
|
||||
)
|
||||
}
|
||||
return true
|
||||
},
|
||||
default: undefined
|
||||
},
|
||||
onBeforeHide: {
|
||||
type: (Function as unknown) as PropType<(() => void) | undefined>,
|
||||
validator: () => {
|
||||
if (__DEV__) {
|
||||
warn(
|
||||
'modal',
|
||||
'`on-before-hide` is deprecated, please use `on-before-leave` instead.'
|
||||
)
|
||||
}
|
||||
return true
|
||||
},
|
||||
default: undefined
|
||||
},
|
||||
onAfterHide: {
|
||||
type: (Function as unknown) as PropType<(() => void) | undefined>,
|
||||
validator: () => {
|
||||
if (__DEV__) {
|
||||
warn(
|
||||
'modal',
|
||||
'`on-after-hide` is deprecated, please use `on-after-leave` instead.'
|
||||
)
|
||||
}
|
||||
return true
|
||||
},
|
||||
default: undefined
|
||||
},
|
||||
onHide: {
|
||||
type: (Function as unknown) as PropType<
|
||||
((value: false) => void) | undefined
|
||||
>,
|
||||
validator: () => {
|
||||
if (__DEV__) warn('modal', '`on-hide` is deprecated.')
|
||||
return true
|
||||
},
|
||||
default: undefined
|
||||
}
|
||||
}
|
||||
|
||||
export type ModalProps = ExtractPublicPropTypes<typeof modalProps>
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Modal',
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
...(useTheme.props as ThemeProps<ModalTheme>),
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
unstableShowMask: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
maskClosable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
preset: String as PropType<'confirm' | 'dialog' | 'card'>,
|
||||
to: [String, Object] as PropType<string | HTMLElement>,
|
||||
displayDirective: {
|
||||
type: String as PropType<'if' | 'show'>,
|
||||
default: 'if'
|
||||
},
|
||||
...presetProps,
|
||||
// events
|
||||
// eslint-disable-next-line vue/prop-name-casing
|
||||
'onUpdate:show': [Function, Array] as PropType<
|
||||
MaybeArray<(value: boolean) => void>
|
||||
>,
|
||||
onUpdateShow: [Function, Array] as PropType<
|
||||
MaybeArray<(value: boolean) => void>
|
||||
>,
|
||||
// private
|
||||
dialog: Boolean,
|
||||
appear: {
|
||||
type: Boolean as PropType<boolean | undefined>,
|
||||
default: undefined
|
||||
},
|
||||
onBeforeLeave: Function as PropType<() => void>,
|
||||
onAfterLeave: Function as PropType<() => void>,
|
||||
onClose: Function as PropType<() => Promise<boolean> | boolean | any>,
|
||||
onPositiveClick: Function as PropType<
|
||||
() => Promise<boolean> | boolean | any
|
||||
>,
|
||||
onNegativeClick: Function as PropType<
|
||||
() => Promise<boolean> | boolean | any
|
||||
>,
|
||||
// deprecated
|
||||
overlayStyle: {
|
||||
type: [String, Object] as PropType<string | CSSProperties | undefined>,
|
||||
validator: () => {
|
||||
if (__DEV__) {
|
||||
warn(
|
||||
'modal',
|
||||
'`overlay-style` is deprecated, please use `style` instead.'
|
||||
)
|
||||
}
|
||||
return true
|
||||
},
|
||||
default: undefined
|
||||
},
|
||||
onBeforeHide: {
|
||||
type: (Function as unknown) as PropType<(() => void) | undefined>,
|
||||
validator: () => {
|
||||
if (__DEV__) {
|
||||
warn(
|
||||
'modal',
|
||||
'`on-before-hide` is deprecated, please use `on-before-leave` instead.'
|
||||
)
|
||||
}
|
||||
return true
|
||||
},
|
||||
default: undefined
|
||||
},
|
||||
onAfterHide: {
|
||||
type: (Function as unknown) as PropType<(() => void) | undefined>,
|
||||
validator: () => {
|
||||
if (__DEV__) {
|
||||
warn(
|
||||
'modal',
|
||||
'`on-after-hide` is deprecated, please use `on-after-leave` instead.'
|
||||
)
|
||||
}
|
||||
return true
|
||||
},
|
||||
default: undefined
|
||||
},
|
||||
onHide: {
|
||||
type: (Function as unknown) as PropType<
|
||||
((value: false) => void) | undefined
|
||||
>,
|
||||
validator: () => {
|
||||
if (__DEV__) warn('modal', '`on-hide` is deprecated.')
|
||||
return true
|
||||
},
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
props: modalProps,
|
||||
setup (props) {
|
||||
const containerRef = ref<HTMLElement | null>(null)
|
||||
const themeRef = useTheme('Modal', 'Modal', style, modalLight, props)
|
||||
const { mergedClsPrefix, namespace } = useConfig(props)
|
||||
const themeRef = useTheme(
|
||||
'Modal',
|
||||
'Modal',
|
||||
style,
|
||||
modalLight,
|
||||
props,
|
||||
mergedClsPrefix
|
||||
)
|
||||
const clickedRef = useClicked(64)
|
||||
const clickedPositionRef = useClickPosition()
|
||||
const isMountedRef = useIsMounted()
|
||||
@ -201,28 +199,26 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
}
|
||||
provide<ModalInjection>(
|
||||
'NModal',
|
||||
reactive({
|
||||
getMousePosition: () => {
|
||||
if (NDialogProvider) {
|
||||
if (NDialogProvider.clicked && NDialogProvider.clickPosition) {
|
||||
return NDialogProvider.clickPosition
|
||||
}
|
||||
provide(modalInjectionKey, {
|
||||
getMousePosition: () => {
|
||||
if (NDialogProvider) {
|
||||
if (NDialogProvider.clicked && NDialogProvider.clickPosition) {
|
||||
return NDialogProvider.clickPosition
|
||||
}
|
||||
if (clickedRef.value) {
|
||||
return clickedPositionRef.value
|
||||
}
|
||||
return null
|
||||
},
|
||||
mergedTheme: themeRef,
|
||||
isMounted: isMountedRef,
|
||||
appear: toRef(props, 'appear')
|
||||
})
|
||||
)
|
||||
provide('NDrawer', null)
|
||||
}
|
||||
if (clickedRef.value) {
|
||||
return clickedPositionRef.value
|
||||
}
|
||||
return null
|
||||
},
|
||||
cPrefixRef: mergedClsPrefix,
|
||||
mergedThemeRef: themeRef,
|
||||
isMountedRef: isMountedRef,
|
||||
appearRef: toRef(props, 'appear')
|
||||
})
|
||||
return {
|
||||
...useConfig(props),
|
||||
cPrefix: mergedClsPrefix,
|
||||
namespace,
|
||||
isMounted: isMountedRef,
|
||||
containerRef,
|
||||
presetProps: computed(() => {
|
||||
@ -264,7 +260,7 @@ export default defineComponent({
|
||||
'div',
|
||||
{
|
||||
ref: 'containerRef',
|
||||
class: ['n-modal-container', this.namespace],
|
||||
class: [`${this.cPrefix}-modal-container`, this.namespace],
|
||||
style: this.cssVars as CSSProperties
|
||||
},
|
||||
[
|
||||
@ -281,7 +277,7 @@ export default defineComponent({
|
||||
return this.show
|
||||
? h('div', {
|
||||
ref: 'containerRef',
|
||||
class: 'n-modal-mask'
|
||||
class: `${this.cPrefix}-modal-mask`
|
||||
})
|
||||
: null
|
||||
}
|
||||
|
@ -1,9 +1,24 @@
|
||||
import { Ref, ComponentPublicInstance, InjectionKey } from 'vue'
|
||||
import type { MergedTheme } from '../../_mixins'
|
||||
import type { ModalTheme } from '../styles'
|
||||
|
||||
export type ModalBodyInjection = Ref<
|
||||
HTMLElement | ComponentPublicInstance | null
|
||||
> | null
|
||||
|
||||
export const modalBodyInjectionKey: InjectionKey<ModalBodyInjection> = Symbol(
|
||||
'modalBodyInjection'
|
||||
'modalBody'
|
||||
)
|
||||
|
||||
export interface ModalInjection {
|
||||
getMousePosition: () => {
|
||||
x: number
|
||||
y: number
|
||||
} | null
|
||||
cPrefixRef: Ref<string>
|
||||
mergedThemeRef: Ref<MergedTheme<ModalTheme>>
|
||||
isMountedRef: Ref<boolean>
|
||||
appearRef: Ref<boolean | undefined>
|
||||
}
|
||||
|
||||
export const modalInjectionKey: InjectionKey<ModalInjection> = Symbol('modal')
|
||||
|
Loading…
Reference in New Issue
Block a user