code.tsx 854 B

123456789101112131415161718192021222324252627282930313233343536
  1. import { useMemo } from 'react'
  2. type PreviewState = 'idle' | 'loading' | 'ready' | 'error'
  3. type PreviewBadgeProps = {
  4. type: string
  5. state: PreviewState
  6. filename: string
  7. onOpen?: (filename: string) => void
  8. }
  9. const toneByState: Record<PreviewState, string> = {
  10. idle: '#64748b',
  11. loading: '#2563eb',
  12. ready: '#16a34a',
  13. error: '#dc2626'
  14. }
  15. export function PreviewBadge({ type, state, filename, onOpen }: PreviewBadgeProps) {
  16. const label = useMemo(() => {
  17. return `${type.toUpperCase()} / ${state}`
  18. }, [type, state])
  19. return (
  20. <button
  21. className='preview-badge'
  22. style={{ borderColor: toneByState[state], color: toneByState[state] }}
  23. type='button'
  24. aria-label={`Open ${filename}`}
  25. onClick={() => onOpen?.(filename)}
  26. >
  27. <strong>{label}</strong>
  28. <span>{filename}</span>
  29. </button>
  30. )
  31. }