diff --git a/packages/react/src/ActionBar/ActionBar.tsx b/packages/react/src/ActionBar/ActionBar.tsx index 7f2745ef218..979caf12499 100644 --- a/packages/react/src/ActionBar/ActionBar.tsx +++ b/packages/react/src/ActionBar/ActionBar.tsx @@ -320,16 +320,19 @@ export const ActionBar: React.FC> = prop const moreMenuBtnRef = useRef(null) const containerRef = React.useRef(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) + 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, + ) const isVisibleChild = useCallback( (id: string) => { @@ -554,7 +557,7 @@ const ActionBarGroupContext = React.createContext<{ export const ActionBarGroup = forwardRef(({children}: React.PropsWithChildren, forwardedRef) => { const backupRef = useRef(null) - const ref = (forwardedRef ?? backupRef) as RefObject + const ref = (forwardedRef ?? backupRef) as RefObject const id = useId() const {registerChild, unregisterChild} = React.useContext(ActionBarContext) @@ -576,7 +579,11 @@ export const ActionBarGroup = forwardRef(({children}: React.PropsWithChildren, f return ( -
+
{children}
@@ -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(null) - const ref = (forwardedRef ?? backupRef) as RefObject + const ref = (forwardedRef ?? backupRef) as RefObject const id = useId() const {registerChild, unregisterChild, isVisibleChild} = React.useContext(ActionBarContext) diff --git a/packages/react/src/ActionList/List.tsx b/packages/react/src/ActionList/List.tsx index 0546d85abca..7f84acb856c 100644 --- a/packages/react/src/ActionList/List.tsx +++ b/packages/react/src/ActionList/List.tsx @@ -41,7 +41,7 @@ const UnwrappedList = ( const ariaLabelledBy = slots.heading ? (slots.heading.props.id ?? headingId) : listLabelledBy const listRole = role || listRoleFromContainer - const listRef = useProvidedRefOrCreate(forwardedRef as React.RefObject) + const listRef = useProvidedRefOrCreate(forwardedRef as React.RefObject) let enableFocusZone = false if (enableFocusZoneFromContainer !== undefined) enableFocusZone = enableFocusZoneFromContainer @@ -66,17 +66,19 @@ const UnwrappedList = ( }} > {slots.heading} - - {childrenWithoutSlots} - + {React.createElement( + Component, + { + className: clsx(classes.ActionList, className), + role: listRole, + 'aria-labelledby': ariaLabelledBy, + ref: listRef, + 'data-dividers': showDividers, + 'data-variant': variant, + ...restProps, + }, + childrenWithoutSlots, + )} ) } diff --git a/packages/react/src/AnchoredOverlay/AnchoredOverlay.tsx b/packages/react/src/AnchoredOverlay/AnchoredOverlay.tsx index ffc1ad10064..c0cd18f64ef 100644 --- a/packages/react/src/AnchoredOverlay/AnchoredOverlay.tsx +++ b/packages/react/src/AnchoredOverlay/AnchoredOverlay.tsx @@ -27,7 +27,7 @@ interface AnchoredOverlayPropsWithAnchor { /** * An override to the internal ref that will be spread on to the renderAnchor */ - anchorRef?: React.RefObject + anchorRef?: React.RefObject /** * An override to the internal id that will be spread on to the renderAnchor @@ -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 + anchorRef: React.RefObject /** * An override to the internal id that will be spread on to the renderAnchor */ diff --git a/packages/react/src/Autocomplete/Autocomplete.features.stories.tsx b/packages/react/src/Autocomplete/Autocomplete.features.stories.tsx index 55fa35d8389..cbd8400c293 100644 --- a/packages/react/src/Autocomplete/Autocomplete.features.stories.tsx +++ b/packages/react/src/Autocomplete/Autocomplete.features.stories.tsx @@ -462,7 +462,11 @@ export const CustomOverlayMenuAnchor = () => { Default label -
} className={classes.AnchorContainer}> +
} + className={classes.AnchorContainer} + > {
-
} className={classes.OverlayScroll}> +
} + className={classes.OverlayScroll} + > + menuAnchorRef?: React.RefObject /** * Props to be spread on the internal `Overlay` component. */ @@ -60,7 +60,8 @@ function AutocompleteOverlay({ preventFocusOnOpen={true} onClickOutside={closeOptionList} onEscape={closeOptionList} - ref={floatingElementRef as React.RefObject} + // @ts-expect-error [react-19] [TS2322] + ref={floatingElementRef as React.RefObject} top={position?.top} left={position?.left} className={classes.Overlay} diff --git a/packages/react/src/AvatarStack/AvatarStack.tsx b/packages/react/src/AvatarStack/AvatarStack.tsx index 9661161a24c..fe6c59f123c 100644 --- a/packages/react/src/AvatarStack/AvatarStack.tsx +++ b/packages/react/src/AvatarStack/AvatarStack.tsx @@ -38,7 +38,7 @@ const AvatarStackBody = ({ }: { disableExpand: boolean | undefined hasInteractiveChildren: boolean | undefined - stackContainer: React.RefObject + stackContainer: React.RefObject } & React.ComponentPropsWithoutRef<'div'>) => { return (
{children} diff --git a/packages/react/src/ButtonGroup/ButtonGroup.tsx b/packages/react/src/ButtonGroup/ButtonGroup.tsx index cd07d132175..f186248fb66 100644 --- a/packages/react/src/ButtonGroup/ButtonGroup.tsx +++ b/packages/react/src/ButtonGroup/ButtonGroup.tsx @@ -17,7 +17,7 @@ const ButtonGroup = React.forwardRef(function ButtonGroup( forwardRef, ) { const buttons = React.Children.map(children, (child, index) =>
{child}
) - const buttonRef = useProvidedRefOrCreate(forwardRef as React.RefObject) + const buttonRef = useProvidedRefOrCreate(forwardRef as React.RefObject) useFocusZone({ containerRef: buttonRef, @@ -27,7 +27,13 @@ const ButtonGroup = React.forwardRef(function ButtonGroup( }) return ( - + {buttons} ) diff --git a/packages/react/src/Checkbox/Checkbox.stories.tsx b/packages/react/src/Checkbox/Checkbox.stories.tsx index 1ffafd73c8e..c8dffa5f8d8 100644 --- a/packages/react/src/Checkbox/Checkbox.stories.tsx +++ b/packages/react/src/Checkbox/Checkbox.stories.tsx @@ -19,7 +19,13 @@ export const Playground = ({value: _value, checked, ...args}: FormControlArgs - + {captionArgs.children && } diff --git a/packages/react/src/Checkbox/Checkbox.tsx b/packages/react/src/Checkbox/Checkbox.tsx index d54c372cd80..45ea0badaa7 100644 --- a/packages/react/src/Checkbox/Checkbox.tsx +++ b/packages/react/src/Checkbox/Checkbox.tsx @@ -20,7 +20,7 @@ export type CheckboxProps = { /** * Forward a ref to the underlying input element */ - ref?: React.RefObject + ref?: React.RefObject /** * Indicates whether the checkbox must be checked */ @@ -44,7 +44,7 @@ const Checkbox = React.forwardRef( {checked, className, defaultChecked, indeterminate, disabled, onChange, required, validationStatus, value, ...rest}, ref, ): ReactElement => { - const checkboxRef = useProvidedRefOrCreate(ref as React.RefObject) + const checkboxRef = useProvidedRefOrCreate(ref as React.RefObject) const checkboxGroupContext = useContext(CheckboxGroupContext) const handleOnChange: ChangeEventHandler = e => { checkboxGroupContext.onChange && checkboxGroupContext.onChange(e) @@ -84,7 +84,14 @@ const Checkbox = React.forwardRef( } }) - return + return ( + + ) }, ) diff --git a/packages/react/src/ConfirmationDialog/ConfirmationDialog.tsx b/packages/react/src/ConfirmationDialog/ConfirmationDialog.tsx index e6e1cb6ffe3..f6f3ef3ef8b 100644 --- a/packages/react/src/ConfirmationDialog/ConfirmationDialog.tsx +++ b/packages/react/src/ConfirmationDialog/ConfirmationDialog.tsx @@ -108,7 +108,11 @@ const ConfirmationFooter: React.FC> = ({foo // Must have exactly 2 buttons! return ( -
} className={classes.ConfirmationFooter}> +
} + className={classes.ConfirmationFooter} + >
) diff --git a/packages/react/src/Details/Details.features.stories.tsx b/packages/react/src/Details/Details.features.stories.tsx index d3cb107cddc..f9dde784139 100644 --- a/packages/react/src/Details/Details.features.stories.tsx +++ b/packages/react/src/Details/Details.features.stories.tsx @@ -9,8 +9,13 @@ export default { export const WithCustomSummary: StoryFn = () => { const {getDetailsProps} = useDetails({closeOnOutsideClick: true}) + const {ref, ...detailsProps} = getDetailsProps() return ( -
+
Custom see Details This is some content
diff --git a/packages/react/src/Details/Details.stories.tsx b/packages/react/src/Details/Details.stories.tsx index 9c1d44c4ee4..d3673322cf3 100644 --- a/packages/react/src/Details/Details.stories.tsx +++ b/packages/react/src/Details/Details.stories.tsx @@ -9,8 +9,13 @@ export default { } as Meta export const Default: StoryFn = () => { const {getDetailsProps} = useDetails({closeOnOutsideClick: true}) + const {ref, ...detailsProps} = getDetailsProps() return ( -
+
See Details This is some content
diff --git a/packages/react/src/Details/__tests__/Details.test.tsx b/packages/react/src/Details/__tests__/Details.test.tsx index ead5d97a041..3ee2b4af873 100644 --- a/packages/react/src/Details/__tests__/Details.test.tsx +++ b/packages/react/src/Details/__tests__/Details.test.tsx @@ -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 ( -
+
hi
) @@ -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 ( -
+
{open ? 'Open' : 'Closed'}
) @@ -45,8 +57,14 @@ describe('Details', () => { const CloseButton = (props: ButtonProps) => diff --git a/packages/react/src/Dialog/Dialog.tsx b/packages/react/src/Dialog/Dialog.tsx index 301bc80304c..af7dfd8dc1d 100644 --- a/packages/react/src/Dialog/Dialog.tsx +++ b/packages/react/src/Dialog/Dialog.tsx @@ -44,7 +44,7 @@ export type DialogButtonProps = Omit & { * A reference to the rendered Button’s DOM node, used together with * `autoFocus` for `focusTrap`’s `initialFocus`. */ - ref?: React.RefObject + ref?: React.RefObject } /** @@ -136,12 +136,12 @@ export interface DialogProps { * Return focus to this element when the Dialog closes, * instead of the element that had focus immediately before the Dialog opened */ - returnFocusRef?: React.RefObject + returnFocusRef?: React.RefObject /** * The element to focus when the Dialog opens */ - initialFocusRef?: React.RefObject + initialFocusRef?: React.RefObject /** * Additional class names to apply to the dialog @@ -215,7 +215,10 @@ const DefaultFooter: React.FC> = ({footerBu focusInStrategy: 'closest', }) return footerButtons ? ( - }> + } + > ) : null @@ -408,6 +411,7 @@ const Buttons: React.FC> {...buttonProps} // 'normal' value is equivalent to 'default', this is used for backwards compatibility variant={buttonType === 'normal' ? 'default' : buttonType} + // @ts-expect-error [react-19] [TS2322] ref={autoFocus && autoFocusCount === 0 ? (autoFocusCount++, autoFocusRef) : null} > {content} diff --git a/packages/react/src/FilteredActionList/FilteredActionList.tsx b/packages/react/src/FilteredActionList/FilteredActionList.tsx index d6d3fe6dfec..9db3c59876e 100644 --- a/packages/react/src/FilteredActionList/FilteredActionList.tsx +++ b/packages/react/src/FilteredActionList/FilteredActionList.tsx @@ -33,9 +33,9 @@ export interface FilteredActionListProps extends Partial | null) => void onListContainerRefChanged?: (ref: HTMLElement | null) => void - onInputRefChanged?: (ref: React.RefObject) => void + onInputRefChanged?: (ref: React.RefObject) => void textInputProps?: Partial> - inputRef?: React.RefObject + inputRef?: React.RefObject message?: React.ReactNode messageText?: { title: string @@ -341,6 +341,7 @@ export function FilteredActionList({
{ //TODO remove this when we remove usingRemoveActiveDescendant const getItemWithActiveDescendant = ( - listRef: React.RefObject, + listRef: React.RefObject, items: FilteredActionListProps['items'], ) => { const listElement = listRef.current @@ -43,8 +43,8 @@ const getItemWithActiveDescendant = ( export const useAnnouncements = ( items: FilteredActionListProps['items'], - listContainerRef: React.RefObject, - inputRef: React.RefObject, + listContainerRef: React.RefObject, + inputRef: React.RefObject, enabled: boolean = true, loading: boolean = false, message?: {title: string; description: string}, diff --git a/packages/react/src/LabelGroup/LabelGroup.tsx b/packages/react/src/LabelGroup/LabelGroup.tsx index 2c59e38b841..2def704e1ec 100644 --- a/packages/react/src/LabelGroup/LabelGroup.tsx +++ b/packages/react/src/LabelGroup/LabelGroup.tsx @@ -19,12 +19,12 @@ export type LabelGroupProps = { // Calculates the width of the overlay to cover the labels/tokens and the expand button. const getOverlayWidth = ( buttonClientRect: DOMRect, - containerRef: React.RefObject, + containerRef: React.RefObject, overlayPaddingPx: number, ) => overlayPaddingPx + buttonClientRect.right - (containerRef.current?.getBoundingClientRect().left || 0) const InlineToggle: React.FC<{ - collapseButtonRef: React.RefObject + collapseButtonRef: React.RefObject collapseInlineExpandedChildren: () => void expandButtonRef: React.RefCallback hiddenItemIds: string[] @@ -40,7 +40,13 @@ const InlineToggle: React.FC<{ showAllTokensInline, }) => isOverflowShown ? ( - ) : hiddenItemIds.length ? ( @@ -81,7 +87,7 @@ const OverlayToggle: React.FC< align="start" side="inside-right" // expandButtonRef satisfies React.RefObject because we manually set `.current` in the `useCallback` above - anchorRef={expandButtonRef as unknown as React.RefObject} + anchorRef={expandButtonRef as unknown as React.RefObject} anchorOffset={overlayPaddingPx * -1} alignmentOffset={overlayPaddingPx * -1} renderAnchor={props => ( diff --git a/packages/react/src/Overlay/Overlay.tsx b/packages/react/src/Overlay/Overlay.tsx index 399078d4e37..b3f3ad7d0f6 100644 --- a/packages/react/src/Overlay/Overlay.tsx +++ b/packages/react/src/Overlay/Overlay.tsx @@ -137,14 +137,14 @@ export const BaseOverlay = React.forwardRef( type ContainerProps = { anchorSide?: AnchorSide - ignoreClickRefs?: React.RefObject[] - initialFocusRef?: React.RefObject + ignoreClickRefs?: React.RefObject[] + initialFocusRef?: React.RefObject onClickOutside: (e: TouchOrMouseEvent) => void onEscape: (e: KeyboardEvent) => void portalContainerName?: string preventOverflow?: boolean preventFocusOnOpen?: boolean - returnFocusRef: React.RefObject + returnFocusRef: React.RefObject } type internalOverlayProps = Merge diff --git a/packages/react/src/Overlay/Overlay.types.test.tsx b/packages/react/src/Overlay/Overlay.types.test.tsx index 613438c8c25..210d9589c2c 100644 --- a/packages/react/src/Overlay/Overlay.types.test.tsx +++ b/packages/react/src/Overlay/Overlay.types.test.tsx @@ -1,26 +1,26 @@ import type React from 'react' import Overlay from './Overlay' -export function shouldAcceptCallWithNoProps(ref: React.RefObject) { +export function shouldAcceptCallWithNoProps(ref: React.RefObject) { return null} onEscape={() => null} /> } -export function shouldAcceptCallWithDOMProps(ref: React.RefObject) { +export function shouldAcceptCallWithDOMProps(ref: React.RefObject) { return null} onEscape={() => null} onMouseDown={() => null} /> } -export function shouldNotAcceptCallWithDOMPropsThatDontMatchElement(ref: React.RefObject) { +export function shouldNotAcceptCallWithDOMPropsThatDontMatchElement(ref: React.RefObject) { // @ts-expect-error href should not be allowed on a
return null} onEscape={() => null} href="//primer.style/" /> } -export function shouldAcceptCallWithAsAndDOMProps(ref: React.RefObject) { +export function shouldAcceptCallWithAsAndDOMProps(ref: React.RefObject) { return ( null} onEscape={() => null} href="//primer.style/" /> ) } -export function shouldNotAcceptSystemProps(ref: React.RefObject) { +export function shouldNotAcceptSystemProps(ref: React.RefObject) { return ( >( ({children, className, as: BaseComponent = 'div', 'aria-label': ariaLabel, role, hasBorder}, forwardedRef) => { - const rootRef = useProvidedRefOrCreate(forwardedRef as React.RefObject) + const rootRef = useProvidedRefOrCreate(forwardedRef as React.RefObject) const isInteractive = (element: HTMLElement) => { return ( @@ -205,10 +205,11 @@ export type TitleAreaProps = { const TitleArea = React.forwardRef>( ({children, className, hidden = false, variant = 'medium'}, forwardedRef) => { - const titleAreaRef = useProvidedRefOrCreate(forwardedRef as React.RefObject) + const titleAreaRef = useProvidedRefOrCreate(forwardedRef as React.RefObject) return (
+ paneRef: React.RefObject }>({ padding: 'normal', rowGap: 'normal', @@ -682,6 +682,7 @@ const Pane = React.forwardRef
[] = [] +const EMPTY_IGNORE_CLICK_REFS: React.RefObject[] = [] type CaretPosition = | 'top' @@ -62,7 +62,7 @@ export type PopoverContentProps = { /* * Refs to elements that should be ignored when detecting outside clicks */ - ignoreClickRefs?: React.RefObject[] + ignoreClickRefs?: React.RefObject[] } & HTMLProps const PopoverContent: React.FC> = ({ diff --git a/packages/react/src/Radio/Radio.stories.tsx b/packages/react/src/Radio/Radio.stories.tsx index c7be73a83f4..fb0ccae8a96 100644 --- a/packages/react/src/Radio/Radio.stories.tsx +++ b/packages/react/src/Radio/Radio.stories.tsx @@ -16,13 +16,19 @@ export default { parameters: {controls: {exclude: excludedControlKeys}}, } as Meta -export const Playground = ({value: _value, ...args}: FormControlArgs) => { +export const Playground = ({value: _value, ref, ...args}: FormControlArgs) => { const {parentArgs, labelArgs, captionArgs} = getFormControlArgsByChildComponent(args) return (
- + {captionArgs.children && } diff --git a/packages/react/src/Radio/Radio.tsx b/packages/react/src/Radio/Radio.tsx index 16a98b94a53..2dc8e53ba72 100644 --- a/packages/react/src/Radio/Radio.tsx +++ b/packages/react/src/Radio/Radio.tsx @@ -27,7 +27,7 @@ export type RadioProps = { /** * Forward a ref to the underlying input element */ - ref?: React.RefObject + ref?: React.RefObject /** * Indicates whether the radio button must be checked before the form can be submitted */ @@ -71,6 +71,7 @@ const Radio = React.forwardRef( type="radio" value={value} name={name} + // @ts-expect-error [react-19] [TS2322] ref={ref} disabled={disabled} checked={checked} diff --git a/packages/react/src/SelectPanel/SelectPanel.tsx b/packages/react/src/SelectPanel/SelectPanel.tsx index 8fe2e158fed..79d751ccf55 100644 --- a/packages/react/src/SelectPanel/SelectPanel.tsx +++ b/packages/react/src/SelectPanel/SelectPanel.tsx @@ -198,7 +198,7 @@ function Panel({ const loadingDelayTimeoutId = useRef(null) const loadingManagedInternally = loading === undefined const loadingManagedExternally = !loadingManagedInternally - const [inputRef, setInputRef] = React.useState | null>(null) + const [inputRef, setInputRef] = React.useState | null>(null) const [listContainerElement, setListContainerElement] = useState(null) const [needsNoItemsAnnouncement, setNeedsNoItemsAnnouncement] = useState(false) const isNarrowScreenSize = useResponsiveValue({narrow: true, regular: false, wide: false}, false) @@ -241,7 +241,7 @@ function Panel({ ) const onInputRefChanged = useCallback( - (ref: React.RefObject) => { + (ref: React.RefObject) => { setInputRef(ref) }, [setInputRef], diff --git a/packages/react/src/Skeleton/SkeletonBox.tsx b/packages/react/src/Skeleton/SkeletonBox.tsx index eb52dc7800b..72f759c41c5 100644 --- a/packages/react/src/Skeleton/SkeletonBox.tsx +++ b/packages/react/src/Skeleton/SkeletonBox.tsx @@ -18,7 +18,8 @@ export const SkeletonBox = React.forwardRef(funct ) { return (
} + // @ts-expect-error [react-19] [TS2322] + ref={ref as React.RefObject} className={clsx(className, classes.SkeletonBox)} style={{height, width, ...(style || {})}} {...props} diff --git a/packages/react/src/TabNav/TabNav.tsx b/packages/react/src/TabNav/TabNav.tsx index 876e130160f..c9e41f752a2 100644 --- a/packages/react/src/TabNav/TabNav.tsx +++ b/packages/react/src/TabNav/TabNav.tsx @@ -51,7 +51,11 @@ function TabNav({children, 'aria-label': ariaLabel, ...rest}: TabNavProps) { ) return ( -
}> +
} + >