Skip to content

Commit

Permalink
Merge pull request #207 from gsoft-inc/fix/react-19-access-ref-from-p…
Browse files Browse the repository at this point in the history
…rops

Replace element.ref with element.props.ref
  • Loading branch information
alexasselin008 authored Dec 13, 2024
2 parents 40330b4 + e424e1e commit b5d1626
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/empty-years-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@workleap/orbiter-ui": patch
---

Replace element.ref with element.props.ref for React 19 compatibility
7 changes: 4 additions & 3 deletions packages/components/src/accordion/src/useAccordionItems.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Children, ReactElement, ReactNode, Ref, RefAttributes, useMemo } from "react";
import { Children, ReactElement, ReactNode, Ref, useMemo } from "react";
import { Content, Header } from "../../placeholders/index.ts";
import { isNil, mergeProps } from "../../shared/index.ts";
import { getElementRef } from "../../shared/src/getElementRef.tsx";

export interface AccordionBuilderItem {
header: AccordionBuilderHeader;
Expand Down Expand Up @@ -47,14 +48,14 @@ export class AccordionBuilder {
// elementType: isHeading(header.type) ? undefined : header.type,
elementType: header.type,
props: mergeProps(header.props, element.props),
ref: (header as RefAttributes<any>).ref as Ref<any>
ref: getElementRef(header)
};

const panelProps: AccordionBuilderItem["header"] = {
// Use a custom type if available otherwise let the AccordionPanel component choose his default type.
elementType: content.type !== Content ? content.type : undefined,
props: content.props,
ref: (content as RefAttributes<any>).ref as Ref<any>
ref: getElementRef(content)
};

return {
Expand Down
9 changes: 5 additions & 4 deletions packages/components/src/collection/src/useCollection.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Children, ElementType, ReactElement, ReactNode, Ref, RefAttributes, useMemo } from "react";
import { Children, ElementType, ReactElement, ReactNode, Ref, useMemo } from "react";
import { Divider } from "../../divider/index.ts";
import { Item, Section } from "../../collection/index.ts";
import { getElementRef } from "../../shared/src/getElementRef.tsx";
import { TooltipTrigger, parseTooltipTrigger } from "../../tooltip/index.ts";
import { isNil, resolveChildren } from "../../shared/index.ts";

Expand Down Expand Up @@ -75,7 +76,7 @@ export class CollectionBuilder {
index,
key: !isNil(element.key) ? element.key.toString().replace(".", "").replace("$", "") : index.toString(),
props,
ref: (element as RefAttributes<any>).ref as Ref<any>,
ref: getElementRef(element),
type: NodeType.item
};
}
Expand All @@ -97,7 +98,7 @@ export class CollectionBuilder {
items,
key: index.toString(),
props,
ref: (element as RefAttributes<any>).ref as Ref<any>,
ref: getElementRef(element),
type: NodeType.section
};
}
Expand All @@ -113,7 +114,7 @@ export class CollectionBuilder {
index,
key: index.toString(),
props,
ref: (element as RefAttributes<any>).ref as Ref<any>,
ref: getElementRef(element),
type: NodeType.divider
};
}
Expand Down
3 changes: 2 additions & 1 deletion packages/components/src/shared/src/augmentElement.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { ReactElement, RefAttributes, cloneElement } from "react";
import { Size, SizeAdapter, normalizeSize } from "./size.ts";
import { mergeProps } from "./mergeProps.ts";
import { getElementRef } from "./getElementRef.tsx";

export function augmentElement(element: ReactElement & RefAttributes<any>, newProps: Record<string, any>) {
const augmentedProps = mergeProps({ ...element.props, ref: element.ref }, newProps);
const augmentedProps = mergeProps({ ...element.props, ref: getElementRef(element) }, newProps);

return cloneElement(element, augmentedProps);
}
Expand Down
10 changes: 10 additions & 0 deletions packages/components/src/shared/src/getElementRef.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ReactElement, Ref } from "react";

/**
* `ref` is passed as prop in React 19, whereas `ref` is directly attached to
* children in React 18 below check is to ensure `ref` is accessible in both
* cases
*/
export function getElementRef(element: ReactElement): Ref<any> {
return element.props.propertyIsEnumerable("ref") ? element.props.ref : (element as any).ref;
}
5 changes: 3 additions & 2 deletions packages/components/src/tabs/src/useTabsItems.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Children, ReactElement, ReactNode, Ref, RefAttributes, useMemo } from "react";
import { Content, Header } from "../../placeholders/index.ts";
import { isNil, mergeProps, resolveChildren } from "../../shared/index.ts";
import { getElementRef } from "../../shared/src/getElementRef.tsx";

export interface PanelType {
disabled?: boolean;
Expand Down Expand Up @@ -56,7 +57,7 @@ export class TabsBuilder {
key,
panelId,
props: mergeProps(header.props, element.props),
ref: header.ref as Ref<any>,
ref: getElementRef(header),
tabId
});

Expand All @@ -69,7 +70,7 @@ export class TabsBuilder {
key,
panelId,
props: content.props,
ref: content.ref as Ref<any>,
ref: getElementRef(content),
tabId
});
});
Expand Down

0 comments on commit b5d1626

Please sign in to comment.