You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Label.tsx 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import React, { useCallback } from 'react';
  2. import { makeStyles } from 'tss-react/mui';
  3. import Icon from '../../../icons/components/Icon';
  4. import { withPixelLineHeight } from '../../../styles/functions.web';
  5. import { COLORS } from '../../constants';
  6. interface IProps {
  7. /**
  8. * Optional label for screen reader users, invisible in the UI.
  9. *
  10. * Note: if the text prop is set, a screen reader will first announce
  11. * the accessibilityText, then the text.
  12. */
  13. accessibilityText?: string;
  14. /**
  15. * Own CSS class name.
  16. */
  17. className?: string;
  18. /**
  19. * The color of the label.
  20. */
  21. color?: string;
  22. /**
  23. * An SVG icon to be rendered as the content of the label.
  24. */
  25. icon?: Function;
  26. /**
  27. * Color for the icon.
  28. */
  29. iconColor?: string;
  30. /**
  31. * HTML ID attribute to add to the root of {@code Label}.
  32. */
  33. id?: string;
  34. /**
  35. * Click handler if any.
  36. */
  37. onClick?: (e?: React.MouseEvent) => void;
  38. /**
  39. * String or component that will be rendered as the label itself.
  40. */
  41. text?: string;
  42. }
  43. const useStyles = makeStyles()(theme => {
  44. return {
  45. label: {
  46. ...withPixelLineHeight(theme.typography.labelRegular),
  47. alignItems: 'center',
  48. background: theme.palette.ui04,
  49. borderRadius: '4px',
  50. color: theme.palette.text01,
  51. display: 'flex',
  52. margin: '0 2px',
  53. padding: '6px',
  54. height: 28,
  55. boxSizing: 'border-box'
  56. },
  57. withIcon: {
  58. marginLeft: 8
  59. },
  60. clickable: {
  61. cursor: 'pointer'
  62. },
  63. [COLORS.white]: {
  64. background: theme.palette.ui09,
  65. color: theme.palette.text04,
  66. '& svg': {
  67. fill: theme.palette.icon04
  68. }
  69. },
  70. [COLORS.green]: {
  71. background: theme.palette.success02
  72. },
  73. [COLORS.red]: {
  74. background: theme.palette.actionDanger
  75. }
  76. };
  77. });
  78. const Label = ({
  79. accessibilityText,
  80. className,
  81. color,
  82. icon,
  83. iconColor,
  84. id,
  85. onClick,
  86. text
  87. }: IProps) => {
  88. const { classes, cx } = useStyles();
  89. const onKeyPress = useCallback(event => {
  90. if (!onClick) {
  91. return;
  92. }
  93. if (event.key === 'Enter' || event.key === ' ') {
  94. event.preventDefault();
  95. onClick();
  96. }
  97. }, [ onClick ]);
  98. return (
  99. <div
  100. className = { cx(classes.label, onClick && classes.clickable,
  101. color && classes[color], className
  102. ) }
  103. id = { id }
  104. onClick = { onClick }
  105. onKeyPress = { onKeyPress }
  106. role = { onClick ? 'button' : undefined }
  107. tabIndex = { onClick ? 0 : undefined }>
  108. {icon && <Icon
  109. color = { iconColor }
  110. size = '16'
  111. src = { icon } />}
  112. {accessibilityText && <span className = 'sr-only'>{accessibilityText}</span>}
  113. {text && <span className = { icon && classes.withIcon }>{text}</span>}
  114. </div>
  115. );
  116. };
  117. export default Label;