| |
| |
| |
| |
| |
| |
| |
| <template> |
| <span |
| class="evolutionBadge" |
| :class="directionClass" |
| :title="tooltip || undefined" |
| > |
| <span class="evolutionBadge__icon" aria-hidden="true"> |
| <EvolutionTrendIcon class="evolutionTrendIcon" :direction="direction" /> |
| </span> |
| <span class="evolutionBadge__value">{{ formattedPercent }}</span> |
| </span> |
| </template> |
| |
| <script lang="ts"> |
| import { computed, defineComponent } from 'vue'; |
| import EvolutionTrendIcon from './EvolutionTrendIcon.vue'; |
| |
| type Direction = 'up' | 'down' | 'neutral'; |
| |
| export default defineComponent({ |
| name: 'EvolutionBadge', |
| components: { |
| EvolutionTrendIcon, |
| }, |
| props: { |
| |
| |
| percent: { |
| type: [Number, String], |
| required: true, |
| }, |
| |
| isLowerValueBetter: { |
| type: Boolean, |
| default: false, |
| }, |
| |
| |
| trend: { |
| type: Number, |
| default: undefined, |
| }, |
| tooltip: { |
| type: String, |
| default: '', |
| }, |
| }, |
| setup(props) { |
| const changeValue = computed<number>(() => { |
| if (typeof props.trend === 'number' && !Number.isNaN(props.trend)) { |
| return props.trend; |
| } |
| |
| |
| |
| const numeric = parseFloat( |
| String(props.percent) |
| .replace('\u2212', '-') |
| .replace(',', '.') |
| .replace(/[^0-9.+-]/g, ''), |
| ); |
| return Number.isNaN(numeric) ? 0 : numeric; |
| }); |
| |
| const direction = computed<Direction>(() => { |
| if (changeValue.value > 0) { |
| return 'up'; |
| } |
| if (changeValue.value < 0) { |
| return 'down'; |
| } |
| return 'neutral'; |
| }); |
| |
| |
| |
| const directionClass = computed(() => { |
| if (direction.value === 'neutral') { |
| return 'evolutionBadge--neutral'; |
| } |
| |
| const increased = direction.value === 'up'; |
| const isPositive = props.isLowerValueBetter ? !increased : increased; |
| |
| return isPositive ? 'evolutionBadge--positive' : 'evolutionBadge--negative'; |
| }); |
| |
| const formattedPercent = computed(() => { |
| const label = typeof props.percent === 'number' |
| ? `${props.percent}%` |
| : String(props.percent).trim(); |
| |
| const sign = label.charAt(0); |
| if (changeValue.value > 0 && sign !== '+' && sign !== '-') { |
| return `+${label}`; |
| } |
| |
| return label; |
| }); |
| |
| return { |
| direction, |
| directionClass, |
| formattedPercent, |
| }; |
| }, |
| }); |
| </script> |
| |