Project

General

Profile

Download (1.54 KB) Statistics
| Branch: | Tag: | Revision:
import { cloneElement, isValidElement, useState } from 'react';
import PropTypes from 'prop-types';

const Slot = ({
fills,
id,
multi,
children = null,
deprecated,
replacedBy,
versionDeadline, // version deadline for depracation
...props
}) => {
const [warned, setWarned] = useState(false);
const addProps = object => {
if (deprecated && fills?.length && !warned) {
// eslint-disable-next-line no-console
console.warn(
`Slot with id '${id}' is deprecated and will be removed in version ${versionDeadline}. Please use '${replacedBy}' instead.`
);
setWarned(true);
}
if (multi && !object.key) {
// eslint-disable-next-line no-console
console.warn(
`Please add a key attribute to multiple fills [component - ${object.type.name}]`
);
}

if (isValidElement(object)) {
return cloneElement(object, { ...props });
}

if (!children) {
throw new Error('Slot with override props must have a child');
}

return cloneElement(children, { ...props, ...object });
};

if (fills.length) return fills.map(component => addProps(component));
return children;
};

Slot.propTypes = {
fills: PropTypes.array,
id: PropTypes.string.isRequired,
multi: PropTypes.bool,
children: PropTypes.node,
deprecated: PropTypes.bool,
replacedBy: PropTypes.string,
versionDeadline: PropTypes.string,
};

Slot.defaultProps = {
fills: [],
multi: false,
children: undefined,
deprecated: false,
replacedBy: '',
versionDeadline: undefined,
};

export default Slot;
(1-1/4)