Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 20 additions & 13 deletions packages/react/src/ActionBar/ActionBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -320,16 +320,19 @@ export const ActionBar: React.FC<React.PropsWithChildren<ActionBarProps>> = prop
const moreMenuBtnRef = useRef<HTMLButtonElement>(null)
const containerRef = React.useRef<HTMLUListElement>(null)

useResizeObserver((resizeObserverEntries: ResizeObserverEntry[]) => {
const navWidth = resizeObserverEntries[0].contentRect.width
const moreMenuWidth = moreMenuRef.current?.getBoundingClientRect().width ?? 0
const hasActiveMenu = menuItemIds.size > 0

if (navWidth > 0) {
const newMenuItemIds = getMenuItems(navWidth, moreMenuWidth, childRegistry, hasActiveMenu, computedGap)
if (newMenuItemIds) setMenuItemIds(newMenuItemIds)
}
}, navRef as RefObject<HTMLElement>)
useResizeObserver(
(resizeObserverEntries: ResizeObserverEntry[]) => {
const navWidth = resizeObserverEntries[0].contentRect.width
const moreMenuWidth = moreMenuRef.current?.getBoundingClientRect().width ?? 0
const hasActiveMenu = menuItemIds.size > 0

if (navWidth > 0) {
const newMenuItemIds = getMenuItems(navWidth, moreMenuWidth, childRegistry, hasActiveMenu, computedGap)
if (newMenuItemIds) setMenuItemIds(newMenuItemIds)
}
},
navRef as RefObject<HTMLElement | null>,
)

