mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-02-17 13:20:52 +08:00
feat(progress): type prop support dashboard (#2365)
* feat(progress): type props adds dashboard type * Update src/progress/demos/enUS/index.demo-entry.md Co-authored-by: gang.yang <gang.yang@tusimple.ai> Co-authored-by: 07akioni <07akioni2@gmail.com>
This commit is contained in:
parent
aefa598bbd
commit
a9d6e1d3e5
@ -11,6 +11,7 @@
|
||||
|
||||
### Feats
|
||||
|
||||
- `n-progress` props `type` add type `dashboard`.
|
||||
- `n-select` adds `clearFilterAfterSelect` prop, closes [#2352](https://github.com/TuSimple/naive-ui/issues/2352).
|
||||
|
||||
### i18n
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
### Feats
|
||||
|
||||
- `n-progress` 的 `type` 属性新增 `dashboard` 类型
|
||||
- `n-select` 新增 `clearFilterAfterSelect` 属性,关闭 [#2352](https://github.com/TuSimple/naive-ui/issues/2352)
|
||||
|
||||
### i18n
|
||||
|
17
src/progress/demos/enUS/dashboard.demo.vue
Normal file
17
src/progress/demos/enUS/dashboard.demo.vue
Normal file
@ -0,0 +1,17 @@
|
||||
<markdown>
|
||||
# Dashboard
|
||||
Maybe you also need `gapDegree` and `gapPosition` properties to customize the dashboard
|
||||
|
||||
</markdown>
|
||||
|
||||
<template>
|
||||
<n-space>
|
||||
<n-progress type="dashboard" gap-position="bottom" :percentage="50" />
|
||||
<n-progress
|
||||
type="dashboard"
|
||||
gap-position="bottom"
|
||||
:gap-degree="90"
|
||||
:percentage="50"
|
||||
/>
|
||||
</n-space>
|
||||
</template>
|
@ -9,6 +9,7 @@ circle
|
||||
line
|
||||
circle-offset.vue
|
||||
multiple-circle
|
||||
dashboard.vue
|
||||
custom-indicator
|
||||
color
|
||||
no-indicator
|
||||
@ -26,6 +27,8 @@ processing
|
||||
| circle-gap | `number` | `1` | The gap between circles when type is `'multiple-circle'`, suppose `viewbox` size is `100`. | |
|
||||
| color | `string \| string[]` | `undefined` | Progress color. | |
|
||||
| fill-border-radius | `number \| string` | `undefined` | `'line'` typed progress's fill's border-radius. Keep `border-radius` if not passed. | |
|
||||
| gap-degree | `number` | `0` | The gap degree of half circle, 0 ~ 360. | |
|
||||
| gap-position | `'top' \| 'bottom' \| 'left' \| 'right'` | `'top'` | The gap position. | |
|
||||
| height | `number` | `undefined` | `'line'` typed progress's height. Keep default height if not passed. | |
|
||||
| indicator-placement | `'inside' \| 'outside'` | `'outside'` | Indicator placement. | |
|
||||
| indicator-text-color | `string` | `undefined` | Indicator text color. | |
|
||||
@ -37,7 +40,7 @@ processing
|
||||
| show-indicator | `boolean` | `true` | Whether to display indicators. | |
|
||||
| status | `'default' \| 'success' \| 'error' \| 'warning' \| 'info'` | `'default'` | Progress status. | |
|
||||
| stroke-width | `number` | `7` | Progress width. | |
|
||||
| type | `'line' \| 'circle' \| 'multiple-circle'` | `line` | Progress type. | |
|
||||
| type | `'line' \| 'circle' \| 'multiple-circle' \| 'dashboard'` | `line` | Progress type. | |
|
||||
| unit | `string` | `%` | Progress unit. | |
|
||||
|
||||
### Progress Slots
|
||||
|
17
src/progress/demos/zhCN/dashboard.demo.vue
Normal file
17
src/progress/demos/zhCN/dashboard.demo.vue
Normal file
@ -0,0 +1,17 @@
|
||||
<markdown>
|
||||
# 仪表盘
|
||||
可能你还需要`gapDegree` 和 `gapPosition` 两个属性来自定义仪表盘
|
||||
|
||||
</markdown>
|
||||
|
||||
<template>
|
||||
<n-space>
|
||||
<n-progress type="dashboard" gap-position="bottom" :percentage="50" />
|
||||
<n-progress
|
||||
type="dashboard"
|
||||
gap-position="bottom"
|
||||
:gap-degree="90"
|
||||
:percentage="50"
|
||||
/>
|
||||
</n-space>
|
||||
</template>
|
@ -9,6 +9,7 @@ circle
|
||||
line
|
||||
circle-offset.vue
|
||||
multiple-circle
|
||||
dashboard.vue
|
||||
custom-indicator
|
||||
color
|
||||
no-indicator
|
||||
@ -26,6 +27,8 @@ processing
|
||||
| circle-gap | `number` | `1` | 当类型是 `'multiple-circle'` 的时候圈之间的距离,假设 `viewbox` 的尺寸是 `100` | |
|
||||
| color | `string \| string[]` | `undefined` | 进度条颜色 | |
|
||||
| fill-border-radius | `number \| string` | `undefined` | `'line'` 类型进度条填充的圆角半径,不填写则维持 `border-radius` | |
|
||||
| gap-degree | `number` | `0` | 仪表盘进度条缺口角度,取值范围 0 ~ 360 | |
|
||||
| gap-position | `'top' \| 'bottom' \| 'left' \| 'right'` | `'top'` | 仪表盘进度条缺口位置 | |
|
||||
| height | `number` | `undefined` | `'line'` 类型进度条的高度,不填写则维持默认高度 | |
|
||||
| indicator-placement | `'inside' \| 'outside'` | `'outside'` | 设置指标位置 | |
|
||||
| indicator-text-color | `string` | `undefined` | 指标文本颜色 | |
|
||||
@ -37,7 +40,7 @@ processing
|
||||
| show-indicator | `boolean` | `true` | 是否显示指标 | |
|
||||
| status | `'default' \| 'success' \| 'error' \| 'warning' \| 'info'` | `'default'` | 进度条状态 | |
|
||||
| stroke-width | `number` | `7` | 进度条宽度 | |
|
||||
| type | `'line' \| 'circle' \| 'multiple-circle'` | `line` | 进度条类型 | |
|
||||
| type | `'line' \| 'circle' \| 'multiple-circle' \| 'dashboard'` | `line` | 进度条类型 | |
|
||||
| unit | `string` | `%` | 进度条单位 | |
|
||||
|
||||
### Progress Slots
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { h, defineComponent, PropType, computed, CSSProperties } from 'vue'
|
||||
import { h, defineComponent, PropType, CSSProperties } from 'vue'
|
||||
import { NBaseIcon } from '../../_internal'
|
||||
import {
|
||||
SuccessIcon,
|
||||
@ -43,28 +43,79 @@ export default defineComponent({
|
||||
},
|
||||
showIndicator: {
|
||||
type: Boolean,
|
||||
reqiuired: true
|
||||
required: true
|
||||
},
|
||||
indicatorTextColor: String,
|
||||
unit: String,
|
||||
viewBoxWidth: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
gapDegree: {
|
||||
type: Number as PropType<number>,
|
||||
default: 0
|
||||
},
|
||||
gapPosition: {
|
||||
type: String as PropType<'top' | 'bottom' | 'left' | 'right'>,
|
||||
default: 'bottom'
|
||||
}
|
||||
},
|
||||
setup (props, { slots }) {
|
||||
const strokeDasharrayRef = computed(() => {
|
||||
return `${Math.PI * props.percentage}, ${props.viewBoxWidth * 8}`
|
||||
})
|
||||
const strokeDashoffsetRef = computed(() => {
|
||||
return `-${(Math.PI / 3.6) * props.offsetDegree}`
|
||||
})
|
||||
function getPathStyles (
|
||||
percent: number,
|
||||
offsetDegree: number,
|
||||
strokeColor?: string
|
||||
): { pathString: string, pathStyle: CSSProperties } {
|
||||
const { gapPosition, gapDegree, railStyle, viewBoxWidth } = props
|
||||
const radius = 50
|
||||
let beginPositionX = 0
|
||||
let beginPositionY = -radius
|
||||
let endPositionX = 0
|
||||
let endPositionY = -2 * radius
|
||||
switch (gapPosition) {
|
||||
case 'left':
|
||||
beginPositionX = -radius
|
||||
beginPositionY = 0
|
||||
endPositionX = 2 * radius
|
||||
endPositionY = 0
|
||||
break
|
||||
case 'right':
|
||||
beginPositionX = radius
|
||||
beginPositionY = 0
|
||||
endPositionX = -2 * radius
|
||||
endPositionY = 0
|
||||
break
|
||||
case 'bottom':
|
||||
beginPositionY = radius
|
||||
endPositionY = 2 * radius
|
||||
break
|
||||
default:
|
||||
}
|
||||
const pathString = `M 55,55 m ${beginPositionX},${beginPositionY}
|
||||
a ${radius},${radius} 0 1 1 ${endPositionX},${-endPositionY}
|
||||
a ${radius},${radius} 0 1 1 ${-endPositionX},${endPositionY}`
|
||||
const len = Math.PI * 2 * radius
|
||||
const pathStyle = {
|
||||
stroke: strokeColor,
|
||||
strokeDasharray: `${(percent / 100) * (len - gapDegree)}px ${
|
||||
viewBoxWidth * 8
|
||||
}px`,
|
||||
strokeDashoffset: `-${
|
||||
gapDegree / 2 + (Math.PI / 3.6) * offsetDegree
|
||||
}px`,
|
||||
railStyle
|
||||
}
|
||||
return {
|
||||
pathString,
|
||||
pathStyle
|
||||
}
|
||||
}
|
||||
return () => {
|
||||
const {
|
||||
fillColor,
|
||||
railColor,
|
||||
railStyle,
|
||||
strokeWidth,
|
||||
offsetDegree,
|
||||
status,
|
||||
percentage,
|
||||
showIndicator,
|
||||
@ -72,6 +123,10 @@ export default defineComponent({
|
||||
unit,
|
||||
clsPrefix
|
||||
} = props
|
||||
const { pathString: railPathString, pathStyle: railPathStyle } =
|
||||
getPathStyles(100, 0, railColor)
|
||||
const { pathString: fillPathString, pathStyle: fillPathStyle } =
|
||||
getPathStyles(percentage, offsetDegree, fillColor)
|
||||
return (
|
||||
<div class={`${clsPrefix}-progress-content`} role="none">
|
||||
<div class={`${clsPrefix}-progress-graph`} aria-hidden>
|
||||
@ -80,19 +135,11 @@ export default defineComponent({
|
||||
<g>
|
||||
<path
|
||||
class={`${clsPrefix}-progress-graph-circle-rail`}
|
||||
d="m 55 5 a 50 50 0 1 1 0 100 a 50 50 0 1 1 0 -100"
|
||||
stroke-width={strokeWidth * 1.1}
|
||||
d={railPathString}
|
||||
stroke-width={strokeWidth}
|
||||
stroke-linecap="round"
|
||||
fill="none"
|
||||
style={
|
||||
[
|
||||
{
|
||||
strokeDashoffset: 0,
|
||||
stroke: railColor
|
||||
},
|
||||
railStyle
|
||||
] as any
|
||||
}
|
||||
style={railPathStyle}
|
||||
/>
|
||||
</g>
|
||||
<g>
|
||||
@ -102,15 +149,11 @@ export default defineComponent({
|
||||
percentage === 0 &&
|
||||
`${clsPrefix}-progress-graph-circle-fill--empty`
|
||||
]}
|
||||
d="m 55 5 a 50 50 0 1 1 0 100 a 50 50 0 1 1 0 -100"
|
||||
stroke-width={strokeWidth * 1.1}
|
||||
d={fillPathString}
|
||||
stroke-width={strokeWidth}
|
||||
stroke-linecap="round"
|
||||
fill="none"
|
||||
style={{
|
||||
strokeDasharray: strokeDasharrayRef.value,
|
||||
strokeDashoffset: strokeDashoffsetRef.value,
|
||||
stroke: fillColor
|
||||
}}
|
||||
style={fillPathStyle}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
|
@ -14,9 +14,16 @@ const progressProps = {
|
||||
...(useTheme.props as ThemeProps<ProgressTheme>),
|
||||
processing: Boolean,
|
||||
type: {
|
||||
type: String as PropType<'line' | 'circle' | 'multiple-circle'>,
|
||||
type: String as PropType<
|
||||
'line' | 'circle' | 'multiple-circle' | 'dashboard'
|
||||
>,
|
||||
default: 'line'
|
||||
},
|
||||
gapDegree: Number as PropType<number>,
|
||||
gapPosition: {
|
||||
type: String as PropType<'top' | 'bottom' | 'left' | 'right'>,
|
||||
default: 'top'
|
||||
},
|
||||
status: {
|
||||
type: String as PropType<Status>,
|
||||
default: 'default'
|
||||
@ -71,6 +78,15 @@ export default defineComponent({
|
||||
const mergedIndicatorPlacementRef = computed(() => {
|
||||
return props.indicatorPlacement || props.indicatorPosition
|
||||
})
|
||||
const gapDeg = computed(() => {
|
||||
if (props.gapDegree || props.gapDegree === 0) {
|
||||
return props.gapDegree
|
||||
}
|
||||
if (props.type === 'dashboard') {
|
||||
return 75
|
||||
}
|
||||
return undefined
|
||||
})
|
||||
const { mergedClsPrefixRef } = useConfig(props)
|
||||
const themeRef = useTheme(
|
||||
'Progress',
|
||||
@ -83,6 +99,7 @@ export default defineComponent({
|
||||
return {
|
||||
mergedClsPrefix: mergedClsPrefixRef,
|
||||
mergedIndicatorPlacement: mergedIndicatorPlacementRef,
|
||||
gapDeg,
|
||||
cssVars: computed(() => {
|
||||
const { status } = props
|
||||
const {
|
||||
@ -144,6 +161,8 @@ export default defineComponent({
|
||||
processing,
|
||||
circleGap,
|
||||
mergedClsPrefix,
|
||||
gapDeg,
|
||||
gapPosition,
|
||||
$slots
|
||||
} = this
|
||||
return (
|
||||
@ -157,9 +176,13 @@ export default defineComponent({
|
||||
aria-valuemax={100}
|
||||
aria-valuemin={0}
|
||||
aria-valuenow={percentage as number}
|
||||
role={type === 'circle' || type === 'line' ? 'progressbar' : 'none'}
|
||||
role={
|
||||
type === 'circle' || type === 'line' || type === 'dashboard'
|
||||
? 'progressbar'
|
||||
: 'none'
|
||||
}
|
||||
>
|
||||
{type === 'circle' ? (
|
||||
{type === 'circle' || type === 'dashboard' ? (
|
||||
<Circle
|
||||
clsPrefix={mergedClsPrefix}
|
||||
status={status}
|
||||
@ -172,6 +195,8 @@ export default defineComponent({
|
||||
percentage={percentage as number}
|
||||
viewBoxWidth={viewBoxWidth}
|
||||
strokeWidth={strokeWidth}
|
||||
gapDegree={gapDeg}
|
||||
gapPosition={gapPosition}
|
||||
unit={unit}
|
||||
>
|
||||
{$slots}
|
||||
|
@ -55,7 +55,7 @@ export default c([
|
||||
`)
|
||||
])
|
||||
]),
|
||||
cM('circle', {
|
||||
cM('circle, dashboard', {
|
||||
width: '120px'
|
||||
}, [
|
||||
cB('progress-custom-content', `
|
||||
|
Loading…
Reference in New Issue
Block a user