SparkBar.tsx 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import { cn } from 'ui'
  2. interface SparkBarProps {
  3. value: number
  4. max?: number
  5. type?: 'horizontal' | 'vertical'
  6. labelTop?: string
  7. labelTopClass?: string
  8. labelBottom?: string
  9. labelBottomClass?: string
  10. barClass?: string
  11. bgClass?: string
  12. borderClass?: string
  13. }
  14. export const SparkBar = ({
  15. max = 100,
  16. value = 0,
  17. barClass = 'bg-foreground',
  18. bgClass = '',
  19. type = 'vertical',
  20. borderClass = '',
  21. labelBottom = '',
  22. labelBottomClass = 'tabular-nums',
  23. labelTop = '',
  24. labelTopClass = '',
  25. }: SparkBarProps) => {
  26. if (type === 'horizontal') {
  27. const width = Number((value / max) * 100)
  28. const widthCss = `${width}%`
  29. const hasLabels = labelBottom || labelTop
  30. return (
  31. <div className="flex flex-col w-full">
  32. {hasLabels && (
  33. <div className="flex align-baseline justify-between pb-1 space-x-8">
  34. <p
  35. className={cn(
  36. 'text-foreground text-sm truncate capitalize-sentence',
  37. labelTop.length > 0 && 'max-w-[75%]',
  38. labelBottomClass
  39. )}
  40. >
  41. {labelBottom}
  42. </p>
  43. <p className={cn('text-foreground-light text-sm', labelTopClass)}>{labelTop}</p>
  44. </div>
  45. )}
  46. <div
  47. className={`relative rounded-sm h-1 overflow-hidden w-full border p-0 ${
  48. bgClass ? bgClass : 'bg-surface-400'
  49. } ${borderClass ? borderClass : 'border-none'}`}
  50. >
  51. <div
  52. className={`absolute rounded-sm inset-x-0 bottom-0 h-1 ${barClass} transition-all`}
  53. style={{ width: widthCss }}
  54. ></div>
  55. </div>
  56. </div>
  57. )
  58. } else {
  59. const totalHeight = 35
  60. let height = Number((value / max) * totalHeight)
  61. if (height < 2) height = 2
  62. return (
  63. <div
  64. className={`relative rounded-sm w-5 overflow-hidden border p-1 ${
  65. bgClass ? bgClass : 'bg-gray-400'
  66. } ${borderClass ? borderClass : 'border-none'}`}
  67. style={{ height: totalHeight }}
  68. >
  69. <div className={`absolute inset-x-0 bottom-0 w-5 ${barClass}`} style={{ height }}></div>
  70. </div>
  71. )
  72. }
  73. }
  74. export default SparkBar