diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md
index c17a08b47..8e0d1e3b9 100644
--- a/CHANGELOG.en-US.md
+++ b/CHANGELOG.en-US.md
@@ -1,5 +1,11 @@
# CHANGELOG
+## Pending
+
+### Feats
+
+- `n-modal` add `transform-origin` prop, closes [#1498](https://github.com/TuSimple/naive-ui/issues/1498).
+
## 2.20.1 (2021-11-01)
### Fixes
diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md
index cadeee8cd..28f779ffb 100644
--- a/CHANGELOG.zh-CN.md
+++ b/CHANGELOG.zh-CN.md
@@ -1,5 +1,11 @@
# CHANGELOG
+## Pending
+
+### Feats
+
+- `n-modal` 新增 `transform-origin` 属性,关闭 [#1498](https://github.com/TuSimple/naive-ui/issues/1498)
+
## 2.20.1 (2021-11-01)
### Fixes
diff --git a/src/modal/demos/enUS/index.demo-entry.md b/src/modal/demos/enUS/index.demo-entry.md
index 125ad1d12..624674ac0 100644
--- a/src/modal/demos/enUS/index.demo-entry.md
+++ b/src/modal/demos/enUS/index.demo-entry.md
@@ -12,6 +12,7 @@ custom-position
preset-card
preset-confirm
preset-confirm-slot
+transform-origin
```
## API
@@ -24,6 +25,7 @@ preset-confirm-slot
| mask-closable | `boolean` | `true` | Whether to emit `hide` event when click mask. |
| preset | `'card' \| 'confirm'` | `undefined` | The preset of `n-modal`. |
| show | `boolean` | `false` | Whether to show modal. |
+| transform-origin | `'mouse' \| 'center'` | `'mouse'` | The transform origin of the modal's display animation. |
| on-update:show | `(value: boolean) => void` | `undefined` | Callback when modal's display status is changed. |
| on-after-enter | `() => void` | `undefined` | Callback after modal is opened. |
| on-after-leave | `() => void` | `undefined` | Callback after modal is closed. |
diff --git a/src/modal/demos/enUS/transform-origin.demo.md b/src/modal/demos/enUS/transform-origin.demo.md
new file mode 100644
index 000000000..b3f55faf2
--- /dev/null
+++ b/src/modal/demos/enUS/transform-origin.demo.md
@@ -0,0 +1,26 @@
+# Transform Origin
+
+Although the emerging animation from your click position is cool, sometimes we need a plain animation which occurs from the center of the screen. You can set `transfrom-origin` to `'center'` to achieve it.
+
+```html
+Nothing
+
+
+ Great
+ Fine
+ Nice
+
+
+```
+
+```js
+import { defineComponent, ref } from 'vue'
+
+export default defineComponent({
+ setup () {
+ return {
+ showModal: ref(false)
+ }
+ }
+})
+```
diff --git a/src/modal/demos/zhCN/index.demo-entry.md b/src/modal/demos/zhCN/index.demo-entry.md
index 2761712f6..ee1acefb7 100644
--- a/src/modal/demos/zhCN/index.demo-entry.md
+++ b/src/modal/demos/zhCN/index.demo-entry.md
@@ -12,6 +12,7 @@ custom-position
preset-card
preset-confirm
preset-confirm-slot
+transform-origin
raw-debug
dark-1-debug
dark-2-debug
@@ -36,6 +37,7 @@ dark-10-debug
| mask-closable | `boolean` | `true` | 点击遮罩时是否发出 `update:show` 事件 |
| preset | `'card' \| 'dialog'` | `undefined` | 模态框使用何种预设 |
| show | `boolean` | `false` | 是否展示 Modal |
+| transform-origin | `'mouse' \| 'center'` | `'mouse'` | 模态框动画出现的位置 |
| on-update:show | `(value: boolean) => void` | `undefined` | 模态框更新是否展示状态的回调 |
| on-after-enter | `() => void` | `undefined` | Modal 出现后的回调 |
| on-after-leave | `() => void` | `undefined` | Modal 关闭后的回调 |
diff --git a/src/modal/demos/zhCN/transform-origin.demo.md b/src/modal/demos/zhCN/transform-origin.demo.md
new file mode 100644
index 000000000..23d3c47e8
--- /dev/null
+++ b/src/modal/demos/zhCN/transform-origin.demo.md
@@ -0,0 +1,26 @@
+# 出现位置
+
+虽然从鼠标位置出现的动画看起来很酷,但是我们有时也想要一些朴实无华的从屏幕中间弹出来的动画。这时你可以将 `transform-origin` 设为 `'center'`。
+
+```html
+没什么的
+
+
+ 按需
+ 原则
+ 支持一下
+
+
+```
+
+```js
+import { defineComponent, ref } from 'vue'
+
+export default defineComponent({
+ setup () {
+ return {
+ showModal: ref(false)
+ }
+ }
+})
+```
diff --git a/src/modal/src/BodyWrapper.tsx b/src/modal/src/BodyWrapper.tsx
index 3bb0662f8..9264172b2 100644
--- a/src/modal/src/BodyWrapper.tsx
+++ b/src/modal/src/BodyWrapper.tsx
@@ -81,6 +81,9 @@ export default defineComponent({
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const NModal = inject(modalInjectionKey)!
function styleTransformOrigin (): string {
+ if (NModal.transformOriginRef.value === 'center') {
+ return ''
+ }
const { value: transformOriginX } = transformOriginXRef
const { value: transformOriginY } = transformOriginYRef
if (transformOriginX === null || transformOriginY === null) {
@@ -92,6 +95,9 @@ export default defineComponent({
return ''
}
function syncTransformOrigin (el: HTMLElement): void {
+ if (NModal.transformOriginRef.value === 'center') {
+ return
+ }
const mousePosition = NModal.getMousePosition()
if (!mousePosition) {
return
diff --git a/src/modal/src/Modal.tsx b/src/modal/src/Modal.tsx
index d96695102..d0936ab52 100644
--- a/src/modal/src/Modal.tsx
+++ b/src/modal/src/Modal.tsx
@@ -43,6 +43,10 @@ const modalProps = {
type: String as PropType<'if' | 'show'>,
default: 'if'
},
+ transformOrigin: {
+ type: String as PropType<'center' | 'mouse'>,
+ default: 'mouse'
+ },
...presetProps,
// events
'onUpdate:show': [Function, Array] as PropType<
@@ -196,7 +200,8 @@ export default defineComponent({
mergedClsPrefixRef,
mergedThemeRef: themeRef,
isMountedRef,
- appearRef: toRef(props, 'appear')
+ appearRef: toRef(props, 'appear'),
+ transformOriginRef: toRef(props, 'transformOrigin')
})
return {
mergedClsPrefix: mergedClsPrefixRef,
diff --git a/src/modal/src/interface.ts b/src/modal/src/interface.ts
index 659ee3e45..0d7daafe6 100644
--- a/src/modal/src/interface.ts
+++ b/src/modal/src/interface.ts
@@ -6,9 +6,8 @@ export type ModalBodyInjection = Ref<
HTMLElement | ComponentPublicInstance | null
> | null
-export const modalBodyInjectionKey: InjectionKey = Symbol(
- 'modalBody'
-)
+export const modalBodyInjectionKey: InjectionKey =
+ Symbol('modalBody')
export interface ModalInjection {
getMousePosition: () => {
@@ -19,6 +18,7 @@ export interface ModalInjection {
mergedThemeRef: Ref>
isMountedRef: Ref
appearRef: Ref
+ transformOriginRef: Ref<'mouse' | 'center'>
}
export const modalInjectionKey: InjectionKey = Symbol('modal')