diff --git a/docs/en-US/component/notification.md b/docs/en-US/component/notification.md
index 15ecb1ae41..6dcefef9f3 100644
--- a/docs/en-US/component/notification.md
+++ b/docs/en-US/component/notification.md
@@ -100,7 +100,7 @@ ElNotification({
})
```
-In this case you should call `ElNotification(options)`. We have also registered methods for different types, e.g. `ElNotification.success(options)`. You can call `ElNotification.closeAll()` to manually close all the instances.
+In this case you should call `ElNotification(options)`. We have also registered methods for different types, e.g. `ElNotification.success(options)`. You can call `ElNotification.closeAll()` to manually close all the instances. In ^(2.10.5) you can manually update the offsets of all instances in a specific direction by calling `ElNotification.updateOffsets(position)`.
## App context inheritance > 2.0.4
diff --git a/packages/components/notification/__tests__/notify.test.tsx b/packages/components/notification/__tests__/notify.test.tsx
index 5879d7def5..9fb9798699 100644
--- a/packages/components/notification/__tests__/notify.test.tsx
+++ b/packages/components/notification/__tests__/notify.test.tsx
@@ -1,7 +1,8 @@
import { createApp, nextTick } from 'vue'
import { afterEach, describe, expect, it, vi } from 'vitest'
import { rAF } from '@element-plus/test-utils/tick'
-import Notification, { closeAll } from '../src/notify'
+import Notification, { closeAll, updateOffsets } from '../src/notify'
+import defineGetter from '@element-plus/test-utils/define-getter'
import type { NotificationHandle } from '../src/notification'
import type { VNode } from 'vue'
@@ -89,6 +90,59 @@ describe('Notification on command', () => {
expect(document.querySelectorAll(selector).length).toBe(0)
})
+ it('it should update offsets notifications', async () => {
+ // the gap size between each notification
+ const GAP_SIZE = 16
+ const height = 100
+ const notifications: NotificationHandle[] = []
+ const cleanups: (() => void)[] = []
+
+ for (let i = 0; i < 4; i++) {
+ notifications.push(Notification({ duration: 0 }))
+
+ await nextTick()
+
+ const el = document.querySelector(`${selector}:nth-child(${i + 1})`)!
+
+ // mocking offsetHeight
+ cleanups.push(
+ defineGetter(el, 'offsetHeight', function (this: HTMLElement) {
+ return Number.parseFloat(this.style.height) || height
+ })
+ )
+ }
+
+ await rAF()
+
+ const notificationEls = Array.from(
+ document.querySelectorAll(selector)
+ )
+
+ expect(notificationEls.length).toBe(4)
+
+ const getOffsets = () => notificationEls.map((el) => el?.style.top || '0')
+
+ expect(getOffsets()).toEqual(
+ Array.from({ length: 4 }).map(
+ (_, i) => `${(i + 1) * GAP_SIZE + i * height}px`
+ )
+ )
+
+ notificationEls[0]?.style.setProperty('height', '150px')
+
+ updateOffsets('top-right')
+
+ await rAF()
+
+ expect(getOffsets()).toEqual(
+ Array.from({ length: 4 }).map(
+ (_, i) => `${(i + 1) * GAP_SIZE + i * height + (i > 0 ? 50 : 0)}px`
+ )
+ )
+
+ cleanups.forEach((fn) => fn())
+ })
+
it('it should be able to render all types notification', () => {
for (const type of ['success', 'warning', 'error', 'info'] as const) {
Notification[type]({})
diff --git a/packages/components/notification/src/notification.ts b/packages/components/notification/src/notification.ts
index e50614a589..1fc7cd32f8 100644
--- a/packages/components/notification/src/notification.ts
+++ b/packages/components/notification/src/notification.ts
@@ -163,6 +163,7 @@ export interface NotifyFn {
appContext?: null | AppContext
): NotificationHandle
closeAll(): void
+ updateOffsets(position?: NotificationOptions['position']): void
_context: AppContext | null
}
diff --git a/packages/components/notification/src/notify.ts b/packages/components/notification/src/notify.ts
index 618138f6d6..a2ced312f7 100644
--- a/packages/components/notification/src/notify.ts
+++ b/packages/components/notification/src/notify.ts
@@ -170,7 +170,19 @@ export function closeAll(): void {
}
}
+export function updateOffsets(
+ position: NotificationOptions['position'] = 'top-right'
+) {
+ let verticalOffset = notifications[position][0]?.vm.props?.offset || 0
+
+ for (const { vm } of notifications[position]) {
+ vm.component!.props.offset = verticalOffset
+ verticalOffset += (vm.el?.offsetHeight || 0) + GAP_SIZE
+ }
+}
+
notify.closeAll = closeAll
+notify.updateOffsets = updateOffsets
notify._context = null
export default notify as Notify