@pingux/astro 2.1.2-alpha.0 → 2.1.2-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/components/HelpHint/HelpHint.js +16 -3
- package/lib/cjs/components/HelpHint/HelpHint.test.js +8 -2
- package/lib/cjs/components/Image/Image.js +16 -8
- package/lib/cjs/components/Image/Image.stories.js +1 -0
- package/lib/cjs/components/Image/Image.test.js +9 -4
- package/lib/cjs/hooks/index.js +7 -0
- package/lib/components/HelpHint/HelpHint.js +17 -4
- package/lib/components/HelpHint/HelpHint.test.js +8 -2
- package/lib/components/Image/Image.js +17 -9
- package/lib/components/Image/Image.stories.js +1 -0
- package/lib/components/Image/Image.test.js +9 -4
- package/lib/hooks/index.js +1 -0
- package/package.json +1 -1
@@ -12,6 +12,8 @@ exports["default"] = void 0;
|
|
12
12
|
var _extends2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/extends"));
|
13
13
|
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/objectWithoutProperties"));
|
14
14
|
var _react = _interopRequireWildcard(require("react"));
|
15
|
+
var _reactAria = require("react-aria");
|
16
|
+
var _interactions = require("@react-aria/interactions");
|
15
17
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
16
18
|
var _uuid = require("uuid");
|
17
19
|
var _ = require("../..");
|
@@ -39,15 +41,26 @@ var HelpHint = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
|
|
39
41
|
iconButtonProps = props.iconButtonProps,
|
40
42
|
others = (0, _objectWithoutProperties2["default"])(props, _excluded);
|
41
43
|
var tooltipId = (0, _uuid.v4)();
|
44
|
+
var buttonRef = (0, _react.useRef)();
|
45
|
+
var _useFocusRing = (0, _reactAria.useFocusRing)(),
|
46
|
+
focusProps = _useFocusRing.focusProps,
|
47
|
+
isFocusVisible = _useFocusRing.isFocusVisible;
|
48
|
+
var _useHover = (0, _interactions.useHover)({}),
|
49
|
+
hoverProps = _useHover.hoverProps,
|
50
|
+
isHovered = _useHover.isHovered;
|
51
|
+
var isTooltipOpen = isFocusVisible || isHovered;
|
42
52
|
return (0, _react2.jsx)(_TooltipTrigger["default"], (0, _extends2["default"])({
|
43
53
|
ref: ref,
|
44
54
|
direction: "top"
|
45
|
-
}, others,
|
55
|
+
}, others, {
|
56
|
+
isOpen: isTooltipOpen
|
57
|
+
}, tooltipProps), (0, _react2.jsx)(_IconButton["default"], (0, _extends2["default"])({
|
58
|
+
ref: buttonRef,
|
46
59
|
variant: "hintButton",
|
47
60
|
"aria-label": "label help hint",
|
48
61
|
"data-testid": "help-hint__button",
|
49
|
-
"aria-describedby": tooltipId
|
50
|
-
}, iconButtonProps), (0, _react2.jsx)(_.Icon, {
|
62
|
+
"aria-describedby": isTooltipOpen ? tooltipId : null
|
63
|
+
}, iconButtonProps, hoverProps, focusProps), (0, _react2.jsx)(_.Icon, {
|
51
64
|
icon: HelpIcon
|
52
65
|
})), (0, _react2.jsx)(_TooltipTrigger.Tooltip, (0, _extends2["default"])({}, tooltipProps, {
|
53
66
|
role: "tooltip",
|
@@ -31,7 +31,10 @@ test('shows tooltip on hover', function () {
|
|
31
31
|
expect(_testWrapper.screen.queryByText(tooltipValue)).not.toBeInTheDocument();
|
32
32
|
_testWrapper.fireEvent.mouseMove(helpHintButton);
|
33
33
|
_testWrapper.fireEvent.mouseEnter(helpHintButton);
|
34
|
-
|
34
|
+
var tooltip = _testWrapper.screen.getByRole('tooltip');
|
35
|
+
var tooltipId = tooltip.getAttribute('id');
|
36
|
+
expect(tooltip).toBeInTheDocument();
|
37
|
+
expect(helpHintButton).toHaveAttribute('aria-describedby', tooltipId);
|
35
38
|
});
|
36
39
|
test('shows tooltip on focus', function () {
|
37
40
|
getComponent();
|
@@ -39,7 +42,10 @@ test('shows tooltip on focus', function () {
|
|
39
42
|
expect(_testWrapper.screen.queryByText(tooltipValue)).not.toBeInTheDocument();
|
40
43
|
_userEvent["default"].tab();
|
41
44
|
expect(helpHintButton).toHaveFocus();
|
42
|
-
|
45
|
+
var tooltip = _testWrapper.screen.getByRole('tooltip');
|
46
|
+
var tooltipId = tooltip.getAttribute('id');
|
47
|
+
expect(tooltip).toBeInTheDocument();
|
48
|
+
expect(helpHintButton).toHaveAttribute('aria-describedby', tooltipId);
|
43
49
|
});
|
44
50
|
test('applies tooltipProps', function () {
|
45
51
|
getComponent({
|
@@ -29,7 +29,7 @@ var _hooks = require("../../hooks");
|
|
29
29
|
var _index = require("../../index");
|
30
30
|
var _colors = require("../../styles/colors");
|
31
31
|
var _templateObject;
|
32
|
-
var _excluded = ["className", "fallbackImage", "fallbackTimeout", "isDisabled", "src", "alt", "sx"];
|
32
|
+
var _excluded = ["className", "fallbackImage", "fallbackTimeout", "isDisabled", "src", "alt", "sx", "fallbackAlt"];
|
33
33
|
function _getRequireWildcardCache(nodeInterop) { if (typeof _WeakMap !== "function") return null; var cacheBabelInterop = new _WeakMap(); var cacheNodeInterop = new _WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
34
34
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = _Object$defineProperty && _Object$getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? _Object$getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { _Object$defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
35
35
|
function ownKeys(object, enumerableOnly) { var keys = _Object$keys(object); if (_Object$getOwnPropertySymbols) { var symbols = _Object$getOwnPropertySymbols(object); enumerableOnly && (symbols = _filterInstanceProperty(symbols).call(symbols, function (sym) { return _Object$getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
@@ -48,6 +48,7 @@ var Image = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
|
|
48
48
|
src = props.src,
|
49
49
|
alt = props.alt,
|
50
50
|
sx = props.sx,
|
51
|
+
fallbackAlt = props.fallbackAlt,
|
51
52
|
others = (0, _objectWithoutProperties2["default"])(props, _excluded);
|
52
53
|
var _useState = (0, _react.useState)(true),
|
53
54
|
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
|
@@ -68,15 +69,16 @@ var Image = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
|
|
68
69
|
setIsLoading(newState);
|
69
70
|
isLoadingRef.current = newState;
|
70
71
|
};
|
71
|
-
var
|
72
|
-
|
73
|
-
|
74
|
-
}
|
75
|
-
return src;
|
72
|
+
var shouldUseFallbackProps = !loadedSuccessfully && !(isLoadingRef !== null && isLoadingRef !== void 0 && isLoadingRef.current) || shouldShowFallback;
|
73
|
+
var setImgAttribute = function setImgAttribute(attribute, fallbackAttribute) {
|
74
|
+
return shouldUseFallbackProps ? fallbackAttribute : attribute;
|
76
75
|
};
|
77
76
|
var imgSrc = (0, _react.useMemo)(function () {
|
78
|
-
return
|
77
|
+
return setImgAttribute(src, fallbackImage);
|
79
78
|
}, [src, isLoading, shouldShowFallback]);
|
79
|
+
var imgAlt = (0, _react.useMemo)(function () {
|
80
|
+
return setImgAttribute(alt, fallbackAlt);
|
81
|
+
}, [alt, isLoading, shouldShowFallback]);
|
80
82
|
var imgRef = (0, _react.useRef)();
|
81
83
|
|
82
84
|
/* istanbul ignore next */
|
@@ -86,6 +88,10 @@ var Image = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
|
|
86
88
|
(0, _hooks.usePropWarning)(props, 'disabled', 'isDisabled');
|
87
89
|
var ariaLabel = props['aria-label'] || alt;
|
88
90
|
(0, _hooks.useAriaLabelWarning)('Image', ariaLabel);
|
91
|
+
(0, _hooks.useDevelopmentWarning)({
|
92
|
+
message: 'Use fallbackAlt to proivide alt attribute for fallback image',
|
93
|
+
shouldTrigger: shouldUseFallbackProps && !fallbackAlt
|
94
|
+
});
|
89
95
|
var _useHover = (0, _interactions.useHover)(props),
|
90
96
|
hoverProps = _useHover.hoverProps,
|
91
97
|
isHovered = _useHover.isHovered;
|
@@ -133,7 +139,7 @@ var Image = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
|
|
133
139
|
}, children);
|
134
140
|
};
|
135
141
|
var themeUiImage = (0, _react2.jsx)(_themeUi.Image, (0, _extends2["default"])({
|
136
|
-
alt:
|
142
|
+
alt: imgAlt,
|
137
143
|
className: classNames,
|
138
144
|
ref: imgRef,
|
139
145
|
role: "img",
|
@@ -167,6 +173,8 @@ Image.propTypes = {
|
|
167
173
|
* See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-alt).
|
168
174
|
* */
|
169
175
|
alt: _propTypes["default"].string,
|
176
|
+
/** Load failure fault-tolerant alt */
|
177
|
+
fallbackAlt: _propTypes["default"].string,
|
170
178
|
/** Defines a string value that labels the current element. */
|
171
179
|
'aria-label': _propTypes["default"].string
|
172
180
|
};
|
@@ -85,6 +85,7 @@ exports.Disabled = Disabled;
|
|
85
85
|
var FallbackImage = function FallbackImage() {
|
86
86
|
return (0, _react2.jsx)(_index.Image, {
|
87
87
|
fallbackImage: _images.pingImg,
|
88
|
+
fallbackAlt: "Ping Identity",
|
88
89
|
src: "https://deelay.me/7000/https://picsum.photos/150/150",
|
89
90
|
sx: {
|
90
91
|
width: '150px',
|
@@ -21,10 +21,12 @@ function ownKeys(object, enumerableOnly) { var keys = _Object$keys(object); if (
|
|
21
21
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var _context, _context2; var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? _forEachInstanceProperty(_context = ownKeys(Object(source), !0)).call(_context, function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(target, _Object$getOwnPropertyDescriptors(source)) : _forEachInstanceProperty(_context2 = ownKeys(Object(source))).call(_context2, function (key) { _Object$defineProperty(target, key, _Object$getOwnPropertyDescriptor(source, key)); }); } return target; }
|
22
22
|
var testSrc = 'test-src';
|
23
23
|
var testFallbackSrc = 'test-fallback-src';
|
24
|
+
var testFallbackAlt = 'test-fallback-alt';
|
24
25
|
var skeletonImageId = 'skeleton-image';
|
25
26
|
var defaultProps = {
|
26
27
|
src: testSrc,
|
27
|
-
fallbackImage: testFallbackSrc
|
28
|
+
fallbackImage: testFallbackSrc,
|
29
|
+
fallbackAlt: testFallbackAlt
|
28
30
|
};
|
29
31
|
var getComponent = function getComponent() {
|
30
32
|
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
@@ -108,23 +110,25 @@ describe('test Image component with useFallbackImage hook', function () {
|
|
108
110
|
});
|
109
111
|
expect(_testWrapper.screen.getByRole('img')).toHaveAttribute('src', testSrc);
|
110
112
|
});
|
111
|
-
test('image component will use fallbackImg if src loaded with error', function () {
|
113
|
+
test('image component will use fallbackImg and fallbackAlt if src loaded with error', function () {
|
112
114
|
getComponent();
|
113
115
|
(0, _react2.act)(function () {
|
114
116
|
fallbackImageObj.onImageError();
|
115
117
|
});
|
116
118
|
var img = _testWrapper.screen.getByRole('img');
|
117
119
|
expect(img).toHaveAttribute('src', testFallbackSrc);
|
120
|
+
expect(img).toHaveAttribute('alt', testFallbackAlt);
|
118
121
|
});
|
119
|
-
test('image component will use fallbackImg if src timed out', function () {
|
122
|
+
test('image component will use fallbackImg and fallbackAlt if src timed out', function () {
|
120
123
|
getComponent();
|
121
124
|
(0, _react2.act)(function () {
|
122
125
|
fallbackImageObj.onFallbackTimeout();
|
123
126
|
});
|
124
127
|
var img = _testWrapper.screen.getByRole('img');
|
125
128
|
expect(img).toHaveAttribute('src', testFallbackSrc);
|
129
|
+
expect(img).toHaveAttribute('alt', testFallbackAlt);
|
126
130
|
});
|
127
|
-
test('if image loads after timeout src still be the fallback', function () {
|
131
|
+
test('if image loads after timeout src and alt still be the fallback', function () {
|
128
132
|
getComponent();
|
129
133
|
(0, _react2.act)(function () {
|
130
134
|
fallbackImageObj.onFallbackTimeout();
|
@@ -132,6 +136,7 @@ describe('test Image component with useFallbackImage hook', function () {
|
|
132
136
|
});
|
133
137
|
var img = _testWrapper.screen.getByRole('img');
|
134
138
|
expect(img).toHaveAttribute('src', testFallbackSrc);
|
139
|
+
expect(img).toHaveAttribute('alt', testFallbackAlt);
|
135
140
|
});
|
136
141
|
test('if image loads before timeout src still be the the origin one', function () {
|
137
142
|
getComponent();
|
package/lib/cjs/hooks/index.js
CHANGED
@@ -41,6 +41,12 @@ _Object$defineProperty(exports, "useDeprecationWarning", {
|
|
41
41
|
return _useDeprecationWarning["default"];
|
42
42
|
}
|
43
43
|
});
|
44
|
+
_Object$defineProperty(exports, "useDevelopmentWarning", {
|
45
|
+
enumerable: true,
|
46
|
+
get: function get() {
|
47
|
+
return _useDevelopmentWarning["default"];
|
48
|
+
}
|
49
|
+
});
|
44
50
|
_Object$defineProperty(exports, "useFallbackImage", {
|
45
51
|
enumerable: true,
|
46
52
|
get: function get() {
|
@@ -131,6 +137,7 @@ var _useComponentToggle = _interopRequireDefault(require("./useComponentToggle")
|
|
131
137
|
var _useCopyToClipboard = _interopRequireDefault(require("./useCopyToClipboard"));
|
132
138
|
var _useDebounce = _interopRequireDefault(require("./useDebounce"));
|
133
139
|
var _useDeprecationWarning = _interopRequireDefault(require("./useDeprecationWarning"));
|
140
|
+
var _useDevelopmentWarning = _interopRequireDefault(require("./useDevelopmentWarning"));
|
134
141
|
var _useFallbackImage = _interopRequireDefault(require("./useFallbackImage"));
|
135
142
|
var _useField = _interopRequireDefault(require("./useField"));
|
136
143
|
var _useLabelHeight = _interopRequireDefault(require("./useLabelHeight"));
|
@@ -1,7 +1,9 @@
|
|
1
1
|
import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
|
2
2
|
import _objectWithoutProperties from "@babel/runtime-corejs3/helpers/esm/objectWithoutProperties";
|
3
3
|
var _excluded = ["children", "tooltipProps", "iconButtonProps"];
|
4
|
-
import React, { forwardRef } from 'react';
|
4
|
+
import React, { forwardRef, useRef } from 'react';
|
5
|
+
import { useFocusRing } from 'react-aria';
|
6
|
+
import { useHover } from '@react-aria/interactions';
|
5
7
|
import PropTypes from 'prop-types';
|
6
8
|
import { v4 as uuid } from 'uuid';
|
7
9
|
import { Icon } from '../..';
|
@@ -26,15 +28,26 @@ var HelpHint = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
26
28
|
iconButtonProps = props.iconButtonProps,
|
27
29
|
others = _objectWithoutProperties(props, _excluded);
|
28
30
|
var tooltipId = uuid();
|
31
|
+
var buttonRef = useRef();
|
32
|
+
var _useFocusRing = useFocusRing(),
|
33
|
+
focusProps = _useFocusRing.focusProps,
|
34
|
+
isFocusVisible = _useFocusRing.isFocusVisible;
|
35
|
+
var _useHover = useHover({}),
|
36
|
+
hoverProps = _useHover.hoverProps,
|
37
|
+
isHovered = _useHover.isHovered;
|
38
|
+
var isTooltipOpen = isFocusVisible || isHovered;
|
29
39
|
return ___EmotionJSX(TooltipTrigger, _extends({
|
30
40
|
ref: ref,
|
31
41
|
direction: "top"
|
32
|
-
}, others,
|
42
|
+
}, others, {
|
43
|
+
isOpen: isTooltipOpen
|
44
|
+
}, tooltipProps), ___EmotionJSX(IconButton, _extends({
|
45
|
+
ref: buttonRef,
|
33
46
|
variant: "hintButton",
|
34
47
|
"aria-label": "label help hint",
|
35
48
|
"data-testid": "help-hint__button",
|
36
|
-
"aria-describedby": tooltipId
|
37
|
-
}, iconButtonProps), ___EmotionJSX(Icon, {
|
49
|
+
"aria-describedby": isTooltipOpen ? tooltipId : null
|
50
|
+
}, iconButtonProps, hoverProps, focusProps), ___EmotionJSX(Icon, {
|
38
51
|
icon: HelpIcon
|
39
52
|
})), ___EmotionJSX(Tooltip, _extends({}, tooltipProps, {
|
40
53
|
role: "tooltip",
|
@@ -28,7 +28,10 @@ test('shows tooltip on hover', function () {
|
|
28
28
|
expect(screen.queryByText(tooltipValue)).not.toBeInTheDocument();
|
29
29
|
fireEvent.mouseMove(helpHintButton);
|
30
30
|
fireEvent.mouseEnter(helpHintButton);
|
31
|
-
|
31
|
+
var tooltip = screen.getByRole('tooltip');
|
32
|
+
var tooltipId = tooltip.getAttribute('id');
|
33
|
+
expect(tooltip).toBeInTheDocument();
|
34
|
+
expect(helpHintButton).toHaveAttribute('aria-describedby', tooltipId);
|
32
35
|
});
|
33
36
|
test('shows tooltip on focus', function () {
|
34
37
|
getComponent();
|
@@ -36,7 +39,10 @@ test('shows tooltip on focus', function () {
|
|
36
39
|
expect(screen.queryByText(tooltipValue)).not.toBeInTheDocument();
|
37
40
|
userEvent.tab();
|
38
41
|
expect(helpHintButton).toHaveFocus();
|
39
|
-
|
42
|
+
var tooltip = screen.getByRole('tooltip');
|
43
|
+
var tooltipId = tooltip.getAttribute('id');
|
44
|
+
expect(tooltip).toBeInTheDocument();
|
45
|
+
expect(helpHintButton).toHaveAttribute('aria-describedby', tooltipId);
|
40
46
|
});
|
41
47
|
test('applies tooltipProps', function () {
|
42
48
|
getComponent({
|
@@ -12,7 +12,7 @@ import _defineProperty from "@babel/runtime-corejs3/helpers/esm/defineProperty";
|
|
12
12
|
import _slicedToArray from "@babel/runtime-corejs3/helpers/esm/slicedToArray";
|
13
13
|
import _objectWithoutProperties from "@babel/runtime-corejs3/helpers/esm/objectWithoutProperties";
|
14
14
|
var _templateObject;
|
15
|
-
var _excluded = ["className", "fallbackImage", "fallbackTimeout", "isDisabled", "src", "alt", "sx"];
|
15
|
+
var _excluded = ["className", "fallbackImage", "fallbackTimeout", "isDisabled", "src", "alt", "sx", "fallbackAlt"];
|
16
16
|
function ownKeys(object, enumerableOnly) { var keys = _Object$keys(object); if (_Object$getOwnPropertySymbols) { var symbols = _Object$getOwnPropertySymbols(object); enumerableOnly && (symbols = _filterInstanceProperty(symbols).call(symbols, function (sym) { return _Object$getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
17
17
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var _context, _context2; var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? _forEachInstanceProperty(_context = ownKeys(Object(source), !0)).call(_context, function (key) { _defineProperty(target, key, source[key]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(target, _Object$getOwnPropertyDescriptors(source)) : _forEachInstanceProperty(_context2 = ownKeys(Object(source))).call(_context2, function (key) { _Object$defineProperty(target, key, _Object$getOwnPropertyDescriptor(source, key)); }); } return target; }
|
18
18
|
import React, { forwardRef, useImperativeHandle, useMemo, useRef, useState } from 'react';
|
@@ -20,7 +20,7 @@ import { keyframes } from '@emotion/react';
|
|
20
20
|
import { useHover } from '@react-aria/interactions';
|
21
21
|
import PropTypes from 'prop-types';
|
22
22
|
import { Image as ThemeUIImage } from 'theme-ui';
|
23
|
-
import { useAriaLabelWarning, useFallbackImage, usePropWarning, useStatusClasses } from '../../hooks';
|
23
|
+
import { useAriaLabelWarning, useDevelopmentWarning, useFallbackImage, usePropWarning, useStatusClasses } from '../../hooks';
|
24
24
|
import { Box } from '../../index';
|
25
25
|
import { neutral } from '../../styles/colors';
|
26
26
|
|
@@ -38,6 +38,7 @@ var Image = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
38
38
|
src = props.src,
|
39
39
|
alt = props.alt,
|
40
40
|
sx = props.sx,
|
41
|
+
fallbackAlt = props.fallbackAlt,
|
41
42
|
others = _objectWithoutProperties(props, _excluded);
|
42
43
|
var _useState = useState(true),
|
43
44
|
_useState2 = _slicedToArray(_useState, 2),
|
@@ -58,15 +59,16 @@ var Image = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
58
59
|
setIsLoading(newState);
|
59
60
|
isLoadingRef.current = newState;
|
60
61
|
};
|
61
|
-
var
|
62
|
-
|
63
|
-
|
64
|
-
}
|
65
|
-
return src;
|
62
|
+
var shouldUseFallbackProps = !loadedSuccessfully && !(isLoadingRef !== null && isLoadingRef !== void 0 && isLoadingRef.current) || shouldShowFallback;
|
63
|
+
var setImgAttribute = function setImgAttribute(attribute, fallbackAttribute) {
|
64
|
+
return shouldUseFallbackProps ? fallbackAttribute : attribute;
|
66
65
|
};
|
67
66
|
var imgSrc = useMemo(function () {
|
68
|
-
return
|
67
|
+
return setImgAttribute(src, fallbackImage);
|
69
68
|
}, [src, isLoading, shouldShowFallback]);
|
69
|
+
var imgAlt = useMemo(function () {
|
70
|
+
return setImgAttribute(alt, fallbackAlt);
|
71
|
+
}, [alt, isLoading, shouldShowFallback]);
|
70
72
|
var imgRef = useRef();
|
71
73
|
|
72
74
|
/* istanbul ignore next */
|
@@ -76,6 +78,10 @@ var Image = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
76
78
|
usePropWarning(props, 'disabled', 'isDisabled');
|
77
79
|
var ariaLabel = props['aria-label'] || alt;
|
78
80
|
useAriaLabelWarning('Image', ariaLabel);
|
81
|
+
useDevelopmentWarning({
|
82
|
+
message: 'Use fallbackAlt to proivide alt attribute for fallback image',
|
83
|
+
shouldTrigger: shouldUseFallbackProps && !fallbackAlt
|
84
|
+
});
|
79
85
|
var _useHover = useHover(props),
|
80
86
|
hoverProps = _useHover.hoverProps,
|
81
87
|
isHovered = _useHover.isHovered;
|
@@ -123,7 +129,7 @@ var Image = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
123
129
|
}, children);
|
124
130
|
};
|
125
131
|
var themeUiImage = ___EmotionJSX(ThemeUIImage, _extends({
|
126
|
-
alt:
|
132
|
+
alt: imgAlt,
|
127
133
|
className: classNames,
|
128
134
|
ref: imgRef,
|
129
135
|
role: "img",
|
@@ -157,6 +163,8 @@ Image.propTypes = {
|
|
157
163
|
* See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-alt).
|
158
164
|
* */
|
159
165
|
alt: PropTypes.string,
|
166
|
+
/** Load failure fault-tolerant alt */
|
167
|
+
fallbackAlt: PropTypes.string,
|
160
168
|
/** Defines a string value that labels the current element. */
|
161
169
|
'aria-label': PropTypes.string
|
162
170
|
};
|
@@ -67,6 +67,7 @@ export var Disabled = function Disabled() {
|
|
67
67
|
export var FallbackImage = function FallbackImage() {
|
68
68
|
return ___EmotionJSX(Image, {
|
69
69
|
fallbackImage: pingImg,
|
70
|
+
fallbackAlt: "Ping Identity",
|
70
71
|
src: "https://deelay.me/7000/https://picsum.photos/150/150",
|
71
72
|
sx: {
|
72
73
|
width: '150px',
|
@@ -18,10 +18,12 @@ import Image from '.';
|
|
18
18
|
import { jsx as ___EmotionJSX } from "@emotion/react";
|
19
19
|
var testSrc = 'test-src';
|
20
20
|
var testFallbackSrc = 'test-fallback-src';
|
21
|
+
var testFallbackAlt = 'test-fallback-alt';
|
21
22
|
var skeletonImageId = 'skeleton-image';
|
22
23
|
var defaultProps = {
|
23
24
|
src: testSrc,
|
24
|
-
fallbackImage: testFallbackSrc
|
25
|
+
fallbackImage: testFallbackSrc,
|
26
|
+
fallbackAlt: testFallbackAlt
|
25
27
|
};
|
26
28
|
var getComponent = function getComponent() {
|
27
29
|
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
@@ -105,23 +107,25 @@ describe('test Image component with useFallbackImage hook', function () {
|
|
105
107
|
});
|
106
108
|
expect(screen.getByRole('img')).toHaveAttribute('src', testSrc);
|
107
109
|
});
|
108
|
-
test('image component will use fallbackImg if src loaded with error', function () {
|
110
|
+
test('image component will use fallbackImg and fallbackAlt if src loaded with error', function () {
|
109
111
|
getComponent();
|
110
112
|
act(function () {
|
111
113
|
fallbackImageObj.onImageError();
|
112
114
|
});
|
113
115
|
var img = screen.getByRole('img');
|
114
116
|
expect(img).toHaveAttribute('src', testFallbackSrc);
|
117
|
+
expect(img).toHaveAttribute('alt', testFallbackAlt);
|
115
118
|
});
|
116
|
-
test('image component will use fallbackImg if src timed out', function () {
|
119
|
+
test('image component will use fallbackImg and fallbackAlt if src timed out', function () {
|
117
120
|
getComponent();
|
118
121
|
act(function () {
|
119
122
|
fallbackImageObj.onFallbackTimeout();
|
120
123
|
});
|
121
124
|
var img = screen.getByRole('img');
|
122
125
|
expect(img).toHaveAttribute('src', testFallbackSrc);
|
126
|
+
expect(img).toHaveAttribute('alt', testFallbackAlt);
|
123
127
|
});
|
124
|
-
test('if image loads after timeout src still be the fallback', function () {
|
128
|
+
test('if image loads after timeout src and alt still be the fallback', function () {
|
125
129
|
getComponent();
|
126
130
|
act(function () {
|
127
131
|
fallbackImageObj.onFallbackTimeout();
|
@@ -129,6 +133,7 @@ describe('test Image component with useFallbackImage hook', function () {
|
|
129
133
|
});
|
130
134
|
var img = screen.getByRole('img');
|
131
135
|
expect(img).toHaveAttribute('src', testFallbackSrc);
|
136
|
+
expect(img).toHaveAttribute('alt', testFallbackAlt);
|
132
137
|
});
|
133
138
|
test('if image loads before timeout src still be the the origin one', function () {
|
134
139
|
getComponent();
|
package/lib/hooks/index.js
CHANGED
@@ -4,6 +4,7 @@ export { default as useComponentToggle } from './useComponentToggle';
|
|
4
4
|
export { default as useCopyToClipboard } from './useCopyToClipboard';
|
5
5
|
export { default as useDebounce } from './useDebounce';
|
6
6
|
export { default as useDeprecationWarning } from './useDeprecationWarning';
|
7
|
+
export { default as useDevelopmentWarning } from './useDevelopmentWarning';
|
7
8
|
export { default as useFallbackImage } from './useFallbackImage';
|
8
9
|
export { default as useField } from './useField';
|
9
10
|
export { default as useLabelHeight } from './useLabelHeight';
|