|
| 1 | +<script setup lang="ts"> |
| 2 | +import type { HTMLAttributes } from 'vue' |
| 3 | +import { Progress } from '@repo/shadcn-vue/components/ui/progress' |
| 4 | +import { cn } from '@repo/shadcn-vue/lib/utils' |
| 5 | +import { computed, useSlots } from 'vue' |
| 6 | +import { useContextValue } from './context' |
| 7 | +
|
| 8 | +const props = defineProps<{ |
| 9 | + class?: HTMLAttributes['class'] |
| 10 | +}>() |
| 11 | +
|
| 12 | +const PERCENT_MAX = 100 |
| 13 | +
|
| 14 | +const { usedTokens, maxTokens } = useContextValue() |
| 15 | +const slots = useSlots() |
| 16 | +
|
| 17 | +const formatter = new Intl.NumberFormat('en-US', { notation: 'compact' }) |
| 18 | +
|
| 19 | +const usedPercent = computed(() => { |
| 20 | + if (maxTokens.value === 0) |
| 21 | + return 0 |
| 22 | + return usedTokens.value / maxTokens.value |
| 23 | +}) |
| 24 | +const displayPct = computed(() => { |
| 25 | + return new Intl.NumberFormat('en-US', { |
| 26 | + style: 'percent', |
| 27 | + maximumFractionDigits: 1, |
| 28 | + }).format(usedPercent.value) |
| 29 | +}) |
| 30 | +const used = computed(() => formatter.format(usedTokens.value)) |
| 31 | +const total = computed(() => formatter.format(maxTokens.value)) |
| 32 | +</script> |
| 33 | + |
| 34 | +<template> |
| 35 | + <div :class="cn('w-full space-y-2 p-3', props.class)"> |
| 36 | + <slot v-if="slots.default" /> |
| 37 | + |
| 38 | + <template v-else> |
| 39 | + <div class="flex items-center justify-between gap-3 text-xs"> |
| 40 | + <p>{{ displayPct }}</p> |
| 41 | + <p class="font-mono text-muted-foreground"> |
| 42 | + {{ used }} / {{ total }} |
| 43 | + </p> |
| 44 | + </div> |
| 45 | + <div class="space-y-2"> |
| 46 | + <Progress class="bg-muted" :model-value="usedPercent * PERCENT_MAX" /> |
| 47 | + </div> |
| 48 | + </template> |
| 49 | + </div> |
| 50 | +</template> |
0 commit comments