diff --git a/.eslintrc b/.eslintrc
index 6d549eac24..02a0b7d930 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -44,7 +44,9 @@
}],
"react/jsx-uses-react": "off",
"react/react-in-jsx-scope": "off",
- "react/require-default-props": "off",
+ "react/require-default-props": [2, {
+ "functions": "defaultArguments"
+ }],
"react-hooks/exhaustive-deps": "error",
"testing-library/render-result-naming-convention": "off",
"testing-library/no-render-in-lifecycle": [
diff --git a/__tests__/src/components/ThumbnailNavigation.test.js b/__tests__/src/components/ThumbnailNavigation.test.js
index bf7c89ae4d..0cb5607614 100644
--- a/__tests__/src/components/ThumbnailNavigation.test.js
+++ b/__tests__/src/components/ThumbnailNavigation.test.js
@@ -28,7 +28,7 @@ function Subject({ fixture = manifestJson, ...props }) {
}
Subject.propTypes = {
- fixture: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
+ fixture: PropTypes.object, // eslint-disable-line react/forbid-prop-types
};
jest.mock(
diff --git a/setupJest.js b/setupJest.js
index af9f272bcf..0f4ca57955 100644
--- a/setupJest.js
+++ b/setupJest.js
@@ -44,10 +44,12 @@ jest.mock('react-i18next', () => ({
type: '3rdParty',
},
// this mock makes sure any components using the translate HoC receive the t function as a prop
- withTranslation: () => (Component) => {
- Component.defaultProps = { // eslint-disable-line no-param-reassign
- ...Component.defaultProps, t: k => k,
- };
- return Component;
+ withTranslation: () => (WrappedComponent) => {
+ /**
+ *
+ */
+ const I18nAwareComponent = ({ t = (k => k), ...props }) => ; // eslint-disable-line react/prop-types
+
+ return I18nAwareComponent;
},
}));
diff --git a/src/components/AudioViewer.js b/src/components/AudioViewer.js
index 9ceb07d788..710b5aaedd 100644
--- a/src/components/AudioViewer.js
+++ b/src/components/AudioViewer.js
@@ -13,12 +13,8 @@ const StyledAudio = styled('audio')({
});
/** */
-export function AudioViewer(props) {
+export function AudioViewer({ audioOptions = {}, audioResources = [], captions = [] }) {
/* eslint-disable jsx-a11y/media-has-caption */
- /** */
- const {
- captions, audioOptions, audioResources,
- } = props;
return (
@@ -44,9 +40,3 @@ AudioViewer.propTypes = {
audioResources: PropTypes.arrayOf(PropTypes.object), // eslint-disable-line react/forbid-prop-types
captions: PropTypes.arrayOf(PropTypes.object), // eslint-disable-line react/forbid-prop-types
};
-
-AudioViewer.defaultProps = {
- audioOptions: {},
- audioResources: [],
- captions: [],
-};
diff --git a/src/components/BackgroundPluginArea.js b/src/components/BackgroundPluginArea.js
index c59c745e6a..90b8b9c537 100644
--- a/src/components/BackgroundPluginArea.js
+++ b/src/components/BackgroundPluginArea.js
@@ -3,16 +3,12 @@ import ns from '../config/css-ns';
import { PluginHook } from './PluginHook';
/** invisible area where background plugins can add to */
-export const BackgroundPluginArea = props => (
+export const BackgroundPluginArea = ({ PluginComponents = [], ...props }) => (
);
BackgroundPluginArea.propTypes = {
PluginComponents: PropTypes.array, // eslint-disable-line react/forbid-prop-types
};
-
-BackgroundPluginArea.defaultProps = {
- PluginComponents: [],
-};
diff --git a/src/components/CompanionWindow.js b/src/components/CompanionWindow.js
index 3b0d04e28d..26b9fd7498 100644
--- a/src/components/CompanionWindow.js
+++ b/src/components/CompanionWindow.js
@@ -23,17 +23,18 @@ const StyledCloseButton = styled(MiradorMenuButton, { name: 'CompanionWindow', s
/**
* CompanionWindow
*/
-export function CompanionWindow(props) {
+export function CompanionWindow(props) { // eslint-disable-line react/require-default-props
+ const {
+ ariaLabel = undefined, classes = {}, direction, paperClassName = '', onCloseClick = () => {}, updateCompanionWindow = undefined, isDisplayed = false,
+ position = null, t = key => key, title = null, children = undefined, titleControls = null, size = {},
+ defaultSidebarPanelWidth = 235, defaultSidebarPanelHeight = 201, innerRef = undefined,
+ } = props;
+
/** */
- const openInNewStyle = () => {
- const { direction } = props;
- if (direction === 'rtl') return { transform: 'scale(-1, 1)' };
- return {};
- };
+ const openInNewStyle = direction === 'rtl' ? { transform: 'scale(-1, 1)' } : {};
/** */
- const resizeHandles = () => {
- const { direction, position } = props;
+ const resizeHandles = (() => {
const positions = {
ltr: {
default: 'left',
@@ -69,12 +70,7 @@ export function CompanionWindow(props) {
}
return base;
- };
- const {
- ariaLabel, classes, paperClassName, onCloseClick, updateCompanionWindow, isDisplayed,
- position, t, title, children, titleControls, size,
- defaultSidebarPanelWidth, defaultSidebarPanelHeight, innerRef,
- } = props;
+ })();
const isBottom = (position === 'bottom' || position === 'far-bottom');
@@ -111,7 +107,7 @@ export function CompanionWindow(props) {
width: isBottom ? 'auto' : defaultSidebarPanelWidth,
}}
disableDragging
- enableResizing={resizeHandles()}
+ enableResizing={resizeHandles}
minHeight={50}
minWidth={position === 'left' ? 235 : 100}
>
@@ -130,7 +126,7 @@ export function CompanionWindow(props) {
aria-label={t('openInCompanionWindow')}
onClick={() => { updateCompanionWindow({ position: 'right' }); }}
>
-
+
)
: (
@@ -208,21 +204,3 @@ CompanionWindow.propTypes = {
titleControls: PropTypes.node,
updateCompanionWindow: PropTypes.func,
};
-
-CompanionWindow.defaultProps = {
- ariaLabel: undefined,
- children: undefined,
- classes: {},
- defaultSidebarPanelHeight: 201,
- defaultSidebarPanelWidth: 235,
- innerRef: undefined,
- isDisplayed: false,
- onCloseClick: () => { },
- paperClassName: '',
- position: null,
- size: {},
- t: key => key,
- title: null,
- titleControls: null,
- updateCompanionWindow: undefined,
-};
diff --git a/src/components/IIIFIFrameCommunication.js b/src/components/IIIFIFrameCommunication.js
index c26ef42dad..37b8211188 100644
--- a/src/components/IIIFIFrameCommunication.js
+++ b/src/components/IIIFIFrameCommunication.js
@@ -1,10 +1,20 @@
import { useEffect } from 'react';
import PropTypes from 'prop-types';
+const IIIFIFrameCommunicationDefaultProps = {
+ 'aria-hidden': true,
+ frameBorder: 0,
+ height: 1,
+ name: undefined,
+ scrolling: undefined,
+ style: { visibility: 'hidden' },
+ width: 1,
+};
+
/**
* Handle IIIF Auth token validation using iframe message events
*/
-export function IIIFIFrameCommunication({ handleReceiveMessage, ...props }) {
+export function IIIFIFrameCommunication({ handleReceiveMessage = undefined, ...props }) {
// Attaches the 'message' event listener to the window.
useEffect(() => {
if (!handleReceiveMessage) return undefined;
@@ -19,6 +29,7 @@ export function IIIFIFrameCommunication({ handleReceiveMessage, ...props }) {
// iframe "title" attribute is passed in via props for accessibility
// eslint-disable-next-line jsx-a11y/iframe-has-title
);
@@ -35,14 +46,3 @@ IIIFIFrameCommunication.propTypes = {
style: PropTypes.shape({}),
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
};
-
-IIIFIFrameCommunication.defaultProps = {
- 'aria-hidden': true,
- frameBorder: 0,
- handleReceiveMessage: undefined,
- height: 1,
- name: undefined,
- scrolling: undefined,
- style: { visibility: 'hidden' },
- width: 1,
-};
diff --git a/src/components/IIIFThumbnail.js b/src/components/IIIFThumbnail.js
index 1fd61e66fe..378e94f10d 100644
--- a/src/components/IIIFThumbnail.js
+++ b/src/components/IIIFThumbnail.js
@@ -22,7 +22,8 @@ const Image = styled('img', { name: 'IIIFThumbnail', slot: 'image' })(() => ({
* try to load the image (or even calculate that the image url/height/width are)
*/
const LazyLoadedImage = ({
- border, placeholder, style = {}, thumbnail, resource, maxHeight, maxWidth, thumbnailsConfig, ...props
+ border = false, placeholder, style = {}, thumbnail = null,
+ resource, maxHeight, maxWidth, thumbnailsConfig = {}, ...props
}) => {
const { ref, inView } = useInView();
const [loaded, setLoaded] = useState(false);
@@ -129,13 +130,6 @@ LazyLoadedImage.propTypes = {
thumbnailsConfig: PropTypes.object, // eslint-disable-line react/forbid-prop-types
};
-LazyLoadedImage.defaultProps = {
- border: false,
- style: {},
- thumbnail: null,
- thumbnailsConfig: {},
-};
-
/**
* Uses InteractionObserver to "lazy" load canvas thumbnails that are in view.
*/
diff --git a/src/components/MiradorMenuButton.js b/src/components/MiradorMenuButton.js
index bb723913c1..c42a113713 100644
--- a/src/components/MiradorMenuButton.js
+++ b/src/components/MiradorMenuButton.js
@@ -16,23 +16,22 @@ const Root = styled(IconButton, { name: 'MiradorMenuButton', slot: 'root' })(({
* This shares the passed in aria-label w/ the Tooltip (as title) and the IconButton
* All props besides icon are spread to the IconButton component
*/
-export function MiradorMenuButton(props) {
- const { 'aria-label': ariaLabel } = props;
- const {
- badge,
- children,
- container,
- dispatch,
- selected,
- BadgeProps,
- TooltipProps,
- sx,
- ...iconButtonProps
- } = props;
-
+export function MiradorMenuButton({
+ 'aria-label': ariaLabel,
+ badge = false,
+ children,
+ container = null,
+ dispatch = () => {},
+ selected = false,
+ BadgeProps = {},
+ TooltipProps = {},
+ sx = {},
+ ...iconButtonProps
+}) {
const button = (
{},
- selected: false,
- sx: {},
- TooltipProps: {},
-};
diff --git a/src/components/MosaicRenderPreview.js b/src/components/MosaicRenderPreview.js
index a0ae3ea0c9..98dbbc85c8 100644
--- a/src/components/MosaicRenderPreview.js
+++ b/src/components/MosaicRenderPreview.js
@@ -7,7 +7,7 @@ import MinimalWindow from '../containers/MinimalWindow';
export function MosaicRenderPreview({
t = k => k,
title = '',
- windowId = '',
+ windowId,
}) {
return (
{
@@ -29,8 +28,3 @@ PluginProvider.propTypes = {
children: PropTypes.node,
plugins: PropTypes.array, // eslint-disable-line react/forbid-prop-types
};
-
-PluginProvider.defaultProps = {
- children: null,
- plugins: [],
-};