ReportBlockContainer.tsx 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import { Code, GripHorizontal } from 'lucide-react'
  2. import { DragEvent, PropsWithChildren, ReactNode } from 'react'
  3. import { cn, Tooltip, TooltipContent, TooltipTrigger } from 'ui'
  4. interface ReportBlockContainerProps {
  5. icon?: ReactNode
  6. label: string
  7. badge?: ReactNode
  8. actions: ReactNode
  9. loading?: boolean
  10. draggable?: boolean
  11. showDragHandle?: boolean
  12. tooltip?: ReactNode
  13. onDragStart?: (e: DragEvent) => void
  14. }
  15. export const ReportBlockContainer = ({
  16. icon,
  17. label,
  18. badge,
  19. actions,
  20. loading = false,
  21. draggable = false,
  22. showDragHandle = false,
  23. tooltip,
  24. onDragStart,
  25. children,
  26. }: PropsWithChildren<ReportBlockContainerProps>) => {
  27. const hasChildren = Array.isArray(children)
  28. ? children.filter(Boolean).filter((x) => !!x.props.children).length > 0
  29. : !!children
  30. return (
  31. <div
  32. draggable={draggable}
  33. unselectable={draggable ? 'on' : undefined}
  34. onDragStart={onDragStart}
  35. className="h-full flex flex-col overflow-hidden bg-surface-100 border-overlay relative rounded-sm border shadow-xs"
  36. >
  37. <Tooltip>
  38. <TooltipTrigger asChild>
  39. <div
  40. className={cn(
  41. 'grid-item-drag-handle flex py-1 pl-3 pr-1 items-center gap-2 z-10 shrink-0 group h-9',
  42. draggable && 'cursor-move'
  43. )}
  44. >
  45. {showDragHandle ? (
  46. <GripHorizontal size={16} strokeWidth={1.5} />
  47. ) : icon ? (
  48. icon
  49. ) : (
  50. <Code size={16} strokeWidth={1.5} className="text-foreground-muted" />
  51. )}
  52. <div className={cn('flex items-center gap-2 flex-1 min-w-0 transition-opacity')}>
  53. <h3 className="heading-meta truncate">{label}</h3>
  54. {badge && <div className="flex items-center shrink-0">{badge}</div>}
  55. </div>
  56. <div className="flex items-center shrink-0">{actions}</div>
  57. </div>
  58. </TooltipTrigger>
  59. {tooltip && (
  60. <TooltipContent asChild side="bottom">
  61. {tooltip}
  62. </TooltipContent>
  63. )}
  64. </Tooltip>
  65. <div
  66. className={cn(
  67. 'relative flex flex-col grow w-full',
  68. hasChildren && 'border-t overflow-hidden'
  69. )}
  70. >
  71. <div
  72. className={cn(
  73. 'flex flex-col grow items-center overflow-hidden',
  74. loading && 'pointer-events-none'
  75. )}
  76. >
  77. {children}
  78. </div>
  79. </div>
  80. </div>
  81. )
  82. }