Pill.tsx 1.3 KB

123456789101112131415161718192021222324252627282930313233343536
  1. // Pill: capsule at the 24px text-line size, selectable when given `onClick`
  2. // (view switcher tabs, filters) and a static span otherwise — TerminalBlock's
  3. // exit status is the read-only case. The 11px read-only badge is `Tag`; size
  4. // separates the two as much as interactivity does.
  5. import type { ButtonHTMLAttributes, ReactNode } from 'react'
  6. import clsx from 'clsx'
  7. import css from './Pill.module.css'
  8. /**
  9. * Render a pill chip. Interactive when onClick is supplied (renders a button);
  10. * otherwise a static span.
  11. * @param props.active - selected/active visual state.
  12. * @returns pill element.
  13. */
  14. export function Pill({ active = false, className, children, onClick, ...rest }: {
  15. active?: boolean
  16. // `| undefined` so a caller can forward an optional class straight through
  17. // under exactOptionalPropertyTypes (a CSS-module lookup is string|undefined).
  18. className?: string | undefined
  19. children?: ReactNode
  20. } & ButtonHTMLAttributes<HTMLButtonElement>) {
  21. if (!onClick) {
  22. return <span className={clsx(css.pill, active && css.active, className)}>{children}</span>
  23. }
  24. return (
  25. <button
  26. type="button"
  27. className={clsx(css.pill, css.interactive, active && css.active, className)}
  28. onClick={onClick}
  29. {...rest}
  30. >
  31. {children}
  32. </button>
  33. )
  34. }