diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index ba3d5ba01e6..ef26025d2a7 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -1,5 +1,12 @@ # CHANGELOG +## 2.41.1 + +### Features + +- `n-progress` add `size` props. closes [#6650](https://github.com/tusen-ai/naive-ui/issues/6650) +- `n-progress` add `indeterminate`, `duration` props. closes [#6786](https://github.com/tusen-ai/naive-ui/issues/6786) + ## 2.41.0 `2025-01-05` diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index aee800ad1d2..a18d6ea43f6 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -1,5 +1,12 @@ # CHANGELOG +## 2.41.1 + +### Features + +- `n-progress` 新增 `size` 参数. 关闭 [#6650](https://github.com/tusen-ai/naive-ui/issues/6650) +- `n-progress` 新增 `indeterminate`, `duration` 参数. closes [#6786](https://github.com/tusen-ai/naive-ui/issues/6786) + ## 2.41.0 `2025-01-05` diff --git a/src/progress/demos/enUS/indeterminate.demo.vue b/src/progress/demos/enUS/indeterminate.demo.vue new file mode 100644 index 00000000000..4b75b37f0a2 --- /dev/null +++ b/src/progress/demos/enUS/indeterminate.demo.vue @@ -0,0 +1,15 @@ + +# Indeterminate progress + +Use `indeterminate` attribute to set indeterminate progress, with `duration` to control the animation duration. + + + diff --git a/src/progress/demos/enUS/index.demo-entry.md b/src/progress/demos/enUS/index.demo-entry.md index 13d8225a050..7aa3c4cf5bd 100644 --- a/src/progress/demos/enUS/index.demo-entry.md +++ b/src/progress/demos/enUS/index.demo-entry.md @@ -16,6 +16,8 @@ no-indicator.vue height.vue processing.vue gradient.vue +size.vue +indeterminate.vue ``` ## API @@ -42,7 +44,10 @@ gradient.vue | status | `'default' \| 'success' \| 'error' \| 'warning' \| 'info'` | `'default'` | Progress status. | | | stroke-width | `number` | `7` | Progress width. | | | type | `'line' \| 'circle' \| 'multiple-circle' \| 'dashboard'` | `line` | Progress type. | `'dashboard'` 2.25.2 | +| indeterminate | `boolean` | `false` | set indeterminate progress | 2.41.1 | +| duration | `number` | `3` | control the animation duration of indeterminate progress or striped flow progress | 2.41.1 | | unit | `string` | `%` | Progress unit. | | +| size | `'tiny' \| 'small' \| 'medium' \| 'large'` | `'medium'` | Progress size. | 2.41.1 | ### Progress Slots diff --git a/src/progress/demos/enUS/size.demo.vue b/src/progress/demos/enUS/size.demo.vue new file mode 100644 index 00000000000..c14cfffa52e --- /dev/null +++ b/src/progress/demos/enUS/size.demo.vue @@ -0,0 +1,100 @@ + +# Size + +Progress can be `tiny` `small`, `medium` and `large` in size. + + + + + diff --git a/src/progress/demos/zhCN/indeterminate.demo.vue b/src/progress/demos/zhCN/indeterminate.demo.vue new file mode 100644 index 00000000000..e6b9b815105 --- /dev/null +++ b/src/progress/demos/zhCN/indeterminate.demo.vue @@ -0,0 +1,15 @@ + +# 动画进度条 + +使用 `indeterminate` 属性来设置不确定的进度, `duration` 来控制动画持续时间 + + + diff --git a/src/progress/demos/zhCN/index.demo-entry.md b/src/progress/demos/zhCN/index.demo-entry.md index 1286060186d..3a81df88ee7 100644 --- a/src/progress/demos/zhCN/index.demo-entry.md +++ b/src/progress/demos/zhCN/index.demo-entry.md @@ -16,6 +16,8 @@ no-indicator.vue height.vue processing.vue gradient.vue +size.vue +indeterminate.vue ``` ## API @@ -42,7 +44,10 @@ gradient.vue | status | `'default' \| 'success' \| 'error' \| 'warning' \| 'info'` | `'default'` | 进度条状态 | | | stroke-width | `number` | `7` | 进度条宽度 | | | type | `'line' \| 'circle' \| 'multiple-circle' \| 'dashboard'` | `'line'` | 进度条类型 | `'dashboard'` 2.25.2 | +| indeterminate | `boolean` | `false` | 是否为动画进度条 | 2.41.1 | +| duration | `number` | `3` | 控制动画进度条速度和条纹进度条流动速度 | 2.41.1 | | unit | `string` | `%` | 进度条单位 | | +| size | `'tiny' \| 'small' \| 'medium' \| 'large'` | `'medium'` | 组件尺寸 | 2.41.1 | ### Progress Slots diff --git a/src/progress/demos/zhCN/size.demo.vue b/src/progress/demos/zhCN/size.demo.vue new file mode 100644 index 00000000000..2cc9cdaab41 --- /dev/null +++ b/src/progress/demos/zhCN/size.demo.vue @@ -0,0 +1,100 @@ + +# 尺寸 + +有 `tiny` `small`、`medium` 和 `large` 尺寸。 + + + + + diff --git a/src/progress/src/Line.tsx b/src/progress/src/Line.tsx index 02119598953..03bcba5e903 100644 --- a/src/progress/src/Line.tsx +++ b/src/progress/src/Line.tsx @@ -59,7 +59,8 @@ export default defineComponent({ }, height: [String, Number], railBorderRadius: [String, Number], - fillBorderRadius: [String, Number] + fillBorderRadius: [String, Number], + indeterminate: Boolean }, setup(props, { slots }) { const styleHeightRef = computed(() => { @@ -102,6 +103,7 @@ export default defineComponent({ status, showIndicator, processing, + indeterminate, clsPrefix } = props return ( @@ -133,7 +135,9 @@ export default defineComponent({ class={[ `${clsPrefix}-progress-graph-line-fill`, processing - && `${clsPrefix}-progress-graph-line-fill--processing` + && `${clsPrefix}-progress-graph-line-fill--processing`, + indeterminate + && `${clsPrefix}-progress-graph-line-fill--indeterminate` ]} style={{ maxWidth: `${props.percentage}%`, diff --git a/src/progress/src/Progress.tsx b/src/progress/src/Progress.tsx index 500c77e06b2..a69bd114372 100644 --- a/src/progress/src/Progress.tsx +++ b/src/progress/src/Progress.tsx @@ -1,12 +1,20 @@ import type { ThemeProps } from '../../_mixins' import type { ProgressTheme } from '../styles' -import type { ProgressGradient, ProgressStatus } from './public-types' +import type { + ProgressGradient, + ProgressSize, + ProgressStatus, + ProgressType +} from './public-types' +import { useMergedState } from 'vooks' import { computed, type CSSProperties, defineComponent, h, - type PropType + type PropType, + ref, + toRef } from 'vue' import { useConfig, useTheme, useThemeClass } from '../../_mixins' import { createKey, type ExtractPublicPropTypes } from '../../_utils' @@ -20,9 +28,7 @@ export const progressProps = { ...(useTheme.props as ThemeProps), processing: Boolean, type: { - type: String as PropType< - 'line' | 'circle' | 'multiple-circle' | 'dashboard' - >, + type: String as PropType, default: 'line' }, gapDegree: Number, @@ -68,6 +74,18 @@ export const progressProps = { type: Number, default: 1 }, + size: { + type: String as PropType, + default: 'medium' + }, + indeterminate: { + type: Boolean, + default: false + }, + duration: { + type: Number, + default: 3 + }, height: Number, borderRadius: [String, Number] as PropType, fillBorderRadius: [String, Number] as PropType, @@ -80,6 +98,10 @@ export default defineComponent({ name: 'Progress', props: progressProps, setup(props) { + const uncontrolledSizeRef = ref(props.size) + const controlledSizeRef = toRef(props, 'size') + const mergedSizeRef = useMergedState(controlledSizeRef, uncontrolledSizeRef) + const mergedIndicatorPlacementRef = computed(() => { return props.indicatorPlacement || props.indicatorPosition }) @@ -101,15 +123,13 @@ export default defineComponent({ props, mergedClsPrefixRef ) + const cssVarsRef = computed(() => { const { status } = props const { common: { cubicBezierEaseInOut }, self: { - fontSize, - fontSizeCircle, railColor, - railHeight, iconSizeCircle, iconSizeLine, textColorCircle, @@ -117,10 +137,19 @@ export default defineComponent({ textColorLineOuter, lineBgProcessing, fontWeightCircle, + [createKey('railHeight', mergedSizeRef.value)]: railHeight, + [createKey('circleWidth', mergedSizeRef.value)]: circleWidth, + [createKey('multipleCircleWidth', mergedSizeRef.value)]: + multipleCircleWidth, + [createKey('multipleCircleFontSize', mergedSizeRef.value)]: + multipleCircleFontSize, + [createKey('fontSizeCircle', mergedSizeRef.value)]: fontSizeCircle, + [createKey('fontSize', mergedSizeRef.value)]: fontSize, [createKey('iconColor', status)]: iconColor, [createKey('fillColor', status)]: fillColor } } = themeRef.value + return { '--n-bezier': cubicBezierEaseInOut, '--n-fill-color': fillColor, @@ -133,9 +162,13 @@ export default defineComponent({ '--n-line-bg-processing': lineBgProcessing, '--n-rail-color': railColor, '--n-rail-height': railHeight, + '--n-multiple-circle-width': multipleCircleWidth, + '--n-multiple-circle-font-size': multipleCircleFontSize, '--n-text-color-circle': textColorCircle, '--n-text-color-line-inner': textColorLineInner, - '--n-text-color-line-outer': textColorLineOuter + '--n-text-color-line-outer': textColorLineOuter, + '--n-circle-width': circleWidth, + '--n-progress-indeterminate-duration': `${props.duration}s` } }) const themeClassHandle = inlineThemeDisabled @@ -150,6 +183,8 @@ export default defineComponent({ mergedClsPrefix: mergedClsPrefixRef, mergedIndicatorPlacement: mergedIndicatorPlacementRef, gapDeg, + indeterminate: props.indeterminate, + cssVars: inlineThemeDisabled ? undefined : cssVarsRef, themeClass: themeClassHandle?.themeClass, onRender: themeClassHandle?.onRender @@ -180,6 +215,7 @@ export default defineComponent({ gapDeg, gapOffsetDegree, themeClass, + indeterminate, $slots, onRender } = this @@ -234,6 +270,7 @@ export default defineComponent({ railStyle={railStyle as any} percentage={percentage as number} processing={processing} + indeterminate={indeterminate} indicatorPlacement={mergedIndicatorPlacement} unit={unit} fillBorderRadius={fillBorderRadius} diff --git a/src/progress/src/public-types.ts b/src/progress/src/public-types.ts index 1548a48a15f..02f1350a067 100644 --- a/src/progress/src/public-types.ts +++ b/src/progress/src/public-types.ts @@ -7,3 +7,7 @@ export type ProgressStatus = export interface ProgressGradient { stops: string[] } + +export type ProgressSize = 'tiny' | 'small' | 'medium' | 'large' + +export type ProgressType = 'line' | 'circle' | 'multiple-circle' | 'dashboard' diff --git a/src/progress/src/styles/index.cssr.ts b/src/progress/src/styles/index.cssr.ts index 146becd3adf..f39583af708 100644 --- a/src/progress/src/styles/index.cssr.ts +++ b/src/progress/src/styles/index.cssr.ts @@ -55,9 +55,9 @@ export default c([ `) ]) ]), - cM('circle, dashboard', { - width: '120px' - }, [ + cM('circle, dashboard', ` + width: var(--n-circle-width) + `, [ cB('progress-custom-content', ` position: absolute; left: 50%; @@ -93,7 +93,7 @@ export default c([ `) ]), cM('multiple-circle', ` - width: 200px; + width: var(--n-multiple-circle-width); color: inherit; `, [ cB('progress-text', ` @@ -107,6 +107,7 @@ export default c([ align-items: center; justify-content: center; transition: color .3s var(--n-bezier); + font-size: var(--n-multiple-circle-font-size); `) ]), cB('progress-content', { @@ -213,7 +214,11 @@ export default c([ background-image: var(--n-line-bg-processing); animation: progress-processing-animation 2s var(--n-bezier) infinite; `) - ]) + ]), + cM('indeterminate', ` + transform: translateZ(0); + animation: indeterminate var(--n-progress-indeterminate-duration) infinite; + `) ]) ]) ]) @@ -244,5 +249,14 @@ export default c([ right: 0; opacity: 0; } + `), + c('@keyframes indeterminate', ` + 0% { + left: -100%; + } + + 100% { + left: 100%; + } `) ]) diff --git a/src/progress/styles/light.ts b/src/progress/styles/light.ts index e3d1cd0e72c..4e652c27d2d 100644 --- a/src/progress/styles/light.ts +++ b/src/progress/styles/light.ts @@ -10,15 +10,39 @@ export function self(vars: ThemeCommonVars) { errorColor, textColor2, progressRailColor, - fontSize, + fontSizeTiny, + fontSizeSmall, + fontSizeMedium, + fontSizeLarge, fontWeight } = vars return { - fontSize, - fontSizeCircle: '28px', + fontSizeTiny, + fontSizeSmall, + fontSizeMedium, + fontSizeLarge, + fontSizeCircleTiny: '9px', + fontSizeCircleSmall: '15px', + fontSizeCircleMedium: '28px', + fontSizeCircleLarge: '32px', fontWeightCircle: fontWeight, railColor: progressRailColor, - railHeight: '8px', + railHeightTiny: '3px', + railHeightSmall: '6px', + railHeightMedium: '8px', + railHeightLarge: '12px', + circleWidthTiny: '40px', + circleWidthSmall: '60px', + circleWidthMedium: '120px', + circleWidthLarge: '200px', + multipleCircleWidthTiny: '60px', + multipleCircleWidthSmall: '120px', + multipleCircleWidthMedium: '200px', + multipleCircleWidthLarge: '250px', + multipleCircleFontSizeTiny: '8px', + multipleCircleFontSizeSmall: '10px', + multipleCircleFontSizeMedium: '14px', + multipleCircleFontSizeLarge: '20px', iconSizeCircle: '36px', iconSizeLine: '18px', iconColor: infoColor, diff --git a/volar.d.ts b/volar.d.ts index 85665f4de32..4213df01f2e 100644 --- a/volar.d.ts +++ b/volar.d.ts @@ -68,6 +68,7 @@ declare module 'vue' { NH4: (typeof import('naive-ui'))['NH4'] NH5: (typeof import('naive-ui'))['NH5'] NH6: (typeof import('naive-ui'))['NH6'] + NHighlight: (typeof import('naive-ui'))['NHighlight'] NHr: (typeof import('naive-ui'))['NHr'] NIcon: (typeof import('naive-ui'))['NIcon'] NIconWrapper: (typeof import('naive-ui'))['NIconWrapper'] @@ -89,6 +90,7 @@ declare module 'vue' { NListItem: (typeof import('naive-ui'))['NListItem'] NLoadingBarProvider: (typeof import('naive-ui'))['NLoadingBarProvider'] NLog: (typeof import('naive-ui'))['NLog'] + NMarquee: (typeof import('naive-ui'))['NMarquee'] NMention: (typeof import('naive-ui'))['NMention'] NMenu: (typeof import('naive-ui'))['NMenu'] NMessageProvider: (typeof import('naive-ui'))['NMessageProvider'] @@ -150,8 +152,6 @@ declare module 'vue' { NUploadTrigger: (typeof import('naive-ui'))['NUploadTrigger'] NVirtualList: (typeof import('naive-ui'))['NVirtualList'] NWatermark: (typeof import('naive-ui'))['NWatermark'] - NHighlight: (typeof import('naive-ui'))['NHighlight'] - NMarquee: (typeof import('naive-ui'))['NMarquee'] } } export {}