diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 9731081bae5..2a84eff4d37 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -29,7 +29,7 @@ body:
id: reproduction
attributes:
label: Link to minimal reproduction
- description: Please provide a [minimal reproduction](https://stackoverflow.com/help/minimal-reproducible-example). Provide a streamlined CodePen/CodeSandbox or GitHub repository link. Please don't fill in a link randomly.
+ description: Please provide a [minimal reproduction](https://stackoverflow.com/help/minimal-reproducible-example). Provide a streamlined [Playground](https://play.pro-components.cn)/CodePen/CodeSandbox or GitHub repository link. Please don't fill in a link randomly.
placeholder: Reproduction
validations:
required: true
diff --git a/.github/ISSUE_TEMPLATE/bug_report.zh-CN.yml b/.github/ISSUE_TEMPLATE/bug_report.zh-CN.yml
index d045d91100f..0754bfae7d4 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.zh-CN.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.zh-CN.yml
@@ -29,7 +29,7 @@ body:
id: reproduction
attributes:
label: 最小复现链接
- description: 请提供[最小复现](https://stackoverflow.com/help/minimal-reproducible-example)链接。提供一个简化的 CodePen/CodeSandbox 或 GitHub 仓库链接。请不要随机填写链接。
+ description: 请提供[最小复现](https://stackoverflow.com/help/minimal-reproducible-example)链接。提供一个简化的 [Playground](https://play.pro-components.cn)/CodePen/CodeSandbox 或 GitHub 仓库链接。请不要随机填写链接。
placeholder: 复现链接
validations:
required: true
diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml
index 97dca1eb766..102a0ec5790 100644
--- a/.github/workflows/node.js.yml
+++ b/.github/workflows/node.js.yml
@@ -17,7 +17,7 @@ jobs:
strategy:
matrix:
- node-version: [18, 20]
+ node-version: [22]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v3
@@ -42,7 +42,7 @@ jobs:
strategy:
matrix:
- node-version: [18, 20]
+ node-version: [22]
steps:
- uses: actions/checkout@v3
diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md
index d3a3f62729d..742f704ca8d 100644
--- a/CHANGELOG.en-US.md
+++ b/CHANGELOG.en-US.md
@@ -2,10 +2,35 @@
## NEXT_VERSION
+### Breaking Changes
+
+- (**Vue 3.3+ required**) Add slot type for all components.
+
### i18n
- Add kmKH locale.
+### Features
+
+- `n-modal` adds `draggable` prop, closes [#6525](https://github.com/tusen-ai/naive-ui/issues/6525), [#5792](https://github.com/tusen-ai/naive-ui/issues/5792), [#5711](https://github.com/tusen-ai/naive-ui/issues/5711), [#5501](https://github.com/tusen-ai/naive-ui/issues/5501) and [#2152](https://github.com/tusen-ai/naive-ui/issues/2152).
+- `useDialog` supports `draggable` option.
+- `useModal` supports `draggable` option.
+
+### Fixes
+
+- Fix `n-data-table` may have multiple expand trigger with tree data.
+- Fix `n-date-picker`'s `confirm`, `now`, `clear` slots doesn't work with `'month'`, `'monthrange'`, `'quarter'`, `'quarterrange'`, `'year'` and `'yearrange'` type.
+- Fix `n-input`'s `render-count` prop doesn't work when type is not `'textarea'`.
+
+## 2.40.4
+
+`2024-12-20`
+
+### Fixes
+
+- Fix `inset` CSS property caused compatibility issues in some browsers, closes [#6604](https://github.com/tusen-ai/naive-ui/issues/6604),close [#6602](https://github.com/tusen-ai/naive-ui/issues/6602).
+- Fix memory leak problem when used with new version of vue. Note: After the fix you may still find memory leak in Chrome >= 129, since they introduced a bug, see https://github.com/vuejs/core/issues/12306, https://issues.chromium.org/issues/376777343
+
## 2.40.3
`2024-12-02`
diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md
index 29c29ab5196..2740c468397 100644
--- a/CHANGELOG.zh-CN.md
+++ b/CHANGELOG.zh-CN.md
@@ -2,10 +2,35 @@
## NEXT_VERSION
+### Breaking Changes
+
+- (需要 Vue 3.3+)为所有的组件增加插槽的类型标注
+
### i18n
- 添加 kmKH 国际化
+### Features
+
+- `n-modal` 新增 `draggable` 属性,关闭 [#6525](https://github.com/tusen-ai/naive-ui/issues/6525),[#5792](https://github.com/tusen-ai/naive-ui/issues/5792),[#5711](https://github.com/tusen-ai/naive-ui/issues/5711),[#5501](https://github.com/tusen-ai/naive-ui/issues/5501),[#2152](https://github.com/tusen-ai/naive-ui/issues/2152)
+- `useDialog` 支持 `draggable` 参数
+- `useModal` 支持 `draggable` 参数
+
+### Fixes
+
+- 修复 `n-data-table` 在使用树形数据的时候出现多个展开 icon
+- 修复 `n-date-picker` 的 `confirm`、`now`、`clear` 插槽对 `'month'`、`'monthrange'`、`'quarter'`、`'quarterrange'`、`'year'` 和 `'yearrange'` 类型不生效
+- 修复 `n-input` 的 `render-count` 属性在类型非 `'textarea'` 时不生效
+
+## 2.40.4
+
+`2024-12-20`
+
+### Fixes
+
+- 修复 `n-scrollbar`、`n-float-button`、`n-float-button-group`、`n-popover` 组件中的 `inset` 属性在部分浏览器中有兼容性问题,关闭 [#6604](https://github.com/tusen-ai/naive-ui/issues/6604),关闭 [#6602](https://github.com/tusen-ai/naive-ui/issues/6602)
+- 修复和较新版本 vue 配合使用时的内存泄露问题。注意:修复后你可能仍然会在 Chrome >= 129 中发现内存泄漏,因为他们引入了一个 bug,参考:https://github.com/vuejs/core/issues/12306 https://issues.chromium.org/issues/376777343
+
## 2.40.3
`2024-12-02`
diff --git a/package.json b/package.json
index b12d50542c5..82a4066a248 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "naive-ui",
- "version": "2.40.3",
+ "version": "2.40.4",
"packageManager": "pnpm@9.5.0",
"description": "A Vue 3 Component Library. Fairly Complete, Theme Customizable, Uses TypeScript, Fast",
"author": "07akioni",
@@ -101,9 +101,9 @@
"@rollup/plugin-terser": "^0.4.3",
"@types/estree": "^1.0.1",
"@types/jest": "^29.5.4",
- "@vicons/fluent": "^0.12.0",
- "@vicons/ionicons4": "^0.12.0",
- "@vicons/ionicons5": "^0.12.0",
+ "@vicons/fluent": "^0.13.0",
+ "@vicons/ionicons4": "^0.13.0",
+ "@vicons/ionicons5": "^0.13.0",
"@vitejs/plugin-vue": "^5.0.3",
"@vue/compiler-sfc": "^3.4.15",
"@vue/server-renderer": "^3.5.13",
diff --git a/scripts/utils/loader.js b/scripts/utils/loader.js
index 27f4d21ad91..668e55d4895 100644
--- a/scripts/utils/loader.js
+++ b/scripts/utils/loader.js
@@ -48,8 +48,8 @@ function getPartsOfMdDemo(tokens) {
function createBlockTemplate(tag, content, attrs) {
const attrsStr = attrs
? Object.keys(attrs).reduce((attrsStr, key) => {
- return `${attrsStr} ${key}="${attrs[key]}"`
- }, '')
+ return `${attrsStr} ${key}="${attrs[key]}"`
+ }, '')
: ''
return `<${tag}${attrsStr}>
${content}
diff --git a/src/_internal/icons/Attach.tsx b/src/_internal/icons/Attach.tsx
index 991cff956fb..f8a73584071 100644
--- a/src/_internal/icons/Attach.tsx
+++ b/src/_internal/icons/Attach.tsx
@@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
-export default replaceable(
- 'attach',
+export default replaceable('attach', () => (
-)
+))
diff --git a/src/_internal/icons/Cancel.tsx b/src/_internal/icons/Cancel.tsx
index f93c15c9fba..15b27a69c36 100644
--- a/src/_internal/icons/Cancel.tsx
+++ b/src/_internal/icons/Cancel.tsx
@@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
-export default replaceable(
- 'cancel',
+export default replaceable('cancel', () => (
-)
+))
diff --git a/src/_internal/icons/Clear.tsx b/src/_internal/icons/Clear.tsx
index b3b86232406..8e1e88897e6 100644
--- a/src/_internal/icons/Clear.tsx
+++ b/src/_internal/icons/Clear.tsx
@@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
-export default replaceable(
- 'clear',
+export default replaceable('clear', () => (
-)
+))
diff --git a/src/_internal/icons/Close.tsx b/src/_internal/icons/Close.tsx
index f1c418222cc..b605e01eabf 100644
--- a/src/_internal/icons/Close.tsx
+++ b/src/_internal/icons/Close.tsx
@@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
-export default replaceable(
- 'close',
+export default replaceable('close', () => (
-)
+))
diff --git a/src/_internal/icons/Date.tsx b/src/_internal/icons/Date.tsx
index 6f930cd15f8..a475960a962 100644
--- a/src/_internal/icons/Date.tsx
+++ b/src/_internal/icons/Date.tsx
@@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
-export default replaceable(
- 'date',
+export default replaceable('date', () => (
-)
+))
diff --git a/src/_internal/icons/Download.tsx b/src/_internal/icons/Download.tsx
index c2ba5f7c4e6..a1926ce6a75 100644
--- a/src/_internal/icons/Download.tsx
+++ b/src/_internal/icons/Download.tsx
@@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
-export default replaceable(
- 'download',
+export default replaceable('download', () => (
-)
+))
diff --git a/src/_internal/icons/Error.tsx b/src/_internal/icons/Error.tsx
index b3af34e1edd..390b44f65f6 100644
--- a/src/_internal/icons/Error.tsx
+++ b/src/_internal/icons/Error.tsx
@@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
-export default replaceable(
- 'error',
+export default replaceable('error', () => (
-)
+))
diff --git a/src/_internal/icons/Info.tsx b/src/_internal/icons/Info.tsx
index 42e098d79ac..104e82a3021 100644
--- a/src/_internal/icons/Info.tsx
+++ b/src/_internal/icons/Info.tsx
@@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
-export default replaceable(
- 'info',
+export default replaceable('info', () => (
-)
+))
diff --git a/src/_internal/icons/Retry.tsx b/src/_internal/icons/Retry.tsx
index f272847ecd8..7bc2e29faef 100644
--- a/src/_internal/icons/Retry.tsx
+++ b/src/_internal/icons/Retry.tsx
@@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
-export default replaceable(
- 'retry',
+export default replaceable('retry', () => (
-)
+))
diff --git a/src/_internal/icons/RotateClockwise.tsx b/src/_internal/icons/RotateClockwise.tsx
index 82d7decc12f..fcc1f83dbff 100644
--- a/src/_internal/icons/RotateClockwise.tsx
+++ b/src/_internal/icons/RotateClockwise.tsx
@@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
-export default replaceable(
- 'rotateClockwise',
+export default replaceable('rotateClockwise', () => (
-)
+))
diff --git a/src/_internal/icons/RotateCounterclockwise.tsx b/src/_internal/icons/RotateCounterclockwise.tsx
index 9bae8b0f904..68d44e60d3d 100644
--- a/src/_internal/icons/RotateCounterclockwise.tsx
+++ b/src/_internal/icons/RotateCounterclockwise.tsx
@@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
-export default replaceable(
- 'rotateClockwise',
+export default replaceable('rotateClockwise', () => (
-)
+))
diff --git a/src/_internal/icons/Success.tsx b/src/_internal/icons/Success.tsx
index 9798473af31..2a6da757d01 100644
--- a/src/_internal/icons/Success.tsx
+++ b/src/_internal/icons/Success.tsx
@@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
-export default replaceable(
- 'success',
+export default replaceable('success', () => (
-)
+))
diff --git a/src/_internal/icons/Time.tsx b/src/_internal/icons/Time.tsx
index e3f40debee4..1d4a91a05a6 100644
--- a/src/_internal/icons/Time.tsx
+++ b/src/_internal/icons/Time.tsx
@@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
-export default replaceable(
- 'time',
+export default replaceable('time', () => (
-)
+))
diff --git a/src/_internal/icons/To.tsx b/src/_internal/icons/To.tsx
index da531afcb78..06d9996581a 100644
--- a/src/_internal/icons/To.tsx
+++ b/src/_internal/icons/To.tsx
@@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
-export default replaceable(
- 'to',
+export default replaceable('to', () => (
-)
+))
diff --git a/src/_internal/icons/Trash.tsx b/src/_internal/icons/Trash.tsx
index 9a803494994..bf92702daf2 100644
--- a/src/_internal/icons/Trash.tsx
+++ b/src/_internal/icons/Trash.tsx
@@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
-export default replaceable(
- 'trash',
+export default replaceable('trash', () => (
-)
+))
diff --git a/src/_internal/icons/Warning.tsx b/src/_internal/icons/Warning.tsx
index 9579fc33503..e921cdaef1f 100644
--- a/src/_internal/icons/Warning.tsx
+++ b/src/_internal/icons/Warning.tsx
@@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
-export default replaceable(
- 'warning',
+export default replaceable('warning', () => (
-)
+))
diff --git a/src/_internal/icons/ZoomIn.tsx b/src/_internal/icons/ZoomIn.tsx
index 574003d0c46..02310e12aa7 100644
--- a/src/_internal/icons/ZoomIn.tsx
+++ b/src/_internal/icons/ZoomIn.tsx
@@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
-export default replaceable(
- 'zoomIn',
+export default replaceable('zoomIn', () => (
-)
+))
diff --git a/src/_internal/icons/ZoomOut.tsx b/src/_internal/icons/ZoomOut.tsx
index b56592b2279..14d1ccf21f7 100644
--- a/src/_internal/icons/ZoomOut.tsx
+++ b/src/_internal/icons/ZoomOut.tsx
@@ -1,8 +1,7 @@
import { h } from 'vue'
import { replaceable } from './replaceable'
-export default replaceable(
- 'zoomOut',
+export default replaceable('zoomOut', () => (
-)
+))
diff --git a/src/_internal/icons/replaceable.tsx b/src/_internal/icons/replaceable.tsx
index 377b3aa122d..7fdf7ce2fe2 100644
--- a/src/_internal/icons/replaceable.tsx
+++ b/src/_internal/icons/replaceable.tsx
@@ -1,9 +1,15 @@
+import type { VNode } from 'vue'
import type { GlobalIconConfig } from '../../config-provider/src/internal-interface'
import { upperFirst } from 'lodash-es'
-import { defineComponent, inject } from 'vue'
+import { defineComponent, h, inject } from 'vue'
import { configProviderInjectionKey } from '../../config-provider/src/context'
-export function replaceable(name: keyof GlobalIconConfig, icon: JSX.Element) {
+export function replaceable(name: keyof GlobalIconConfig, icon: () => VNode) {
+ const IconComponent = defineComponent({
+ render() {
+ return icon()
+ }
+ })
return defineComponent({
name: upperFirst(name),
setup() {
@@ -13,7 +19,7 @@ export function replaceable(name: keyof GlobalIconConfig, icon: JSX.Element) {
)?.mergedIconsRef
return () => {
const iconOverride = mergedIconsRef?.value?.[name]
- return iconOverride ? iconOverride() : icon
+ return iconOverride ? iconOverride() :