diff --git a/src/overridable.js b/src/overridable.js
index 24be219..42a4ff6 100644
--- a/src/overridable.js
+++ b/src/overridable.js
@@ -36,7 +36,7 @@ export function parametrize(Component, extraProps) {
/**
* React component to enable overriding children when rendering.
*/
-function Overridable({id, children, ...restProps}) {
+const Overridable = React.forwardRef(({id, children, ...restProps}, ref) => {
const overriddenComponents = useContext(OverridableContext);
const child = children ? React.Children.only(children) : null;
const childProps = child ? child.props : {};
@@ -44,16 +44,22 @@ function Overridable({id, children, ...restProps}) {
if (id in overriddenComponents) {
// If there's an override, we replace the component's content with the override + props
const Overridden = overriddenComponents[id];
- const element = React.createElement(Overridden, {...childProps, ...restProps});
+ const props = {...childProps, ...restProps};
+ if (ref) {
+ props.ref = ref;
+ }
+ const element = React.createElement(Overridden, props);
return {element};
} else if (child) {
// No override? Clone the Overridable component's original children
- const element = React.cloneElement(child, childProps);
+ const element = ref ? React.cloneElement(child, {ref}) : React.cloneElement(child, childProps);
return {element};
} else {
return null;
}
-}
+});
+
+Overridable.displayName = 'Overridable';
Overridable.propTypes = {
/** The children of the component */
diff --git a/src/overridable.test.js b/src/overridable.test.js
index b7a1f4b..7be8562 100644
--- a/src/overridable.test.js
+++ b/src/overridable.test.js
@@ -221,3 +221,42 @@ describe('Tests for Overridable.component', () => {
expect(NewCmp.find('ul')).toHaveLength(0);
});
});
+
+describe('Tests for ref forwarding', () => {
+ class RefChild extends Component {
+ render() {
+ return
;
+ }
+ }
+
+ test('it should forward a ref to the cloned child', () => {
+ const ref = React.createRef();
+ mount(
+
+
+
+ );
+ expect(ref.current).toBeInstanceOf(RefChild);
+ });
+
+ test('it should forward a ref to the overridden component', () => {
+ const ref = React.createRef();
+ mount(
+
+
+
+
+
+ );
+ expect(ref.current).toBeInstanceOf(RefChild);
+ });
+
+ test('it should render normally when no ref is given', () => {
+ const mounted = mount(
+
+
+
+ );
+ expect(mounted.find('.ref-child')).toHaveLength(1);
+ });
+});