diff --git a/.changeset/wicked-buttons-wink.md b/.changeset/wicked-buttons-wink.md new file mode 100644 index 00000000000..e278ac60661 --- /dev/null +++ b/.changeset/wicked-buttons-wink.md @@ -0,0 +1,5 @@ +--- +'@primer/react': minor +--- + +Add support for `ref` types from React 19 by annotating `React.RefObject` types as `React.RefObject` diff --git a/package-lock.json b/package-lock.json index 80e38040423..d0013aad3e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "packages": { "": { "name": "primer", + "hasInstallScript": true, "license": "MIT", "workspaces": [ "packages/rollup-plugin-import-css", @@ -53,6 +54,7 @@ "globals": "^16.2.0", "markdownlint-cli2": "^0.19.0", "markdownlint-cli2-formatter-pretty": "^0.0.8", + "patch-package": "^8.0.1", "prettier": "3.4.2", "rimraf": "5.0.5", "size-limit": "11.2.0", @@ -10030,6 +10032,13 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true, + "license": "BSD-2-Clause" + }, "node_modules/abbrev": { "version": "2.0.0", "dev": true, @@ -14763,6 +14772,16 @@ "node": ">=8" } }, + "node_modules/find-yarn-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "micromatch": "^4.0.2" + } + }, "node_modules/flatted": { "version": "3.3.3", "dev": true, @@ -16566,11 +16585,38 @@ "dev": true, "license": "MIT" }, + "node_modules/json-stable-stringify": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.3.0.tgz", + "integrity": "sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "isarray": "^2.0.5", + "jsonify": "^0.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "dev": true, "license": "MIT" }, + "node_modules/json-stable-stringify/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, "node_modules/json5": { "version": "2.2.3", "dev": true, @@ -16595,6 +16641,16 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", + "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", + "dev": true, + "license": "Public Domain", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "dev": true, @@ -16648,6 +16704,16 @@ "node": ">=0.10.0" } }, + "node_modules/klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.11" + } + }, "node_modules/kleur": { "version": "3.0.3", "dev": true, @@ -19111,6 +19177,131 @@ "node": ">= 0.8" } }, + "node_modules/patch-package": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.1.tgz", + "integrity": "sha512-VsKRIA8f5uqHQ7NGhwIna6Bx6D9s/1iXlA1hthBVBEbkq+t4kXD0HHt+rJhf/Z+Ci0F/HCB2hvn0qLdLG+Qxlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^4.1.2", + "ci-info": "^3.7.0", + "cross-spawn": "^7.0.3", + "find-yarn-workspace-root": "^2.0.0", + "fs-extra": "^10.0.0", + "json-stable-stringify": "^1.0.2", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.6", + "open": "^7.4.2", + "semver": "^7.5.3", + "slash": "^2.0.0", + "tmp": "^0.2.4", + "yaml": "^2.2.2" + }, + "bin": { + "patch-package": "index.js" + }, + "engines": { + "node": ">=14", + "npm": ">5" + } + }, + "node_modules/patch-package/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/patch-package/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/patch-package/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/patch-package/node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/patch-package/node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/patch-package/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/patch-package/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/path-browserify": { "version": "1.0.1", "dev": true, @@ -24706,6 +24897,16 @@ "node": ">=14.0.0" } }, + "node_modules/tmp": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "dev": true, diff --git a/package.json b/package.json index 6836581153f..65a1b20fe35 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "lint:css:fix": "npm run lint:css -- --fix", "lint:fix": "npm run lint -- --fix", "lint:md": "markdownlint-cli2 \"**/*.{md,mdx}\" \"!.github\" \"!.changeset\" \"!**/node_modules/**\" \"!**/CHANGELOG.md\"", + "postinstall": "patch-package", "test": "vitest", "test:type-check": "tsc --noEmit", "test:update": "npm run test -- -u", @@ -81,6 +82,7 @@ "globals": "^16.2.0", "markdownlint-cli2": "^0.19.0", "markdownlint-cli2-formatter-pretty": "^0.0.8", + "patch-package": "^8.0.1", "prettier": "3.4.2", "rimraf": "5.0.5", "size-limit": "11.2.0", diff --git a/packages/react/src/ActionBar/ActionBar.tsx b/packages/react/src/ActionBar/ActionBar.tsx index 7f2745ef218..7fc7801ca7d 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) @@ -586,7 +589,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..f629c80d7ba 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 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..52ee15dcb2f 100644 --- a/packages/react/src/Autocomplete/Autocomplete.features.stories.tsx +++ b/packages/react/src/Autocomplete/Autocomplete.features.stories.tsx @@ -462,7 +462,7 @@ 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,7 @@ function AutocompleteOverlay({ preventFocusOnOpen={true} onClickOutside={closeOptionList} onEscape={closeOptionList} - ref={floatingElementRef as React.RefObject} + 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..2b62bbab72b 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 (
{child}
) - const buttonRef = useProvidedRefOrCreate(forwardRef as React.RefObject) + const buttonRef = useProvidedRefOrCreate(forwardRef as React.RefObject) useFocusZone({ containerRef: buttonRef, diff --git a/packages/react/src/Checkbox/Checkbox.tsx b/packages/react/src/Checkbox/Checkbox.tsx index d54c372cd80..70a02ab2a5e 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) diff --git a/packages/react/src/ConfirmationDialog/ConfirmationDialog.tsx b/packages/react/src/ConfirmationDialog/ConfirmationDialog.tsx index e6e1cb6ffe3..6fd39fe3335 100644 --- a/packages/react/src/ConfirmationDialog/ConfirmationDialog.tsx +++ b/packages/react/src/ConfirmationDialog/ConfirmationDialog.tsx @@ -108,7 +108,7 @@ const ConfirmationFooter: React.FC> = ({foo // Must have exactly 2 buttons! return ( -
} className={classes.ConfirmationFooter}> +
} className={classes.ConfirmationFooter}>
) diff --git a/packages/react/src/Dialog/Dialog.tsx b/packages/react/src/Dialog/Dialog.tsx index 301bc80304c..1d2989ef080 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,7 @@ const DefaultFooter: React.FC> = ({footerBu focusInStrategy: 'closest', }) return footerButtons ? ( - }> + }> ) : null diff --git a/packages/react/src/FilteredActionList/FilteredActionList.tsx b/packages/react/src/FilteredActionList/FilteredActionList.tsx index 4c2b59b2cc2..413867d5377 100644 --- a/packages/react/src/FilteredActionList/FilteredActionList.tsx +++ b/packages/react/src/FilteredActionList/FilteredActionList.tsx @@ -32,9 +32,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 diff --git a/packages/react/src/FilteredActionList/useAnnouncements.tsx b/packages/react/src/FilteredActionList/useAnnouncements.tsx index c3026078eba..dcc3a03062a 100644 --- a/packages/react/src/FilteredActionList/useAnnouncements.tsx +++ b/packages/react/src/FilteredActionList/useAnnouncements.tsx @@ -19,7 +19,7 @@ const useFirstRender = () => { } const getItemWithActiveDescendant = ( - listRef: React.RefObject, + listRef: React.RefObject, items: FilteredActionListProps['items'], ) => { const listElement = listRef.current @@ -40,8 +40,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..37625fa91ab 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[] @@ -81,7 +81,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,7 +205,7 @@ 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', diff --git a/packages/react/src/Popover/Popover.tsx b/packages/react/src/Popover/Popover.tsx index 6eb3a0d9fea..a6a61d2a9cc 100644 --- a/packages/react/src/Popover/Popover.tsx +++ b/packages/react/src/Popover/Popover.tsx @@ -5,7 +5,7 @@ import React, {useRef} from 'react' import {useOnOutsideClick} from '../hooks' // Stable empty array reference to avoid unnecessary re-renders -const EMPTY_IGNORE_CLICK_REFS: React.RefObject[] = [] +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.tsx b/packages/react/src/Radio/Radio.tsx index 16a98b94a53..59ed4846be5 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 */ diff --git a/packages/react/src/SelectPanel/SelectPanel.tsx b/packages/react/src/SelectPanel/SelectPanel.tsx index cd99fc00bc2..d407a771fca 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) @@ -240,7 +240,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..8ed2d396566 100644 --- a/packages/react/src/Skeleton/SkeletonBox.tsx +++ b/packages/react/src/Skeleton/SkeletonBox.tsx @@ -18,7 +18,7 @@ export const SkeletonBox = React.forwardRef(funct ) { return (
} + 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..a5db7c4fff4 100644 --- a/packages/react/src/TabNav/TabNav.tsx +++ b/packages/react/src/TabNav/TabNav.tsx @@ -51,7 +51,7 @@ function TabNav({children, 'aria-label': ariaLabel, ...rest}: TabNavProps) { ) return ( -
}> +
}>