Skip to content

Commit 5e50887

Browse files
authored
fix(fuselage-forms): withLabelHelpers missing forwardRef (#1922)
1 parent e0ac8d5 commit 5e50887

File tree

2 files changed

+49
-18
lines changed

2 files changed

+49
-18
lines changed

.changeset/eighty-boxes-prove.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@rocket.chat/fuselage-forms': patch
3+
---
4+
5+
fix(fuselage-forms): withLabelHelpers missing forwardRef

packages/fuselage-forms/src/Inputs/withLabelHelpers.tsx

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
// Disabled this flag since we need to wrap multiple components
22
/* eslint-disable react/no-multi-comp */
3-
import type { ReactNode, ForwardRefExoticComponent } from 'react';
3+
import { useMergedRefs } from '@rocket.chat/fuselage-hooks';
4+
import type {
5+
ReactNode,
6+
ForwardRefExoticComponent,
7+
Ref,
8+
RefAttributes,
9+
} from 'react';
10+
import { forwardRef } from 'react';
411
import { VisuallyHidden } from 'react-aria';
512

613
import {
@@ -11,28 +18,44 @@ import {
1118

1219
type WithLabelId = { id?: string };
1320

14-
function withLabelId<TProps>(
15-
Component: ForwardRefExoticComponent<TProps & WithLabelId>,
21+
function withLabelId<TProps, TRef>(
22+
Component: ForwardRefExoticComponent<
23+
TProps & WithLabelId & RefAttributes<TRef>
24+
>,
1625
) {
17-
const WrappedComponent = function (props: TProps) {
26+
const WrappedComponent = forwardRef<TRef, TProps>(function (props, ref) {
1827
const labelProps = useFieldReferencedByInput();
19-
return <Component {...props} {...labelProps} />;
20-
};
28+
return (
29+
<Component
30+
{...(props as TProps & WithLabelId)}
31+
{...labelProps}
32+
ref={ref}
33+
/>
34+
);
35+
});
2136

2237
WrappedComponent.displayName = `withLabelId(${Component.displayName ?? Component.name ?? 'InputComponent'})`;
2338

2439
return WrappedComponent;
2540
}
2641

27-
type WithLablledBy = { 'aria-labelledby'?: string };
42+
type WithLabelledBy = { 'aria-labelledby'?: string };
2843

29-
function withAriaLabelledBy<TProps>(
30-
Component: ForwardRefExoticComponent<TProps & WithLablledBy>,
44+
function withAriaLabelledBy<TProps, TRef>(
45+
Component: ForwardRefExoticComponent<
46+
TProps & WithLabelledBy & RefAttributes<TRef>
47+
>,
3148
) {
32-
const WrappedComponent = function (props: TProps) {
49+
const WrappedComponent = forwardRef<TRef, TProps>(function (props, ref) {
3350
const labelProps = useFieldReferencedByLabel();
34-
return <Component {...props} {...labelProps} />;
35-
};
51+
return (
52+
<Component
53+
{...(props as TProps & WithLabelledBy)}
54+
{...labelProps}
55+
ref={ref}
56+
/>
57+
);
58+
});
3659

3760
WrappedComponent.displayName = `withAriaLabelledBy(${Component.displayName ?? Component.name ?? 'InputComponent'})`;
3861

@@ -41,20 +64,23 @@ function withAriaLabelledBy<TProps>(
4164

4265
type WithChildrenLabel = { labelChildren: ReactNode };
4366

44-
function withVisuallyHiddenLabel<TProps>(
45-
Component: ForwardRefExoticComponent<TProps & WithChildrenLabel>,
67+
function withVisuallyHiddenLabel<TProps, TRef>(
68+
Component: ForwardRefExoticComponent<
69+
TProps & WithChildrenLabel & RefAttributes<TRef>
70+
>,
4671
) {
47-
const WrappedComponent = function (props: TProps) {
72+
const WrappedComponent = forwardRef<TRef, TProps>(function (props, ref) {
4873
const [label, labelProps, labelRef] = useFieldWrappedByInputLabel();
74+
const mergedRef = useMergedRefs(ref, labelRef as Ref<TRef>);
4975
return (
5076
<Component
51-
{...props}
77+
{...(props as TProps & WithChildrenLabel)}
5278
{...labelProps}
53-
ref={labelRef}
79+
ref={mergedRef}
5480
labelChildren={<VisuallyHidden>{label}</VisuallyHidden>}
5581
/>
5682
);
57-
};
83+
});
5884

5985
WrappedComponent.displayName = `withVisuallyHiddenLabel(${Component.displayName ?? Component.name ?? 'InputComponent'})`;
6086

0 commit comments

Comments
 (0)