Skip to content

Commit 1667225

Browse files
authored
chore - Fix type compatibility with react 19 refs (#7246)
1 parent ececdb9 commit 1667225

32 files changed

+83
-64
lines changed

.changeset/three-years-film.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@primer/react": patch
3+
---
4+
5+
chore - Fix type compatibility with react 19 refs

packages/react/src/ActionList/List.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ const UnwrappedList = <As extends React.ElementType = 'ul'>(
6666
}}
6767
>
6868
{slots.heading}
69+
{/* @ts-expect-error ref needs a non nullable ref */}
6970
<Component
7071
className={clsx(classes.ActionList, className)}
7172
role={listRole}

packages/react/src/AnchoredOverlay/AnchoredOverlay.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ interface AnchoredOverlayPropsWithAnchor {
2727
/**
2828
* An override to the internal ref that will be spread on to the renderAnchor
2929
*/
30-
anchorRef?: React.RefObject<HTMLElement>
30+
anchorRef?: React.RefObject<HTMLElement | null>
3131

3232
/**
3333
* An override to the internal id that will be spread on to the renderAnchor
@@ -46,7 +46,7 @@ interface AnchoredOverlayPropsWithoutAnchor {
4646
* An override to the internal renderAnchor ref that will be used to position the overlay.
4747
* When renderAnchor is null this can be used to make an anchor that is detached from ActionMenu.
4848
*/
49-
anchorRef: React.RefObject<HTMLElement>
49+
anchorRef: React.RefObject<HTMLElement | null>
5050
/**
5151
* An override to the internal id that will be spread on to the renderAnchor
5252
*/

packages/react/src/ButtonGroup/ButtonGroup.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const ButtonGroup = React.forwardRef(function ButtonGroup(
1717
forwardRef,
1818
) {
1919
const buttons = React.Children.map(children, (child, index) => <div key={index}>{child}</div>)
20-
const buttonRef = useProvidedRefOrCreate(forwardRef as React.RefObject<HTMLDivElement>)
20+
const buttonRef = useProvidedRefOrCreate(forwardRef as React.RefObject<HTMLDivElement | null>)
2121

2222
useFocusZone({
2323
containerRef: buttonRef,
@@ -27,6 +27,7 @@ const ButtonGroup = React.forwardRef(function ButtonGroup(
2727
})
2828

2929
return (
30+
//@ts-expect-error it needs a non nullable ref
3031
<BaseComponent ref={buttonRef} className={clsx(className, classes.ButtonGroup)} role={role} {...rest}>
3132
{buttons}
3233
</BaseComponent>

packages/react/src/Checkbox/Checkbox.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
8484
checkbox.setAttribute('aria-checked', checkbox.checked ? 'true' : 'false')
8585
}
8686
})
87-
87+
// @ts-expect-error inputProp needs a non nullable ref
8888
return <input {...inputProps} className={clsx(className, sharedClasses.Input, classes.Checkbox)} />
8989
},
9090
)

packages/react/src/Dialog/Dialog.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export type DialogButtonProps = Omit<ButtonProps, 'content'> & {
4444
* A reference to the rendered Button’s DOM node, used together with
4545
* `autoFocus` for `focusTrap`’s `initialFocus`.
4646
*/
47-
ref?: React.RefObject<HTMLButtonElement>
47+
ref?: React.RefObject<HTMLButtonElement | null>
4848
}
4949

5050
/**
@@ -136,12 +136,12 @@ export interface DialogProps {
136136
* Return focus to this element when the Dialog closes,
137137
* instead of the element that had focus immediately before the Dialog opened
138138
*/
139-
returnFocusRef?: React.RefObject<HTMLElement>
139+
returnFocusRef?: React.RefObject<HTMLElement | null>
140140

141141
/**
142142
* The element to focus when the Dialog opens
143143
*/
144-
initialFocusRef?: React.RefObject<HTMLElement>
144+
initialFocusRef?: React.RefObject<HTMLElement | null>
145145

146146
/**
147147
* Additional class names to apply to the dialog
@@ -408,6 +408,7 @@ const Buttons: React.FC<React.PropsWithChildren<{buttons: DialogButtonProps[]}>>
408408
{...buttonProps}
409409
// 'normal' value is equivalent to 'default', this is used for backwards compatibility
410410
variant={buttonType === 'normal' ? 'default' : buttonType}
411+
// @ts-expect-error it needs a non nullable ref
411412
ref={autoFocus && autoFocusCount === 0 ? (autoFocusCount++, autoFocusRef) : null}
412413
>
413414
{content}

packages/react/src/FilteredActionList/FilteredActionList.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ export interface FilteredActionListProps extends Partial<Omit<GroupedListProps,
3131
filterValue?: string
3232
onFilterChange: (value: string, e: React.ChangeEvent<HTMLInputElement> | null) => void
3333
onListContainerRefChanged?: (ref: HTMLElement | null) => void
34-
onInputRefChanged?: (ref: React.RefObject<HTMLInputElement>) => void
34+
onInputRefChanged?: (ref: React.RefObject<HTMLInputElement | null>) => void
3535
/**
3636
* A ref assigned to the scrollable container wrapping the ActionList
3737
*/
3838
scrollContainerRef?: React.Ref<HTMLDivElement | null>
3939
textInputProps?: Partial<Omit<TextInputProps, 'onChange'>>
40-
inputRef?: React.RefObject<HTMLInputElement>
40+
inputRef?: React.RefObject<HTMLInputElement | null>
4141
message?: React.ReactNode
4242
messageText?: {
4343
title: string
@@ -382,6 +382,7 @@ export function FilteredActionList({
382382
<div ref={inputAndListContainerRef} className={clsx(className, classes.Root)} data-testid="filtered-action-list">
383383
<div className={classes.Header}>
384384
<TextInput
385+
// @ts-expect-error it needs a non nullable ref
385386
ref={inputRef}
386387
block
387388
width="auto"
@@ -418,6 +419,7 @@ export function FilteredActionList({
418419
</label>
419420
</div>
420421
)}
422+
{/* @ts-expect-error div needs a non nullable ref */}
421423
<div ref={scrollContainerRef} className={classes.Container}>
422424
{getBodyContent()}
423425
</div>

packages/react/src/FilteredActionList/useAnnouncements.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const useFirstRender = () => {
1919
}
2020

2121
const getItemWithActiveDescendant = (
22-
listRef: React.RefObject<HTMLUListElement>,
22+
listRef: React.RefObject<HTMLUListElement | null>,
2323
items: FilteredActionListProps['items'],
2424
) => {
2525
const listElement = listRef.current
@@ -40,8 +40,8 @@ const getItemWithActiveDescendant = (
4040

4141
export const useAnnouncements = (
4242
items: FilteredActionListProps['items'],
43-
listContainerRef: React.RefObject<HTMLUListElement>,
44-
inputRef: React.RefObject<HTMLInputElement>,
43+
listContainerRef: React.RefObject<HTMLUListElement | null>,
44+
inputRef: React.RefObject<HTMLInputElement | null>,
4545
enabled: boolean = true,
4646
loading: boolean = false,
4747
message?: {title: string; description: string},

packages/react/src/Overlay/Overlay.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,14 @@ export const BaseOverlay = React.forwardRef(
138138

139139
type ContainerProps = {
140140
anchorSide?: AnchorSide
141-
ignoreClickRefs?: React.RefObject<HTMLElement>[]
142-
initialFocusRef?: React.RefObject<HTMLElement>
141+
ignoreClickRefs?: React.RefObject<HTMLElement | null>[]
142+
initialFocusRef?: React.RefObject<HTMLElement | null>
143143
onClickOutside: (e: TouchOrMouseEvent) => void
144144
onEscape: (e: KeyboardEvent) => void
145145
portalContainerName?: string
146146
preventOverflow?: boolean
147147
preventFocusOnOpen?: boolean
148-
returnFocusRef: React.RefObject<HTMLElement>
148+
returnFocusRef: React.RefObject<HTMLElement | null>
149149
}
150150

151151
type internalOverlayProps = Merge<OwnOverlayProps, ContainerProps>

packages/react/src/PageHeader/PageHeader.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ const TitleArea = React.forwardRef<HTMLDivElement, React.PropsWithChildren<Title
209209
return (
210210
<div
211211
className={clsx(classes.TitleArea, className)}
212+
// @ts-expect-error it needs a non nullable ref
212213
ref={titleAreaRef}
213214
data-component="TitleArea"
214215
{...getResponsiveAttributes('size-variant', variant)}

0 commit comments

Comments
 (0)