const isVisibleChild = useCallback(
(id: string) => {
Expand Down Expand Up @@ -554,7 +557,7 @@ const ActionBarGroupContext = React.createContext<{

export const ActionBarGroup = forwardRef(({children}: React.PropsWithChildren, forwardedRef) => {
const backupRef = useRef<HTMLDivElement>(null)
const ref = (forwardedRef ?? backupRef) as RefObject<HTMLDivElement>
const ref = (forwardedRef ?? backupRef) as RefObject<HTMLDivElement | null>
const id = useId()
const {registerChild, unregisterChild} = React.useContext(ActionBarContext)

Expand All @@ -576,7 +579,11 @@ export const ActionBarGroup = forwardRef(({children}: React.PropsWithChildren, f

return (
<ActionBarGroupContext.Provider value={{groupId: id}}>
<div className={styles.Group} ref={ref}>
<div
className={styles.Group}
// @ts-expect-error [react-19] [TS2322]
ref={ref}
>
{children}
</div>
</ActionBarGroupContext.Provider>
Expand All @@ -586,7 +593,7 @@ export const ActionBarGroup = forwardRef(({children}: React.PropsWithChildren, f
export const ActionBarMenu = forwardRef(
({'aria-label': ariaLabel, icon, overflowIcon, items, ...props}: ActionBarMenuProps, forwardedRef) => {
const backupRef = useRef<HTMLButtonElement>(null)
const ref = (forwardedRef ?? backupRef) as RefObject<HTMLButtonElement>
const ref = (forwardedRef ?? backupRef) as RefObject<HTMLButtonElement | null>
const id = useId()
const {registerChild, unregisterChild, isVisibleChild} = React.useContext(ActionBarContext)

Expand Down
26 changes: 14 additions & 12 deletions packages/react/src/ActionList/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const UnwrappedList = <As extends React.ElementType = 'ul'>(

const ariaLabelledBy = slots.heading ? (slots.heading.props.id ?? headingId) : listLabelledBy
const listRole = role || listRoleFromContainer
const listRef = useProvidedRefOrCreate(forwardedRef as React.RefObject<HTMLUListElement>)
const listRef = useProvidedRefOrCreate(forwardedRef as React.RefObject<HTMLUListElement | null>)

let enableFocusZone = false
if (enableFocusZoneFromContainer !== undefined) enableFocusZone = enableFocusZoneFromContainer
Expand All @@ -66,17 +66,19 @@ const UnwrappedList = <As extends React.ElementType = 'ul'>(
}}
>
{slots.heading}
<Component
className={clsx(classes.ActionList, className)}
role={listRole}
aria-labelledby={ariaLabelledBy}
ref={listRef}
data-dividers={showDividers}
data-variant={variant}
{...restProps}
>
{childrenWithoutSlots}
</Component>
{React.createElement(
Component,
{
className: clsx(classes.ActionList, className),
role: listRole,
'aria-labelledby': ariaLabelledBy,
ref: listRef,
'data-dividers': showDividers,
'data-variant': variant,
...restProps,
},
childrenWithoutSlots,
)}
</ListContext.Provider>
)
}
Expand Down
4 changes: 2 additions & 2 deletions packages/react/src/AnchoredOverlay/AnchoredOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ interface AnchoredOverlayPropsWithAnchor {
/**
* An override to the internal ref that will be spread on to the renderAnchor
*/
anchorRef?: React.RefObject<HTMLElement>
anchorRef?: React.RefObject<HTMLElement | null>

/**
* An override to the internal id that will be spread on to the renderAnchor
Expand All @@ -46,7 +46,7 @@ interface AnchoredOverlayPropsWithoutAnchor {
* An override to the internal renderAnchor ref that will be used to position the overlay.
* When renderAnchor is null this can be used to make an anchor that is detached from ActionMenu.
*/
anchorRef: React.RefObject<HTMLElement>
anchorRef: React.RefObject<HTMLElement | null>
/**
* An override to the internal id that will be spread on to the renderAnchor
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,11 @@ export const CustomOverlayMenuAnchor = () => {
<FormControl.Label htmlFor="autocompleteInput" id="autocompleteLabel">
Default label
</FormControl.Label>
<div ref={menuAnchorRef as React.RefObject<HTMLDivElement>} className={classes.AnchorContainer}>
<div
// @ts-expect-error [react-19] [TS2322]
ref={menuAnchorRef as React.RefObject<HTMLDivElement | null>}
className={classes.AnchorContainer}
>
<Autocomplete>
<Autocomplete.Input
id="autocompleteInput"
Expand Down Expand Up @@ -522,7 +526,11 @@ export const InOverlayWithCustomScrollContainerRef = () => {
<div className={classes.OverlayInputBar}>
<Autocomplete.Input ref={inputRef} className={classes.OverlayInput} block aria-label="Search" />
</div>
<div ref={scrollContainerRef as RefObject<HTMLDivElement>} className={classes.OverlayScroll}>
<div
// @ts-expect-error [react-19] [TS2322]
ref={scrollContainerRef as RefObject<HTMLDivElement | null>}
className={classes.OverlayScroll}
>
<Autocomplete.Menu
items={items}
selectedItemIds={[]}
Expand Down
5 changes: 3 additions & 2 deletions packages/react/src/Autocomplete/AutocompleteOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type AutocompleteOverlayInternalProps = {
/**
* The ref of the element that the position of the menu is based on. By default, the menu is positioned based on the text input
*/
menuAnchorRef?: React.RefObject<HTMLElement>
menuAnchorRef?: React.RefObject<HTMLElement | null>
/**
* Props to be spread on the internal `Overlay` component.
*/
Expand Down Expand Up @@ -60,7 +60,8 @@ function AutocompleteOverlay({
preventFocusOnOpen={true}
onClickOutside={closeOptionList}
onEscape={closeOptionList}
ref={floatingElementRef as React.RefObject<HTMLDivElement>}
// @ts-expect-error [react-19] [TS2322]
ref={floatingElementRef as React.RefObject<HTMLDivElement | null>}
top={position?.top}
left={position?.left}
className={classes.Overlay}
Expand Down
3 changes: 2 additions & 1 deletion packages/react/src/AvatarStack/AvatarStack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const AvatarStackBody = ({
}: {
disableExpand: boolean | undefined
hasInteractiveChildren: boolean | undefined
stackContainer: React.RefObject<HTMLDivElement>
stackContainer: React.RefObject<HTMLDivElement | null>
} & React.ComponentPropsWithoutRef<'div'>) => {
return (
<div
Expand All @@ -51,6 +51,7 @@ const AvatarStackBody = ({
classes.AvatarStackBody,
)}
tabIndex={!hasInteractiveChildren && !disableExpand ? 0 : undefined}
// @ts-expect-error [react-19] [TS2322]
ref={stackContainer}
>
{children}
Expand Down
10 changes: 8 additions & 2 deletions packages/react/src/ButtonGroup/ButtonGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const ButtonGroup = React.forwardRef(function ButtonGroup(
forwardRef,
) {
const buttons = React.Children.map(children, (child, index) => <div key={index}>{child}</div>)
const buttonRef = useProvidedRefOrCreate(forwardRef as React.RefObject<HTMLDivElement>)
const buttonRef = useProvidedRefOrCreate(forwardRef as React.RefObject<HTMLDivElement | null>)

useFocusZone({
containerRef: buttonRef,
Expand All @@ -27,7 +27,13 @@ const ButtonGroup = React.forwardRef(function ButtonGroup(
})

return (
<BaseComponent ref={buttonRef} className={clsx(className, classes.ButtonGroup)} role={role} {...rest}>
<BaseComponent
// @ts-expect-error [react-19] [TS2322]
ref={buttonRef}
className={clsx(className, classes.ButtonGroup)}
role={role}
{...rest}
>
{buttons}
</BaseComponent>
)
Expand Down
8 changes: 7 additions & 1 deletion packages/react/src/Checkbox/Checkbox.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ export const Playground = ({value: _value, checked, ...args}: FormControlArgs<Ch
return (
<form>
<FormControl {...parentArgs}>
<Checkbox value="default" checked={checked} {...args} />
<Checkbox
value="default"
checked={checked}
{...args}
// @ts-expect-error [react-19] [TS2322]
ref={args.ref}
/>
<FormControl.Label {...labelArgs} />
{captionArgs.children && <FormControl.Caption {...captionArgs} />}
</FormControl>
Expand Down
13 changes: 10 additions & 3 deletions packages/react/src/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export type CheckboxProps = {
/**
* Forward a ref to the underlying input element
*/
ref?: React.RefObject<HTMLInputElement>
ref?: React.RefObject<HTMLInputElement | null>
/**
* Indicates whether the checkbox must be checked
*/
Expand All @@ -44,7 +44,7 @@ const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
{checked, className, defaultChecked, indeterminate, disabled, onChange, required, validationStatus, value, ...rest},
ref,
): ReactElement => {
const checkboxRef = useProvidedRefOrCreate(ref as React.RefObject<HTMLInputElement>)
const checkboxRef = useProvidedRefOrCreate(ref as React.RefObject<HTMLInputElement | null>)
const checkboxGroupContext = useContext(CheckboxGroupContext)
const handleOnChange: ChangeEventHandler<HTMLInputElement> = e => {
checkboxGroupContext.onChange && checkboxGroupContext.onChange(e)
Expand Down Expand Up @@ -84,7 +84,14 @@ const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
}
})

return <input {...inputProps} className={clsx(className, sharedClasses.Input, classes.Checkbox)} />
return (
<input
{...inputProps}
// @ts-expect-error [react-19] [TS2322]
ref={inputProps.ref}
className={clsx(className, sharedClasses.Input, classes.Checkbox)}
/>
)
},
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,11 @@ const ConfirmationFooter: React.FC<React.PropsWithChildren<DialogProps>> = ({foo

// Must have exactly 2 buttons!
return (
<div ref={footerRef as React.RefObject<HTMLDivElement>} className={classes.ConfirmationFooter}>
<div
// @ts-expect-error [react-19] [TS2322]
ref={footerRef as React.RefObject<HTMLDivElement | null>}
className={classes.ConfirmationFooter}
>
<Dialog.Buttons buttons={footerButtons ?? []} />
</div>
)
Expand Down
7 changes: 6 additions & 1 deletion packages/react/src/Details/Details.features.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@ export default {

export const WithCustomSummary: StoryFn<typeof Details> = () => {
const {getDetailsProps} = useDetails({closeOnOutsideClick: true})
const {ref, ...detailsProps} = getDetailsProps()
return (
<Details {...getDetailsProps()}>
<Details
{...detailsProps}
// @ts-expect-error [react-19] [TS2322]
ref={ref}
>
<summary>Custom see Details</summary>
This is some content
</Details>
Expand Down
7 changes: 6 additions & 1 deletion packages/react/src/Details/Details.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@ export default {
} as Meta<typeof Details>
export const Default: StoryFn<typeof Details> = () => {
const {getDetailsProps} = useDetails({closeOnOutsideClick: true})
const {ref, ...detailsProps} = getDetailsProps()
return (
<Details {...getDetailsProps()}>
<Details
{...detailsProps}
// @ts-expect-error [react-19] [TS2322]
ref={ref}
>
<Details.Summary as={Button}>See Details</Details.Summary>
This is some content
</Details>
Expand Down
31 changes: 27 additions & 4 deletions packages/react/src/Details/__tests__/Details.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@ describe('Details', () => {
it('Toggles when you click outside', async () => {
const Component = () => {
const {getDetailsProps} = useDetails({closeOnOutsideClick: true})
const {ref, ...detailsProps} = getDetailsProps()
return (
<Details data-testid="details" {...getDetailsProps()}>
<Details
data-testid="details"
{...detailsProps}
// @ts-expect-error [react-19] [TS2322]
ref={ref}
>
<Details.Summary>hi</Details.Summary>
</Details>
)
Expand All @@ -25,8 +31,14 @@ describe('Details', () => {
it('Accurately passes down open state', async () => {
const Component = () => {
const {getDetailsProps, open} = useDetails({closeOnOutsideClick: true})
const {ref, ...detailsProps} = getDetailsProps()
return (
<Details {...getDetailsProps()} data-testid="details">
<Details
{...detailsProps}
data-testid="details"
// @ts-expect-error [react-19] [TS2322]
ref={ref}
>
<summary data-testid="summary">{open ? 'Open' : 'Closed'}</summary>
</Details>
)
Expand All @@ -45,8 +57,14 @@ describe('Details', () => {
const CloseButton = (props: ButtonProps) => <Button {...props} />
const Component = () => {
const {getDetailsProps, setOpen, open} = useDetails({closeOnOutsideClick: true, defaultOpen: true})
const {ref, ...detailsProps} = getDetailsProps()
return (
<Details {...getDetailsProps()} data-testid="details">
<Details
{...detailsProps}
data-testid="details"
// @ts-expect-error [react-19] [TS2322]
ref={ref}
>
<summary data-testid="summary">{open ? 'Open' : 'Closed'}</summary>
<CloseButton onClick={() => setOpen(false)}>Close</CloseButton>
</Details>
Expand All @@ -65,8 +83,13 @@ describe('Details', () => {
const user = userEvent.setup()
const Component = () => {
const {getDetailsProps, open} = useDetails({closeOnOutsideClick: true, defaultOpen: true})
const {ref, ...detailsProps} = getDetailsProps()
return (
<Details {...getDetailsProps()}>
<Details
{...detailsProps}
// @ts-expect-error [react-19] [TS2322]
ref={ref}
>
<summary data-testid="summary">{open ? 'Open' : 'Closed'}</summary>
<div>
<Button variant="primary">test</Button>
Expand Down
Loading
Loading