radio.tsx 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import {css} from '@emotion/react';
  2. import styled from '@emotion/styled';
  3. import {growIn} from 'sentry/styles/animations';
  4. import {Theme} from 'sentry/utils/theme';
  5. interface CheckedProps extends React.InputHTMLAttributes<HTMLInputElement> {
  6. disabled?: boolean;
  7. radioSize?: 'small';
  8. }
  9. const checkedCss = (p: CheckedProps, theme: Theme) => css`
  10. display: block;
  11. width: ${p.radioSize === 'small' ? '0.5rem' : '0.875rem'};
  12. height: ${p.radioSize === 'small' ? '0.5rem' : '0.875rem'};
  13. border-radius: 50%;
  14. background-color: ${theme.active};
  15. animation: 0.2s ${growIn} ease;
  16. opacity: ${p.disabled ? 0.4 : null};
  17. `;
  18. const Radio = styled('input')<CheckedProps>`
  19. display: flex;
  20. padding: 0;
  21. width: ${p => (p.radioSize === 'small' ? '1rem' : '1.5rem')};
  22. height: ${p => (p.radioSize === 'small' ? '1rem' : '1.5rem')};
  23. position: relative;
  24. border-radius: 50%;
  25. align-items: center;
  26. justify-content: center;
  27. border: 1px solid ${p => p.theme.border};
  28. box-shadow: inset ${p => p.theme.dropShadowLight};
  29. background: none;
  30. appearance: none;
  31. transition: border 0.1s, box-shadow 0.1s;
  32. /* TODO(bootstrap): Our bootstrap CSS adds this, we can remove when we remove that */
  33. margin: 0 !important;
  34. &:focus,
  35. &.focus-visible {
  36. outline: none;
  37. border-color: ${p => p.theme.focusBorder};
  38. box-shadow: ${p => p.theme.focusBorder} 0 0 0 1px;
  39. }
  40. &:checked:after {
  41. content: '';
  42. ${p => checkedCss(p, p.theme)}
  43. }
  44. `;
  45. Radio.defaultProps = {
  46. type: 'radio',
  47. };
  48. export default Radio;