@hig/avatar
Advanced tools
Comparing version 0.1.0-alpha.b2c30c06 to 0.1.0-alpha.b5deb0cb
import React, { Component } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import cx from 'classnames'; | ||
import { polyfill } from 'react-lifecycles-compat'; | ||
// TODO: convert to a hashmap | ||
var _AVAILABLE_SIZES = Object.freeze(["small", "medium", "medium-32", "large", "large-48", "extralarge"]); | ||
var sizes = Object.freeze({ | ||
SMALL_16: "small", | ||
MEDIUM_24: "medium", | ||
MEDIUM_32: "medium-32", | ||
LARGE_36: "large", | ||
LARGE_48: "large-48", | ||
XLARGE_64: "extralarge" | ||
}); | ||
var AVAILABLE_SIZES = Object.freeze(Object.values(sizes)); | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
@@ -16,2 +25,87 @@ | ||
/** | ||
* @param {number} value | ||
* @param {number[]} range1 | ||
* @param {number[]} range2 | ||
* @returns {number} | ||
*/ | ||
function convertRanges(value, range1, range2) { | ||
return Number((value - range1[0]) * (range2[1] - range2[0]) / (range1[1] - range1[0]) + range2[0]).toFixed(); | ||
} | ||
/** | ||
* @param {string} name | ||
* @returns {number} | ||
*/ | ||
function backgroundIdFromName(name) { | ||
return convertRanges(name.charCodeAt(0) - 65, [0, 26], [1, 9]); | ||
} | ||
/** | ||
* @param {string} name | ||
* @returns {string} | ||
*/ | ||
function initialsFromName(name) { | ||
var initials = name.match(/\b\w/g) || []; | ||
return ((initials.shift() || "") + (initials.pop() || "")).toUpperCase(); | ||
} | ||
/** | ||
* @param {Object} props | ||
* @param {string} props.image | ||
* @param {string} props.name | ||
* @returns {JSX.Element} | ||
*/ | ||
// eslint-disable-next-line react/prop-types | ||
function Image(_ref) { | ||
var image = _ref.image, | ||
name = _ref.name, | ||
onError = _ref.onError; | ||
var alt = "Avatar image of " + name; | ||
return React.createElement( | ||
"div", | ||
{ className: "hig__avatarV2__image-wrapper" }, | ||
React.createElement("img", { | ||
className: "hig__avatarV2__image", | ||
src: image, | ||
alt: alt, | ||
onError: onError | ||
}) | ||
); | ||
} | ||
/** | ||
* @param {Object} props | ||
* @param {Object} props.name | ||
* @returns {JSX.Element} | ||
*/ | ||
// eslint-disable-next-line react/prop-types | ||
function Initials(_ref2) { | ||
var name = _ref2.name; | ||
return React.createElement( | ||
"div", | ||
{ className: "hig__avatarV2__initials", "aria-hidden": "true" }, | ||
initialsFromName(name) | ||
); | ||
} | ||
/** | ||
* @typedef {Object} AvatarProps | ||
* @param {string} name | ||
* @param {string} size | ||
* @param {string} [image] | ||
* @param {Function} [onImageError] | ||
/** | ||
* | ||
* | ||
* @typedef {Object} AvatarState | ||
* @property {boolean} hasImageError | ||
* @property {string} [imageUrl] | ||
*/ | ||
var Avatar = function (_Component) { | ||
@@ -21,3 +115,3 @@ _inherits(Avatar, _Component); | ||
function Avatar() { | ||
var _ref; | ||
var _ref3; | ||
@@ -32,9 +126,15 @@ var _temp, _this, _ret; | ||
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = Avatar.__proto__ || Object.getPrototypeOf(Avatar)).call.apply(_ref, [this].concat(args))), _this), _this._initialsFromName = function (name) { | ||
var initials = name.match(/\b\w/g) || []; | ||
return ((initials.shift() || "") + (initials.pop() || "")).toUpperCase(); | ||
}, _this._backgroundIdFromName = function (name) { | ||
return _this._convertRanges(name.charCodeAt(0) - 65, [0, 26], [1, 9]); | ||
}, _this._convertRanges = function (value, range1, range2) { | ||
return Number((value - range1[0]) * (range2[1] - range2[0]) / (range1[1] - range1[0]) + range2[0]).toFixed(); | ||
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref3 = Avatar.__proto__ || Object.getPrototypeOf(Avatar)).call.apply(_ref3, [this].concat(args))), _this), _this.state = { | ||
hasImageError: false, | ||
imageUrl: undefined | ||
}, _this.handleImageError = function (errorEvent) { | ||
var onImageError = _this.props.onImageError; | ||
if (onImageError) { | ||
onImageError(errorEvent); | ||
return; | ||
} | ||
_this.setState({ hasImageError: true }); | ||
}, _temp), _possibleConstructorReturn(_this, _ret); | ||
@@ -46,23 +146,50 @@ } | ||
value: function render() { | ||
var avatarClasses = cx("hig__avatar", "hig__avatar--size--" + this.props.size, "hig__avatar__background--" + this._backgroundIdFromName(this.props.name)); | ||
var _props = this.props, | ||
size = _props.size, | ||
name = _props.name; | ||
var _state = this.state, | ||
imageUrl = _state.imageUrl, | ||
hasImageError = _state.hasImageError; | ||
var handleImageError = this.handleImageError; | ||
var label = "Avatar for " + name; | ||
var showImage = imageUrl && !hasImageError; | ||
var classes = cx("hig__avatarV2", "hig__avatarV2--size--" + size, "hig__avatarV2__background--" + backgroundIdFromName(name)); | ||
return React.createElement( | ||
"div", | ||
{ className: avatarClasses }, | ||
this.props.image && React.createElement( | ||
"div", | ||
{ className: "hig__avatar__image-wrapper" }, | ||
React.createElement("img", { | ||
className: "hig__avatar__image", | ||
src: this.props.image, | ||
alt: "Avatar for " + this.props.name | ||
}) | ||
), | ||
React.createElement( | ||
"div", | ||
{ className: "hig__avatar__initials" }, | ||
this._initialsFromName(this.props.name) | ||
) | ||
"figure", | ||
{ className: classes, "aria-label": label }, | ||
!showImage ? null : React.createElement(Image, { image: imageUrl, name: name, onError: handleImageError }), | ||
React.createElement(Initials, { name: name }) | ||
); | ||
} | ||
}], [{ | ||
key: "getDerivedStateFromProps", | ||
/** | ||
* @param {AvatarProps} nextProps | ||
* @param {AvatarState} prevState | ||
* @returns {AvatarState | null} | ||
*/ | ||
value: function getDerivedStateFromProps(nextProps, prevState) { | ||
var image = nextProps.image; | ||
var imageUrl = prevState.imageUrl; | ||
if (image === imageUrl) return null; | ||
return { | ||
hasImageError: false, | ||
imageUrl: image | ||
}; | ||
} | ||
/** @type {AvatarState} */ | ||
/** | ||
* @param {Event} errorEvent | ||
*/ | ||
}]); | ||
@@ -73,19 +200,18 @@ | ||
Avatar.propTypes = { | ||
/** | ||
* The name for the avatar | ||
*/ | ||
/** The name for the avatar */ | ||
name: PropTypes.string.isRequired, | ||
/** | ||
* Set the size of the avatar | ||
*/ | ||
size: PropTypes.oneOf(_AVAILABLE_SIZES).isRequired, | ||
/** | ||
* Url to a profile image | ||
*/ | ||
image: PropTypes.string | ||
/** Set the size of the avatar */ | ||
size: PropTypes.oneOf(AVAILABLE_SIZES).isRequired, | ||
/** URL to a profile image */ | ||
// eslint-disable-next-line react/no-unused-prop-types | ||
image: PropTypes.string, | ||
/** Called when an error occurs on the image */ | ||
onImageError: PropTypes.func | ||
}; | ||
var Avatar$1 = polyfill(Avatar); | ||
Avatar.__docgenInfo = { | ||
"description": "", | ||
"description": "@typedef {Object} AvatarProps\n@param {string} name\n@param {string} size\n@param {string} [image]\n@param {Function} [onImageError]\n\n/**\n\n\n@typedef {Object} AvatarState\n@property {boolean} hasImageError\n@property {string} [imageUrl]", | ||
"displayName": "Avatar", | ||
@@ -104,3 +230,3 @@ "props": { | ||
"computed": true, | ||
"value": "_AVAILABLE_SIZES" | ||
"value": "AVAILABLE_SIZES" | ||
}, | ||
@@ -115,3 +241,10 @@ "required": true, | ||
"required": false, | ||
"description": "Url to a profile image" | ||
"description": "URL to a profile image" | ||
}, | ||
"onImageError": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "Called when an error occurs on the image" | ||
} | ||
@@ -121,3 +254,3 @@ } | ||
export default Avatar; | ||
export { _AVAILABLE_SIZES }; | ||
export default Avatar$1; | ||
export { sizes, AVAILABLE_SIZES }; |
@@ -11,6 +11,15 @@ 'use strict'; | ||
var cx = _interopDefault(require('classnames')); | ||
var reactLifecyclesCompat = require('react-lifecycles-compat'); | ||
// TODO: convert to a hashmap | ||
var _AVAILABLE_SIZES = Object.freeze(["small", "medium", "medium-32", "large", "large-48", "extralarge"]); | ||
var sizes = Object.freeze({ | ||
SMALL_16: "small", | ||
MEDIUM_24: "medium", | ||
MEDIUM_32: "medium-32", | ||
LARGE_36: "large", | ||
LARGE_48: "large-48", | ||
XLARGE_64: "extralarge" | ||
}); | ||
var AVAILABLE_SIZES = Object.freeze(Object.values(sizes)); | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
@@ -24,2 +33,87 @@ | ||
/** | ||
* @param {number} value | ||
* @param {number[]} range1 | ||
* @param {number[]} range2 | ||
* @returns {number} | ||
*/ | ||
function convertRanges(value, range1, range2) { | ||
return Number((value - range1[0]) * (range2[1] - range2[0]) / (range1[1] - range1[0]) + range2[0]).toFixed(); | ||
} | ||
/** | ||
* @param {string} name | ||
* @returns {number} | ||
*/ | ||
function backgroundIdFromName(name) { | ||
return convertRanges(name.charCodeAt(0) - 65, [0, 26], [1, 9]); | ||
} | ||
/** | ||
* @param {string} name | ||
* @returns {string} | ||
*/ | ||
function initialsFromName(name) { | ||
var initials = name.match(/\b\w/g) || []; | ||
return ((initials.shift() || "") + (initials.pop() || "")).toUpperCase(); | ||
} | ||
/** | ||
* @param {Object} props | ||
* @param {string} props.image | ||
* @param {string} props.name | ||
* @returns {JSX.Element} | ||
*/ | ||
// eslint-disable-next-line react/prop-types | ||
function Image(_ref) { | ||
var image = _ref.image, | ||
name = _ref.name, | ||
onError = _ref.onError; | ||
var alt = "Avatar image of " + name; | ||
return React__default.createElement( | ||
"div", | ||
{ className: "hig__avatarV2__image-wrapper" }, | ||
React__default.createElement("img", { | ||
className: "hig__avatarV2__image", | ||
src: image, | ||
alt: alt, | ||
onError: onError | ||
}) | ||
); | ||
} | ||
/** | ||
* @param {Object} props | ||
* @param {Object} props.name | ||
* @returns {JSX.Element} | ||
*/ | ||
// eslint-disable-next-line react/prop-types | ||
function Initials(_ref2) { | ||
var name = _ref2.name; | ||
return React__default.createElement( | ||
"div", | ||
{ className: "hig__avatarV2__initials", "aria-hidden": "true" }, | ||
initialsFromName(name) | ||
); | ||
} | ||
/** | ||
* @typedef {Object} AvatarProps | ||
* @param {string} name | ||
* @param {string} size | ||
* @param {string} [image] | ||
* @param {Function} [onImageError] | ||
/** | ||
* | ||
* | ||
* @typedef {Object} AvatarState | ||
* @property {boolean} hasImageError | ||
* @property {string} [imageUrl] | ||
*/ | ||
var Avatar = function (_Component) { | ||
@@ -29,3 +123,3 @@ _inherits(Avatar, _Component); | ||
function Avatar() { | ||
var _ref; | ||
var _ref3; | ||
@@ -40,9 +134,15 @@ var _temp, _this, _ret; | ||
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = Avatar.__proto__ || Object.getPrototypeOf(Avatar)).call.apply(_ref, [this].concat(args))), _this), _this._initialsFromName = function (name) { | ||
var initials = name.match(/\b\w/g) || []; | ||
return ((initials.shift() || "") + (initials.pop() || "")).toUpperCase(); | ||
}, _this._backgroundIdFromName = function (name) { | ||
return _this._convertRanges(name.charCodeAt(0) - 65, [0, 26], [1, 9]); | ||
}, _this._convertRanges = function (value, range1, range2) { | ||
return Number((value - range1[0]) * (range2[1] - range2[0]) / (range1[1] - range1[0]) + range2[0]).toFixed(); | ||
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref3 = Avatar.__proto__ || Object.getPrototypeOf(Avatar)).call.apply(_ref3, [this].concat(args))), _this), _this.state = { | ||
hasImageError: false, | ||
imageUrl: undefined | ||
}, _this.handleImageError = function (errorEvent) { | ||
var onImageError = _this.props.onImageError; | ||
if (onImageError) { | ||
onImageError(errorEvent); | ||
return; | ||
} | ||
_this.setState({ hasImageError: true }); | ||
}, _temp), _possibleConstructorReturn(_this, _ret); | ||
@@ -54,23 +154,50 @@ } | ||
value: function render() { | ||
var avatarClasses = cx("hig__avatar", "hig__avatar--size--" + this.props.size, "hig__avatar__background--" + this._backgroundIdFromName(this.props.name)); | ||
var _props = this.props, | ||
size = _props.size, | ||
name = _props.name; | ||
var _state = this.state, | ||
imageUrl = _state.imageUrl, | ||
hasImageError = _state.hasImageError; | ||
var handleImageError = this.handleImageError; | ||
var label = "Avatar for " + name; | ||
var showImage = imageUrl && !hasImageError; | ||
var classes = cx("hig__avatarV2", "hig__avatarV2--size--" + size, "hig__avatarV2__background--" + backgroundIdFromName(name)); | ||
return React__default.createElement( | ||
"div", | ||
{ className: avatarClasses }, | ||
this.props.image && React__default.createElement( | ||
"div", | ||
{ className: "hig__avatar__image-wrapper" }, | ||
React__default.createElement("img", { | ||
className: "hig__avatar__image", | ||
src: this.props.image, | ||
alt: "Avatar for " + this.props.name | ||
}) | ||
), | ||
React__default.createElement( | ||
"div", | ||
{ className: "hig__avatar__initials" }, | ||
this._initialsFromName(this.props.name) | ||
) | ||
"figure", | ||
{ className: classes, "aria-label": label }, | ||
!showImage ? null : React__default.createElement(Image, { image: imageUrl, name: name, onError: handleImageError }), | ||
React__default.createElement(Initials, { name: name }) | ||
); | ||
} | ||
}], [{ | ||
key: "getDerivedStateFromProps", | ||
/** | ||
* @param {AvatarProps} nextProps | ||
* @param {AvatarState} prevState | ||
* @returns {AvatarState | null} | ||
*/ | ||
value: function getDerivedStateFromProps(nextProps, prevState) { | ||
var image = nextProps.image; | ||
var imageUrl = prevState.imageUrl; | ||
if (image === imageUrl) return null; | ||
return { | ||
hasImageError: false, | ||
imageUrl: image | ||
}; | ||
} | ||
/** @type {AvatarState} */ | ||
/** | ||
* @param {Event} errorEvent | ||
*/ | ||
}]); | ||
@@ -81,19 +208,18 @@ | ||
Avatar.propTypes = { | ||
/** | ||
* The name for the avatar | ||
*/ | ||
/** The name for the avatar */ | ||
name: PropTypes.string.isRequired, | ||
/** | ||
* Set the size of the avatar | ||
*/ | ||
size: PropTypes.oneOf(_AVAILABLE_SIZES).isRequired, | ||
/** | ||
* Url to a profile image | ||
*/ | ||
image: PropTypes.string | ||
/** Set the size of the avatar */ | ||
size: PropTypes.oneOf(AVAILABLE_SIZES).isRequired, | ||
/** URL to a profile image */ | ||
// eslint-disable-next-line react/no-unused-prop-types | ||
image: PropTypes.string, | ||
/** Called when an error occurs on the image */ | ||
onImageError: PropTypes.func | ||
}; | ||
var Avatar$1 = reactLifecyclesCompat.polyfill(Avatar); | ||
Avatar.__docgenInfo = { | ||
"description": "", | ||
"description": "@typedef {Object} AvatarProps\n@param {string} name\n@param {string} size\n@param {string} [image]\n@param {Function} [onImageError]\n\n/**\n\n\n@typedef {Object} AvatarState\n@property {boolean} hasImageError\n@property {string} [imageUrl]", | ||
"displayName": "Avatar", | ||
@@ -112,3 +238,3 @@ "props": { | ||
"computed": true, | ||
"value": "_AVAILABLE_SIZES" | ||
"value": "AVAILABLE_SIZES" | ||
}, | ||
@@ -123,3 +249,10 @@ "required": true, | ||
"required": false, | ||
"description": "Url to a profile image" | ||
"description": "URL to a profile image" | ||
}, | ||
"onImageError": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "Called when an error occurs on the image" | ||
} | ||
@@ -129,3 +262,4 @@ } | ||
exports.default = Avatar; | ||
exports._AVAILABLE_SIZES = _AVAILABLE_SIZES; | ||
exports.default = Avatar$1; | ||
exports.sizes = sizes; | ||
exports.AVAILABLE_SIZES = AVAILABLE_SIZES; |
{ | ||
"name": "@hig/avatar", | ||
"version": "0.1.0-alpha.b2c30c06", | ||
"version": "0.1.0-alpha.b5deb0cb", | ||
"description": "HIG Avatar", | ||
@@ -17,17 +17,18 @@ "author": "Autodesk Inc.", | ||
"dependencies": { | ||
"classnames": "^2.2.5" | ||
"classnames": "^2.2.5", | ||
"react-lifecycles-compat": "^3.0.2" | ||
}, | ||
"peerDependencies": { | ||
"prop-types": "^15.5.10", | ||
"react": "^15.4.1" | ||
"react": "^15.4.1 || ^16.3.2" | ||
}, | ||
"devDependencies": { | ||
"@hig/babel-preset": "0.2.0-alpha.b2c30c06", | ||
"@hig/eslint-config": "0.2.0-alpha.b2c30c06", | ||
"@hig/scripts": "0.2.0-alpha.b2c30c06", | ||
"@hig/styles": "0.1.0-alpha.b2c30c06" | ||
"@hig/babel-preset": "0.2.0-alpha.b5deb0cb", | ||
"@hig/eslint-config": "0.2.0-alpha.b5deb0cb", | ||
"@hig/scripts": "0.2.0-alpha.b5deb0cb", | ||
"@hig/styles": "0.2.0-alpha.b5deb0cb" | ||
}, | ||
"scripts": { | ||
"build": "hig-scripts-build", | ||
"lint": "eslint ./src/**/*" | ||
"lint": "eslint src --color --ext .js,.jsx" | ||
}, | ||
@@ -37,6 +38,2 @@ "eslintConfig": { | ||
}, | ||
"eslintIgnore": [ | ||
"*.scss", | ||
"*.json" | ||
], | ||
"babel": { | ||
@@ -43,0 +40,0 @@ "env": { |
# Avatar | ||
Avatars are [...]. | ||
Avatars are a visual representation of a customer's identity. These may be small thumbnails as part of a menu or more prominent, standalone elements on account and management views. | ||
<!-- TODO: Write description --> | ||
Initials are dynamically generated from the provided name and always rendered. This allows the initials to serve as a placeholder while the image is loading. | ||
@@ -20,3 +20,3 @@ Read more about when and how to use the Avatar component [on the internal wiki](https://wiki.autodesk.com/display/HIG/Avatars). | ||
```js | ||
import Avatar from '@hig/avatar'; | ||
import Avatar, { sizes } from '@hig/avatar'; | ||
import '@hig/avatar/build/index.css'; | ||
@@ -27,2 +27,7 @@ ``` | ||
<!-- TODO: Write usage description --> | ||
```jsx | ||
<Avatar | ||
name="David Gonzales" | ||
size={sizes.LARGE_36} | ||
/> | ||
``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
34059
749
32
4
+ Addedreact@16.14.0(transitive)
+ Addedreact-lifecycles-compat@3.0.4(transitive)
- Removedasap@2.0.6(transitive)
- Removedcore-js@1.2.7(transitive)
- Removedcreate-react-class@15.7.0(transitive)
- Removedencoding@0.1.13(transitive)
- Removedfbjs@0.8.18(transitive)
- Removediconv-lite@0.6.3(transitive)
- Removedis-stream@1.1.0(transitive)
- Removedisomorphic-fetch@2.2.1(transitive)
- Removednode-fetch@1.7.3(transitive)
- Removedpromise@7.3.1(transitive)
- Removedreact@15.7.0(transitive)
- Removedsafer-buffer@2.1.2(transitive)
- Removedsetimmediate@1.0.5(transitive)
- Removedua-parser-js@0.7.39(transitive)
- Removedwhatwg-fetch@3.6.20(transitive)