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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // @flow
  2. import React from 'react';
  3. import AbstractStatelessAvatar, { type Props as AbstractProps } from '../AbstractStatelessAvatar';
  4. type Props = AbstractProps & {
  5. /**
  6. * External class name passed through props.
  7. */
  8. className?: string,
  9. /**
  10. * The default avatar URL if we want to override the app bundled one (e.g. AlwaysOnTop)
  11. */
  12. defaultAvatar?: string,
  13. /**
  14. * ID of the component to be rendered.
  15. */
  16. id?: string
  17. };
  18. /**
  19. * Implements a stateless avatar component that renders an avatar purely from what gets passed through
  20. * props.
  21. */
  22. export default class StatelessAvatar extends AbstractStatelessAvatar<Props> {
  23. /**
  24. * Implements {@code Component#render}.
  25. *
  26. * @inheritdoc
  27. */
  28. render() {
  29. const { initials, url } = this.props;
  30. const icon = this._parseIconUrl(url);
  31. if (icon) {
  32. return (
  33. <div
  34. className = { this._getAvatarClassName() }
  35. id = { this.props.id }
  36. style = { this._getAvatarStyle(this.props.color) }>
  37. <i className = { `icon-${icon}` } />
  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. _parseIconUrl: ?string => ?string
  108. }