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.

StatelessAvatar.js 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. // @flow
  2. import React from 'react';
  3. import { Icon } from '../../../icons';
  4. import AbstractStatelessAvatar, { type Props as AbstractProps } from '../AbstractStatelessAvatar';
  5. type Props = AbstractProps & {
  6. /**
  7. * External class name passed through props.
  8. */
  9. className?: string,
  10. /**
  11. * The default avatar URL if we want to override the app bundled one (e.g. AlwaysOnTop)
  12. */
  13. defaultAvatar?: string,
  14. /**
  15. * ID of the component to be rendered.
  16. */
  17. id?: string
  18. };
  19. /**
  20. * Implements a stateless avatar component that renders an avatar purely from what gets passed through
  21. * props.
  22. */
  23. export default class StatelessAvatar extends AbstractStatelessAvatar<Props> {
  24. /**
  25. * Implements {@code Component#render}.
  26. *
  27. * @inheritdoc
  28. */
  29. render() {
  30. const { initials, url } = this.props;
  31. if (this._isIcon(url)) {
  32. return (
  33. <div
  34. className = { this._getAvatarClassName() }
  35. id = { this.props.id }
  36. style = { this._getAvatarStyle(this.props.color) }>
  37. <Icon src = { url } />
  38. </div>
  39. );
  40. }
  41. if (url) {
  42. return (
  43. <img
  44. className = { this._getAvatarClassName() }
  45. id = { this.props.id }
  46. onError = { this.props.onAvatarLoadError }
  47. src = { url }
  48. style = { this._getAvatarStyle() } />
  49. );
  50. }
  51. if (initials) {
  52. return (
  53. <div
  54. className = { this._getAvatarClassName() }
  55. id = { this.props.id }
  56. style = { this._getAvatarStyle(this.props.color) }>
  57. <svg
  58. className = 'avatar-svg'
  59. viewBox = '0 0 100 100'
  60. xmlns = 'http://www.w3.org/2000/svg'
  61. xmlnsXlink = 'http://www.w3.org/1999/xlink'>
  62. <foreignObject
  63. height = '100%'
  64. width = '100%'>
  65. <span
  66. className = 'avatar-foreign'>
  67. { initials }
  68. </span>
  69. </foreignObject>
  70. </svg>
  71. </div>
  72. );
  73. }
  74. // default avatar
  75. return (
  76. <img
  77. className = { this._getAvatarClassName('defaultAvatar') }
  78. id = { this.props.id }
  79. src = { this.props.defaultAvatar || 'images/avatar.png' }
  80. style = { this._getAvatarStyle() } />
  81. );
  82. }
  83. /**
  84. * Constructs a style object to be used on the avatars.
  85. *
  86. * @param {string?} color - The desired background color.
  87. * @returns {Object}
  88. */
  89. _getAvatarStyle(color) {
  90. const { size } = this.props;
  91. return {
  92. backgroundColor: color || undefined,
  93. fontSize: size ? size * 0.5 : '180%',
  94. height: size || '100%',
  95. width: size || '100%'
  96. };
  97. }
  98. /**
  99. * Constructs a list of class names required for the avatar component.
  100. *
  101. * @param {string} additional - Any additional class to add.
  102. * @returns {string}
  103. */
  104. _getAvatarClassName(additional) {
  105. return `avatar ${additional || ''} ${this.props.className || ''}`;
  106. }
  107. _isIcon: (?string | ?Object) => boolean
  108. }