From 19f593416099c7585beb4af2cb4d1a1e38b83dae Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Fri, 13 Feb 2026 11:55:21 -0500 Subject: [PATCH 01/35] just react 19 test --- package.json | 25 +- packages/gamut-icons/package.json | 2 +- packages/gamut-illustrations/package.json | 4 +- packages/gamut-patterns/package.json | 4 +- packages/gamut-styles/package.json | 2 +- packages/gamut-styles/src/variance/utils.ts | 9 +- packages/gamut-tests/package.json | 2 +- packages/gamut-tests/src/index.tsx | 2 +- packages/gamut/package.json | 4 +- packages/gamut/src/Button/shared/types.ts | 3 +- packages/gamut/src/Coachmark/index.tsx | 2 +- .../Form/SelectDropdown/SelectDropdown.tsx | 4 +- packages/gamut/src/Popover/types.tsx | 4 +- packages/gamut/src/PopoverContainer/hooks.ts | 4 +- packages/gamut/src/Tip/__tests__/helpers.tsx | 2 +- packages/gamut/src/Tip/shared/FloatingTip.tsx | 6 +- packages/gamut/src/Tip/shared/types.tsx | 4 +- packages/gamut/src/utils/react.ts | 7 +- .../styleguide/src/lib/Meta/Installation.mdx | 37 +- .../integration/__tests__/component.test.tsx | 16 +- yarn.lock | 322 +++++------------- 21 files changed, 162 insertions(+), 303 deletions(-) diff --git a/package.json b/package.json index 08c91fa14fe..52699327403 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "@vidstack/react": "^1.12.12", "core-js": "3.7.0", "lodash": "^4.17.23", - "react": "18.3.1", - "react-dom": "18.3.1", + "react": "^19.0.0", + "react-dom": "^19.0.0", "react-helmet-async": "^2.0.5" }, "devDependencies": { @@ -44,18 +44,16 @@ "@storybook/react-webpack5": "^8.6.15", "@storybook/theming": "^8.6.15", "@svgr/cli": "5.5.0", - "@testing-library/dom": "^8.11.1", + "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^5.16.1", - "@testing-library/react": "15.0.6", - "@testing-library/react-hooks": "^7.0.2", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.5.2", "@types/classnames": "2.2.10", "@types/invariant": "2.2.29", "@types/konami-code-js": "^0.8.0", "@types/lodash": "4.17.23", - "@types/react": "18.3.1", - "@types/react-dom": "18.3.0", - "@types/react-test-renderer": "^17.0.1", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", "@types/stylis": "^4.2.0", "@typescript-eslint/eslint-plugin": "^5.15.0", "@typescript-eslint/parser": "^5.15.0", @@ -84,7 +82,6 @@ "nx-cloud": "^19.1.0", "onchange": "^7.0.2", "prettier": "^2.8.7", - "react-test-renderer": "18.3.1", "storybook": "^8.6.15", "storybook-addon-deep-controls": "^0.9.5", "style-loader": "^4.0.0", @@ -113,12 +110,12 @@ "private": true, "repository": "git@github.com:Codecademy/gamut.git", "resolutions": { + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", "@typescript-eslint/utils": "^5.15.0", - "@types/react": "18.3.1", - "@types/react-dom": "18.3.0", - "react": "18.3.1", - "react-dom": "18.3.1", - "error-ex": "1.3.4" + "error-ex": "1.3.4", + "react": "^19.0.0", + "react-dom": "^19.0.0" }, "scripts": { "build": "nx run-many --target=build --all", diff --git a/packages/gamut-icons/package.json b/packages/gamut-icons/package.json index 48935e6ce58..db47d0ea021 100644 --- a/packages/gamut-icons/package.json +++ b/packages/gamut-icons/package.json @@ -17,7 +17,7 @@ "@emotion/react": "^11.4.0", "@emotion/styled": "^11.3.0", "lodash": "^4.17.23", - "react": "^17.0.2 || ^18.2.0" + "react": "^18.3.0 || ^19.0.0" }, "publishConfig": { "access": "public" diff --git a/packages/gamut-illustrations/package.json b/packages/gamut-illustrations/package.json index e72c24d034e..31495010452 100644 --- a/packages/gamut-illustrations/package.json +++ b/packages/gamut-illustrations/package.json @@ -18,8 +18,8 @@ "peerDependencies": { "@emotion/react": "^11.4.0", "@emotion/styled": "^11.3.0", - "react": "^17.0.2 || ^18.2.0", - "react-dom": "^17.0.2 || ^18.2.0" + "react": "^18.3.0 || ^19.0.0", + "react-dom": "^18.3.0 || ^19.0.0" }, "publishConfig": { "access": "public" diff --git a/packages/gamut-patterns/package.json b/packages/gamut-patterns/package.json index 05d97216fa0..33d70adc6c4 100644 --- a/packages/gamut-patterns/package.json +++ b/packages/gamut-patterns/package.json @@ -19,8 +19,8 @@ "peerDependencies": { "@emotion/react": "^11.4.0", "@emotion/styled": "^11.3.0", - "react": "^17.0.2 || ^18.2.0", - "react-dom": "^17.0.2 || ^18.2.0" + "react": "^18.3.0 || ^19.0.0", + "react-dom": "^18.3.0 || ^19.0.0" }, "publishConfig": { "access": "public" diff --git a/packages/gamut-styles/package.json b/packages/gamut-styles/package.json index 7dbfc9ac8fb..462a6a3f22d 100644 --- a/packages/gamut-styles/package.json +++ b/packages/gamut-styles/package.json @@ -24,7 +24,7 @@ "@emotion/react": "^11.4.0", "@emotion/styled": "^11.3.0", "lodash": "^4.17.23", - "react": "^17.0.2 || ^18.2.0", + "react": "^18.3.0 || ^19.0.0", "stylis": "^4.0.7" }, "publishConfig": { diff --git a/packages/gamut-styles/src/variance/utils.ts b/packages/gamut-styles/src/variance/utils.ts index a88b1bfb116..c43cdb88633 100644 --- a/packages/gamut-styles/src/variance/utils.ts +++ b/packages/gamut-styles/src/variance/utils.ts @@ -1,3 +1,4 @@ +import type React from 'react'; import { ThemeProps } from '@codecademy/variance'; import isPropValid from '@emotion/is-prop-valid'; @@ -17,10 +18,12 @@ const validPropnames = allPropnames.filter(isPropValid); export type SystemPropNames = (typeof allPropnames)[number]; -export type ElementOrProps = keyof JSX.IntrinsicElements | ThemeProps; +export type ElementOrProps = + | keyof React.JSX.IntrinsicElements + | ThemeProps; export type ForwardableProps = Exclude< - El extends keyof JSX.IntrinsicElements - ? keyof JSX.IntrinsicElements[El] + El extends keyof React.JSX.IntrinsicElements + ? keyof React.JSX.IntrinsicElements[El] : keyof Element, Additional | SystemPropNames >; diff --git a/packages/gamut-tests/package.json b/packages/gamut-tests/package.json index 7cd578e9a02..514b0c999d9 100644 --- a/packages/gamut-tests/package.json +++ b/packages/gamut-tests/package.json @@ -22,7 +22,7 @@ "main": "dist/index.js", "module": "dist/index.js", "peerDependencies": { - "react": "^17.0.2 || ^18.2.0" + "react": "^18.3.0 || ^19.0.0" }, "publishConfig": { "access": "public" diff --git a/packages/gamut-tests/src/index.tsx b/packages/gamut-tests/src/index.tsx index 72005789548..88e73a7aaa7 100644 --- a/packages/gamut-tests/src/index.tsx +++ b/packages/gamut-tests/src/index.tsx @@ -18,7 +18,7 @@ export const MockGamutProvider: React.FC<{ children?: React.ReactNode }> = ({ ); }; -function withMockGamutProvider( +function withMockGamutProvider( WrappedComponent: React.ComponentType ) { const WithBoundaryComponent: React.FC = (props) => ( diff --git a/packages/gamut/package.json b/packages/gamut/package.json index dda7b640ec6..168bd326e67 100644 --- a/packages/gamut/package.json +++ b/packages/gamut/package.json @@ -37,8 +37,8 @@ "peerDependencies": { "@emotion/react": "^11.4.0", "@emotion/styled": "^11.3.0", - "react": "^17.0.2 || ^18.2.0", - "react-dom": "^17.0.2 || ^18.2.0" + "react": "^18.3.0 || ^19.0.0", + "react-dom": "^18.3.0 || ^19.0.0" }, "publishConfig": { "access": "public" diff --git a/packages/gamut/src/Button/shared/types.ts b/packages/gamut/src/Button/shared/types.ts index 02c84d4e278..6e81c863ed9 100644 --- a/packages/gamut/src/Button/shared/types.ts +++ b/packages/gamut/src/Button/shared/types.ts @@ -1,5 +1,6 @@ import { ColorModes } from '@codecademy/gamut-styles'; import { StyleProps } from '@codecademy/variance'; +import type React from 'react'; import { ComponentProps, HTMLProps } from 'react'; import { ButtonBase } from '../../ButtonBase'; @@ -23,7 +24,7 @@ export type ButtonProps = ButtonBaseProps & ComponentProps; export type InlineIconButtonProps< BaseButtonType extends - | keyof JSX.IntrinsicElements + | keyof React.JSX.IntrinsicElements | React.JSXElementConstructor > = ComponentProps & Partial & { diff --git a/packages/gamut/src/Coachmark/index.tsx b/packages/gamut/src/Coachmark/index.tsx index a4316f6fde3..999c3c0a119 100644 --- a/packages/gamut/src/Coachmark/index.tsx +++ b/packages/gamut/src/Coachmark/index.tsx @@ -30,7 +30,7 @@ export type CoachmarkProps = PopoverFocusProps & { /** * Function that returns the contents of the coachmark. */ - renderPopover: (onDismiss?: () => void) => JSX.Element; + renderPopover: (onDismiss?: () => void) => React.JSX.Element; /** * Props to be passed into the popover component. */ diff --git a/packages/gamut/src/Form/SelectDropdown/SelectDropdown.tsx b/packages/gamut/src/Form/SelectDropdown/SelectDropdown.tsx index f31839eaa46..a122e8258d8 100644 --- a/packages/gamut/src/Form/SelectDropdown/SelectDropdown.tsx +++ b/packages/gamut/src/Form/SelectDropdown/SelectDropdown.tsx @@ -273,7 +273,7 @@ export const SelectDropdown: React.FC = ({ inputWidth={inputWidth} isDisabled={disabled} isMulti={multiple} - isOptionDisabled={(option) => option.disabled} + isOptionDisabled={(option: { disabled?: boolean }) => option.disabled} isSearchable={isSearchable} menuAlignment={menuAlignment} name={name} @@ -285,7 +285,7 @@ export const SelectDropdown: React.FC = ({ styles={memoizedStyles} value={multiple ? multiValues : parsedValue} onChange={changeHandler} - onKeyDown={multiple ? (e) => keyPressHandler(e) : undefined} + onKeyDown={multiple ? (e: React.KeyboardEvent) => keyPressHandler(e) : undefined} {...rest} /> diff --git a/packages/gamut/src/Popover/types.tsx b/packages/gamut/src/Popover/types.tsx index b85d4d4595c..562361bcc52 100755 --- a/packages/gamut/src/Popover/types.tsx +++ b/packages/gamut/src/Popover/types.tsx @@ -99,14 +99,14 @@ export type PopoverProps = PopoverBaseProps & * The target element around which the popover will be positioned. */ targetRef: React.RefObject< - Pick + Pick | null >; /** * The PopoverContainer which contents will be rendered into. */ popoverContainerRef?: - | React.RefObject + | React.RefObject | React.RefCallback; /** diff --git a/packages/gamut/src/PopoverContainer/hooks.ts b/packages/gamut/src/PopoverContainer/hooks.ts index 295591da7cd..16599224b93 100644 --- a/packages/gamut/src/PopoverContainer/hooks.ts +++ b/packages/gamut/src/PopoverContainer/hooks.ts @@ -4,7 +4,7 @@ import { findAllAdditionalScrollingParents, findResizingParent } from './utils'; export const useScrollingParentsEffect = ( targetRef: React.RefObject< - Pick + Pick | null >, setTargetRect: (rect: DOMRect | undefined) => void ) => { @@ -40,7 +40,7 @@ export const useScrollingParentsEffect = ( export const useResizingParentEffect = ( targetRef: React.RefObject< - Pick + Pick | null >, setTargetRect: (rect: DOMRect | undefined) => void ) => { diff --git a/packages/gamut/src/Tip/__tests__/helpers.tsx b/packages/gamut/src/Tip/__tests__/helpers.tsx index da836cbef31..0341dbbe056 100644 --- a/packages/gamut/src/Tip/__tests__/helpers.tsx +++ b/packages/gamut/src/Tip/__tests__/helpers.tsx @@ -17,7 +17,7 @@ type LinkTextParam = { linkText: string }; type InfoParam = { info: string }; type PlacementParam = { placement: TipPlacements }; -export const createFocusOnClick = (ref: RefObject) => { +export const createFocusOnClick = (ref: RefObject) => { return ({ isTipHidden }: { isTipHidden: boolean }) => { if (!isTipHidden) ref.current?.focus(); }; diff --git a/packages/gamut/src/Tip/shared/FloatingTip.tsx b/packages/gamut/src/Tip/shared/FloatingTip.tsx index c3013661549..aa30dea6f0e 100644 --- a/packages/gamut/src/Tip/shared/FloatingTip.tsx +++ b/packages/gamut/src/Tip/shared/FloatingTip.tsx @@ -43,8 +43,8 @@ export const FloatingTip: React.FC = ({ const [isFocused, setIsFocused] = useState(false); // Use refs to store timeouts to prevent race conditions - const hoverDelayRef = useRef(); - const focusDelayRef = useRef(); + const hoverDelayRef = useRef(undefined); + const focusDelayRef = useRef(undefined); const commonPopoverProps = getPopoverAlignmentAndPattern({ alignment, type }); const dims = getAlignmentStyles({ avatar, alignment, type }); @@ -175,7 +175,7 @@ export const FloatingTip: React.FC = ({ horizNarrow={narrow && isHorizontalCenter} isHoverType={isHoverType} narrow={narrow && !isHorizontalCenter} - ref={childRef} + ref={childRef as unknown as React.RefObject} > {contents} diff --git a/packages/gamut/src/Tip/shared/types.tsx b/packages/gamut/src/Tip/shared/types.tsx index 164ed1aaf37..2d828c05292 100644 --- a/packages/gamut/src/Tip/shared/types.tsx +++ b/packages/gamut/src/Tip/shared/types.tsx @@ -79,9 +79,9 @@ export type TipPlacementComponentProps = Omit< id?: string; isTipHidden?: boolean; contentRef?: - | React.RefObject + | React.RefObject | ((node: HTMLDivElement | null) => void); type: 'info' | 'tool' | 'preview'; - wrapperRef?: React.RefObject; + wrapperRef?: React.RefObject; zIndex?: number; } & React.PropsWithChildren; diff --git a/packages/gamut/src/utils/react.ts b/packages/gamut/src/utils/react.ts index c0b673bb24d..bbe171cb68f 100644 --- a/packages/gamut/src/utils/react.ts +++ b/packages/gamut/src/utils/react.ts @@ -1,3 +1,4 @@ +import type React from 'react'; import { Children, isValidElement } from 'react'; /** @@ -35,7 +36,11 @@ export const extractTextContent = (children: React.ReactNode): string => { return ''; } if (isValidElement(child)) { - const textContent = child.props.children ?? child.props.text ?? ''; + const props = (child as React.ReactElement<{ + children?: React.ReactNode; + text?: string; + }>).props; + const textContent = props.children ?? props.text ?? ''; return extractTextContent(textContent); } return ''; diff --git a/packages/styleguide/src/lib/Meta/Installation.mdx b/packages/styleguide/src/lib/Meta/Installation.mdx index f96edcb0294..9d98d932c23 100644 --- a/packages/styleguide/src/lib/Meta/Installation.mdx +++ b/packages/styleguide/src/lib/Meta/Installation.mdx @@ -39,21 +39,44 @@ yarn add @codecademy/gamut-kit @emotion/react @emotion/styled 3. Wrap your application root with `GamutProvider` and give it the theme you would like to use for your app. +**React 19:** + ```tsx import React from 'react'; -import { render } from 'react-dom'; +import { createRoot } from 'react-dom/client'; import { GamutProvider, theme } from '@codecademy/gamut-styles'; import { App } from './App'; const rootElement = document.getElementById('root'); +if (rootElement) { + const root = createRoot(rootElement); + root.render( + + + + ); +} +``` -render( - - - , - rootElement -); +**React 18:** + +```tsx +import React from 'react'; +import { render } from 'react-dom'; +import { GamutProvider, theme } from '@codecademy/gamut-styles'; + +import { App } from './App'; + +const rootElement = document.getElementById('root'); +if (rootElement) { + render( + + + , + rootElement + ); +} ``` GamutProvider handles a few critical tasks that need to happen in order for components to work. diff --git a/packages/variance/integration/__tests__/component.test.tsx b/packages/variance/integration/__tests__/component.test.tsx index bdc494b5fca..f058ac82592 100644 --- a/packages/variance/integration/__tests__/component.test.tsx +++ b/packages/variance/integration/__tests__/component.test.tsx @@ -1,9 +1,9 @@ import { matchers } from '@emotion/jest'; import { ThemeProvider } from '@emotion/react'; import styled from '@emotion/styled'; +import { render } from '@testing-library/react'; import { ComponentProps } from 'react'; import * as React from 'react'; -import renderer from 'react-test-renderer'; import { variance } from '../../src/core'; import { theme } from '../__fixtures__/theme'; @@ -30,13 +30,13 @@ const setupRender = >( return (props?: P) => { const mergedProps = { ...defaultProps, ...props }; - return renderer - .create( - - - - ) - .toJSON(); + const { container } = render( + + + + ); + + return container.firstChild as HTMLElement; }; }; diff --git a/yarn.lock b/yarn.lock index 942a41c4529..a539c48c8ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1626,7 +1626,7 @@ __metadata: "@emotion/react": ^11.4.0 "@emotion/styled": ^11.3.0 lodash: ^4.17.23 - react: ^17.0.2 || ^18.2.0 + react: ^18.3.0 || ^19.0.0 languageName: unknown linkType: soft @@ -1639,8 +1639,8 @@ __metadata: peerDependencies: "@emotion/react": ^11.4.0 "@emotion/styled": ^11.3.0 - react: ^17.0.2 || ^18.2.0 - react-dom: ^17.0.2 || ^18.2.0 + react: ^18.3.0 || ^19.0.0 + react-dom: ^18.3.0 || ^19.0.0 languageName: unknown linkType: soft @@ -1669,8 +1669,8 @@ __metadata: peerDependencies: "@emotion/react": ^11.4.0 "@emotion/styled": ^11.3.0 - react: ^17.0.2 || ^18.2.0 - react-dom: ^17.0.2 || ^18.2.0 + react: ^18.3.0 || ^19.0.0 + react-dom: ^18.3.0 || ^19.0.0 languageName: unknown linkType: soft @@ -1686,7 +1686,7 @@ __metadata: "@emotion/react": ^11.4.0 "@emotion/styled": ^11.3.0 lodash: ^4.17.23 - react: ^17.0.2 || ^18.2.0 + react: ^18.3.0 || ^19.0.0 stylis: ^4.0.7 languageName: unknown linkType: soft @@ -1699,7 +1699,7 @@ __metadata: component-test-setup: "npm:*" lodash: "npm:^4.17.23" peerDependencies: - react: ^17.0.2 || ^18.2.0 + react: ^18.3.0 || ^19.0.0 languageName: unknown linkType: soft @@ -1733,8 +1733,8 @@ __metadata: peerDependencies: "@emotion/react": ^11.4.0 "@emotion/styled": ^11.3.0 - react: ^17.0.2 || ^18.2.0 - react-dom: ^17.0.2 || ^18.2.0 + react: ^18.3.0 || ^19.0.0 + react-dom: ^18.3.0 || ^19.0.0 languageName: unknown linkType: soft @@ -7668,22 +7668,6 @@ __metadata: languageName: node linkType: hard -"@testing-library/dom@npm:^8.11.1": - version: 8.20.1 - resolution: "@testing-library/dom@npm:8.20.1" - dependencies: - "@babel/code-frame": "npm:^7.10.4" - "@babel/runtime": "npm:^7.12.5" - "@types/aria-query": "npm:^5.0.1" - aria-query: "npm:5.1.3" - chalk: "npm:^4.1.0" - dom-accessibility-api: "npm:^0.5.9" - lz-string: "npm:^1.5.0" - pretty-format: "npm:^27.0.2" - checksum: 10c0/614013756706467f2a7f3f693c18377048c210ec809884f0f9be866f7d865d075805ad15f5d100e8a699467fdde09085bf79e23a00ea0a6ab001d9583ef15e5d - languageName: node - linkType: hard - "@testing-library/jest-dom@npm:^5.16.1": version: 5.17.0 resolution: "@testing-library/jest-dom@npm:5.17.0" @@ -7701,43 +7685,23 @@ __metadata: languageName: node linkType: hard -"@testing-library/react-hooks@npm:^7.0.2": - version: 7.0.2 - resolution: "@testing-library/react-hooks@npm:7.0.2" - dependencies: - "@babel/runtime": "npm:^7.12.5" - "@types/react": "npm:>=16.9.0" - "@types/react-dom": "npm:>=16.9.0" - "@types/react-test-renderer": "npm:>=16.9.0" - react-error-boundary: "npm:^3.1.0" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - react-test-renderer: ">=16.9.0" - peerDependenciesMeta: - react-dom: - optional: true - react-test-renderer: - optional: true - checksum: 10c0/249fa57551a1ce63fdfbc7944eeaa2ca4eaae160b6f64b631ceeb150b2d82c1478190471961d04b640e87c6d5417f2e7649600b69068485cd2a20de664716859 - languageName: node - linkType: hard - -"@testing-library/react@npm:15.0.6": - version: 15.0.6 - resolution: "@testing-library/react@npm:15.0.6" +"@testing-library/react@npm:^16.0.0": + version: 16.3.2 + resolution: "@testing-library/react@npm:16.3.2" dependencies: "@babel/runtime": "npm:^7.12.5" - "@testing-library/dom": "npm:^10.0.0" - "@types/react-dom": "npm:^18.0.0" peerDependencies: - "@types/react": ^18.0.0 - react: ^18.0.0 - react-dom: ^18.0.0 + "@testing-library/dom": ^10.0.0 + "@types/react": ^18.0.0 || ^19.0.0 + "@types/react-dom": ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: 10c0/3705a2272f929f2f848f5d7e6ac9829bf7ecc1725a35733ffae7e7a261d4bdab470b080558e8544edb1f9ba25db9fbc4232527df9b4ec6ab6ae4462a902a7f95 + "@types/react-dom": + optional: true + checksum: 10c0/f9c7f0915e1b5f7b750e6c7d8b51f091b8ae7ea99bacb761d7b8505ba25de9cfcb749a0f779f1650fb268b499dd79165dc7e1ee0b8b4cb63430d3ddc81ffe044 languageName: node linkType: hard @@ -8217,13 +8181,6 @@ __metadata: languageName: node linkType: hard -"@types/prop-types@npm:*": - version: 15.7.13 - resolution: "@types/prop-types@npm:15.7.13" - checksum: 10c0/1b20fc67281902c6743379960247bc161f3f0406ffc0df8e7058745a85ea1538612109db0406290512947f9632fe9e10e7337bf0ce6338a91d6c948df16a7c61 - languageName: node - linkType: hard - "@types/q@npm:^1.5.1": version: 1.5.8 resolution: "@types/q@npm:1.5.8" @@ -8245,30 +8202,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:18.3.0": - version: 18.3.0 - resolution: "@types/react-dom@npm:18.3.0" - dependencies: - "@types/react": "npm:*" - checksum: 10c0/6c90d2ed72c5a0e440d2c75d99287e4b5df3e7b011838cdc03ae5cd518ab52164d86990e73246b9d812eaf02ec351d74e3b4f5bd325bf341e13bf980392fd53b - languageName: node - linkType: hard - -"@types/react-test-renderer@npm:>=16.9.0": - version: 18.3.0 - resolution: "@types/react-test-renderer@npm:18.3.0" - dependencies: - "@types/react": "npm:*" - checksum: 10c0/3c9748be52e8e659e7adf91dea6939486463264e6f633bf21c4cb116de18af7bef0595568a1e588160420b2f65289473075dda1cb417c2875df8cf7a09f5d913 - languageName: node - linkType: hard - -"@types/react-test-renderer@npm:^17.0.1": - version: 17.0.9 - resolution: "@types/react-test-renderer@npm:17.0.9" - dependencies: - "@types/react": "npm:^17" - checksum: 10c0/9147c6fbe08b4b8e130758b4b20af1cab7bbb770eadec5336c36d8ccac14202e703a58cd1e90f67b3753390a521ed23f80cb9184c06aafb56d196303cd3394b1 +"@types/react-dom@npm:^19.0.0": + version: 19.2.3 + resolution: "@types/react-dom@npm:19.2.3" + peerDependencies: + "@types/react": ^19.2.0 + checksum: 10c0/b486ebe0f4e2fb35e2e108df1d8fc0927ca5d6002d5771e8a739de11239fe62d0e207c50886185253c99eb9dedfeeb956ea7429e5ba17f6693c7acb4c02f8cd1 languageName: node linkType: hard @@ -8281,13 +8220,12 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:18.3.1": - version: 18.3.1 - resolution: "@types/react@npm:18.3.1" +"@types/react@npm:^19.0.0": + version: 19.2.14 + resolution: "@types/react@npm:19.2.14" dependencies: - "@types/prop-types": "npm:*" - csstype: "npm:^3.0.2" - checksum: 10c0/18d856c12a4ec93f3cda2d58ef3d77a9480818afd3af895f812896fb82cfca1f35a692ab1add4ce826a4eb58a071624c7d1c8c6c4ccfb81c100d2916dc607614 + csstype: "npm:^3.2.2" + checksum: 10c0/7d25bf41b57719452d86d2ac0570b659210402707313a36ee612666bf11275a1c69824f8c3ee1fdca077ccfe15452f6da8f1224529b917050eb2d861e52b59b7 languageName: node linkType: hard @@ -9285,15 +9223,6 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:5.1.3": - version: 5.1.3 - resolution: "aria-query@npm:5.1.3" - dependencies: - deep-equal: "npm:^2.0.5" - checksum: 10c0/edcbc8044c4663d6f88f785e983e6784f98cb62b4ba1e9dd8d61b725d0203e4cfca38d676aee984c31f354103461102a3d583aa4fbe4fd0a89b679744f4e5faf - languageName: node - linkType: hard - "aria-query@npm:5.3.0": version: 5.3.0 resolution: "aria-query@npm:5.3.0" @@ -9310,7 +9239,7 @@ __metadata: languageName: node linkType: hard -"array-buffer-byte-length@npm:^1.0.0, array-buffer-byte-length@npm:^1.0.1": +"array-buffer-byte-length@npm:^1.0.1": version: 1.0.1 resolution: "array-buffer-byte-length@npm:1.0.1" dependencies: @@ -11779,6 +11708,13 @@ __metadata: languageName: node linkType: hard +"csstype@npm:^3.2.2": + version: 3.2.3 + resolution: "csstype@npm:3.2.3" + checksum: 10c0/cd29c51e70fa822f1cecd8641a1445bed7063697469d35633b516e60fe8c1bde04b08f6c5b6022136bb669b64c63d4173af54864510fbb4ee23281801841a3ce + languageName: node + linkType: hard + "damerau-levenshtein@npm:^1.0.8": version: 1.0.8 resolution: "damerau-levenshtein@npm:1.0.8" @@ -11950,32 +11886,6 @@ __metadata: languageName: node linkType: hard -"deep-equal@npm:^2.0.5": - version: 2.2.3 - resolution: "deep-equal@npm:2.2.3" - dependencies: - array-buffer-byte-length: "npm:^1.0.0" - call-bind: "npm:^1.0.5" - es-get-iterator: "npm:^1.1.3" - get-intrinsic: "npm:^1.2.2" - is-arguments: "npm:^1.1.1" - is-array-buffer: "npm:^3.0.2" - is-date-object: "npm:^1.0.5" - is-regex: "npm:^1.1.4" - is-shared-array-buffer: "npm:^1.0.2" - isarray: "npm:^2.0.5" - object-is: "npm:^1.1.5" - object-keys: "npm:^1.1.1" - object.assign: "npm:^4.1.4" - regexp.prototype.flags: "npm:^1.5.1" - side-channel: "npm:^1.0.4" - which-boxed-primitive: "npm:^1.0.2" - which-collection: "npm:^1.0.1" - which-typed-array: "npm:^1.1.13" - checksum: 10c0/a48244f90fa989f63ff5ef0cc6de1e4916b48ea0220a9c89a378561960814794a5800c600254482a2c8fd2e49d6c2e196131dc983976adb024c94a42dfe4949f - languageName: node - linkType: hard - "deep-equal@npm:~1.0.1": version: 1.0.1 resolution: "deep-equal@npm:1.0.1" @@ -12700,23 +12610,6 @@ __metadata: languageName: node linkType: hard -"es-get-iterator@npm:^1.1.3": - version: 1.1.3 - resolution: "es-get-iterator@npm:1.1.3" - dependencies: - call-bind: "npm:^1.0.2" - get-intrinsic: "npm:^1.1.3" - has-symbols: "npm:^1.0.3" - is-arguments: "npm:^1.1.1" - is-map: "npm:^2.0.2" - is-set: "npm:^2.0.2" - is-string: "npm:^1.0.7" - isarray: "npm:^2.0.5" - stop-iteration-iterator: "npm:^1.0.0" - checksum: 10c0/ebd11effa79851ea75d7f079405f9d0dc185559fd65d986c6afea59a0ff2d46c2ed8675f19f03dce7429d7f6c14ff9aede8d121fbab78d75cfda6a263030bac0 - languageName: node - linkType: hard - "es-iterator-helpers@npm:^1.1.0": version: 1.1.0 resolution: "es-iterator-helpers@npm:1.1.0" @@ -14285,18 +14178,16 @@ __metadata: "@storybook/react-webpack5": "npm:^8.6.15" "@storybook/theming": "npm:^8.6.15" "@svgr/cli": "npm:5.5.0" - "@testing-library/dom": "npm:^8.11.1" + "@testing-library/dom": "npm:^10.0.0" "@testing-library/jest-dom": "npm:^5.16.1" - "@testing-library/react": "npm:15.0.6" - "@testing-library/react-hooks": "npm:^7.0.2" + "@testing-library/react": "npm:^16.0.0" "@testing-library/user-event": "npm:^14.5.2" "@types/classnames": "npm:2.2.10" "@types/invariant": "npm:2.2.29" "@types/konami-code-js": "npm:^0.8.0" "@types/lodash": "npm:4.17.23" - "@types/react": "npm:18.3.1" - "@types/react-dom": "npm:18.3.0" - "@types/react-test-renderer": "npm:^17.0.1" + "@types/react": "npm:^19.0.0" + "@types/react-dom": "npm:^19.0.0" "@types/stylis": "npm:^4.2.0" "@typescript-eslint/eslint-plugin": "npm:^5.15.0" "@typescript-eslint/parser": "npm:^5.15.0" @@ -14328,10 +14219,9 @@ __metadata: nx-cloud: "npm:^19.1.0" onchange: "npm:^7.0.2" prettier: "npm:^2.8.7" - react: "npm:18.3.1" - react-dom: "npm:18.3.1" + react: "npm:^19.0.0" + react-dom: "npm:^19.0.0" react-helmet-async: "npm:^2.0.5" - react-test-renderer: "npm:18.3.1" storybook: "npm:^8.6.15" storybook-addon-deep-controls: "npm:^0.9.5" style-loader: "npm:^4.0.0" @@ -14383,7 +14273,7 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.2, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.6": +"get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.6": version: 1.3.0 resolution: "get-intrinsic@npm:1.3.0" dependencies: @@ -15591,7 +15481,7 @@ __metadata: languageName: node linkType: hard -"internal-slot@npm:^1.0.4, internal-slot@npm:^1.0.7": +"internal-slot@npm:^1.0.7": version: 1.0.7 resolution: "internal-slot@npm:1.0.7" dependencies: @@ -15668,7 +15558,7 @@ __metadata: languageName: node linkType: hard -"is-arguments@npm:^1.0.4, is-arguments@npm:^1.1.1": +"is-arguments@npm:^1.0.4": version: 1.1.1 resolution: "is-arguments@npm:1.1.1" dependencies: @@ -15678,7 +15568,7 @@ __metadata: languageName: node linkType: hard -"is-array-buffer@npm:^3.0.2, is-array-buffer@npm:^3.0.4": +"is-array-buffer@npm:^3.0.4": version: 3.0.4 resolution: "is-array-buffer@npm:3.0.4" dependencies: @@ -15896,7 +15786,7 @@ __metadata: languageName: node linkType: hard -"is-map@npm:^2.0.2, is-map@npm:^2.0.3": +"is-map@npm:^2.0.3": version: 2.0.3 resolution: "is-map@npm:2.0.3" checksum: 10c0/2c4d431b74e00fdda7162cd8e4b763d6f6f217edf97d4f8538b94b8702b150610e2c64961340015fe8df5b1fcee33ccd2e9b62619c4a8a3a155f8de6d6d355fc @@ -16024,7 +15914,7 @@ __metadata: languageName: node linkType: hard -"is-set@npm:^2.0.2, is-set@npm:^2.0.3": +"is-set@npm:^2.0.3": version: 2.0.3 resolution: "is-set@npm:2.0.3" checksum: 10c0/f73732e13f099b2dc879c2a12341cfc22ccaca8dd504e6edae26484bd5707a35d503fba5b4daad530a9b088ced1ae6c9d8200fd92e09b428fe14ea79ce8080b7 @@ -18022,7 +17912,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.0.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -19603,16 +19493,6 @@ __metadata: languageName: node linkType: hard -"object-is@npm:^1.1.5": - version: 1.1.6 - resolution: "object-is@npm:1.1.6" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - checksum: 10c0/506af444c4dce7f8e31f34fc549e2fb8152d6b9c4a30c6e62852badd7f520b579c679af433e7a072f9d78eb7808d230dc12e1cf58da9154dfbf8813099ea0fe0 - languageName: node - linkType: hard - "object-keys@npm:^1.1.1": version: 1.1.1 resolution: "object-keys@npm:1.1.1" @@ -21614,26 +21494,14 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:18.3.1": - version: 18.3.1 - resolution: "react-dom@npm:18.3.1" - dependencies: - loose-envify: "npm:^1.1.0" - scheduler: "npm:^0.23.2" - peerDependencies: - react: ^18.3.1 - checksum: 10c0/a752496c1941f958f2e8ac56239172296fcddce1365ce45222d04a1947e0cc5547df3e8447f855a81d6d39f008d7c32eab43db3712077f09e3f67c4874973e85 - languageName: node - linkType: hard - -"react-error-boundary@npm:^3.1.0": - version: 3.1.4 - resolution: "react-error-boundary@npm:3.1.4" +"react-dom@npm:^19.0.0": + version: 19.2.4 + resolution: "react-dom@npm:19.2.4" dependencies: - "@babel/runtime": "npm:^7.12.5" + scheduler: "npm:^0.27.0" peerDependencies: - react: ">=16.13.1" - checksum: 10c0/f977ca61823e43de2381d53dd7aa8b4d79ff6a984c9afdc88dc44f9973b99de7fd382d2f0f91f2688e24bb987c0185bf45d0b004f22afaaab0f990a830253bfb + react: ^19.2.4 + checksum: 10c0/f0c63f1794dedb154136d4d0f59af00b41907f4859571c155940296808f4b94bf9c0c20633db75b5b2112ec13d8d7dd4f9bf57362ed48782f317b11d05a44f35 languageName: node linkType: hard @@ -21706,13 +21574,6 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^16.12.0 || ^17.0.0 || ^18.0.0, react-is@npm:^18.0.0, react-is@npm:^18.3.1": - version: 18.3.1 - resolution: "react-is@npm:18.3.1" - checksum: 10c0/f2f1e60010c683479e74c63f96b09fb41603527cd131a9959e2aee1e5a8b0caf270b365e5ca77d4a6b18aae659b60a86150bb3979073528877029b35aecd2072 - languageName: node - linkType: hard - "react-is@npm:^16.13.1, react-is@npm:^16.7.0": version: 16.13.1 resolution: "react-is@npm:16.13.1" @@ -21727,6 +21588,13 @@ __metadata: languageName: node linkType: hard +"react-is@npm:^18.0.0, react-is@npm:^18.3.1": + version: 18.3.1 + resolution: "react-is@npm:18.3.1" + checksum: 10c0/f2f1e60010c683479e74c63f96b09fb41603527cd131a9959e2aee1e5a8b0caf270b365e5ca77d4a6b18aae659b60a86150bb3979073528877029b35aecd2072 + languageName: node + linkType: hard + "react-player@npm:^2.16.0": version: 2.16.0 resolution: "react-player@npm:2.16.0" @@ -21797,18 +21665,6 @@ __metadata: languageName: node linkType: hard -"react-shallow-renderer@npm:^16.15.0": - version: 16.15.0 - resolution: "react-shallow-renderer@npm:16.15.0" - dependencies: - object-assign: "npm:^4.1.1" - react-is: "npm:^16.12.0 || ^17.0.0 || ^18.0.0" - peerDependencies: - react: ^16.0.0 || ^17.0.0 || ^18.0.0 - checksum: 10c0/c194d741792e86043a4ae272f7353c1cb9412bc649945c4220c6a101a6ea5410cceb3d65d5a4d750f11a24f7426e8eec7977e8a4e3ad5d3ee235ca2b18166fa8 - languageName: node - linkType: hard - "react-stately@npm:^3.37.0": version: 3.37.0 resolution: "react-stately@npm:3.37.0" @@ -21861,19 +21717,6 @@ __metadata: languageName: node linkType: hard -"react-test-renderer@npm:18.3.1": - version: 18.3.1 - resolution: "react-test-renderer@npm:18.3.1" - dependencies: - react-is: "npm:^18.3.1" - react-shallow-renderer: "npm:^16.15.0" - scheduler: "npm:^0.23.2" - peerDependencies: - react: ^18.3.1 - checksum: 10c0/c633558ef9af33bc68f0c4dbb5163a004c4fb9eade7bd0a7cfc0355fb367f36bd9d96533c90b7e85a146be6c525113a15f58683d269e0177ad77e2b04d4fe51c - languageName: node - linkType: hard - "react-transition-group@npm:^4.3.0": version: 4.4.5 resolution: "react-transition-group@npm:4.4.5" @@ -21938,12 +21781,10 @@ __metadata: languageName: node linkType: hard -"react@npm:18.3.1": - version: 18.3.1 - resolution: "react@npm:18.3.1" - dependencies: - loose-envify: "npm:^1.1.0" - checksum: 10c0/283e8c5efcf37802c9d1ce767f302dd569dd97a70d9bb8c7be79a789b9902451e0d16334b05d73299b20f048cbc3c7d288bbbde10b701fa194e2089c237dbea3 +"react@npm:^19.0.0": + version: 19.2.4 + resolution: "react@npm:19.2.4" + checksum: 10c0/cd2c9ff67a720799cc3b38a516009986f7fc4cb8d3e15716c6211cf098d1357ee3e348ab05ad0600042bbb0fd888530ba92e329198c92eafa0994f5213396596 languageName: node linkType: hard @@ -22195,7 +22036,7 @@ __metadata: languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.5.1, regexp.prototype.flags@npm:^1.5.2": +"regexp.prototype.flags@npm:^1.5.2": version: 1.5.3 resolution: "regexp.prototype.flags@npm:1.5.3" dependencies: @@ -23073,12 +22914,10 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:^0.23.2": - version: 0.23.2 - resolution: "scheduler@npm:0.23.2" - dependencies: - loose-envify: "npm:^1.1.0" - checksum: 10c0/26383305e249651d4c58e6705d5f8425f153211aef95f15161c151f7b8de885f24751b377e4a0b3dd42cce09aad3f87a61dab7636859c0d89b7daf1a1e2a5c78 +"scheduler@npm:^0.27.0": + version: 0.27.0 + resolution: "scheduler@npm:0.27.0" + checksum: 10c0/4f03048cb05a3c8fddc45813052251eca00688f413a3cee236d984a161da28db28ba71bd11e7a3dd02f7af84ab28d39fb311431d3b3772fed557945beb00c452 languageName: node linkType: hard @@ -23779,15 +23618,6 @@ __metadata: languageName: node linkType: hard -"stop-iteration-iterator@npm:^1.0.0": - version: 1.0.0 - resolution: "stop-iteration-iterator@npm:1.0.0" - dependencies: - internal-slot: "npm:^1.0.4" - checksum: 10c0/c4158d6188aac510d9e92925b58709207bd94699e9c31186a040c80932a687f84a51356b5895e6dc72710aad83addb9411c22171832c9ae0e6e11b7d61b0dfb9 - languageName: node - linkType: hard - "storybook-addon-deep-controls@npm:^0.9.5": version: 0.9.5 resolution: "storybook-addon-deep-controls@npm:0.9.5" @@ -25966,7 +25796,7 @@ __metadata: languageName: node linkType: hard -"which-collection@npm:^1.0.1, which-collection@npm:^1.0.2": +"which-collection@npm:^1.0.2": version: 1.0.2 resolution: "which-collection@npm:1.0.2" dependencies: @@ -25978,7 +25808,7 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.13, which-typed-array@npm:^1.1.14, which-typed-array@npm:^1.1.15, which-typed-array@npm:^1.1.2": +"which-typed-array@npm:^1.1.14, which-typed-array@npm:^1.1.15, which-typed-array@npm:^1.1.2": version: 1.1.15 resolution: "which-typed-array@npm:1.1.15" dependencies: From ddbd9835868b67052532818982f56631efa20906 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Fri, 13 Feb 2026 12:33:13 -0500 Subject: [PATCH 02/35] re yarn + add notes; --- packages/gamut/src/ConnectedForm/ConnectedForm.tsx | 8 ++++---- yarn.lock | 7 ------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/packages/gamut/src/ConnectedForm/ConnectedForm.tsx b/packages/gamut/src/ConnectedForm/ConnectedForm.tsx index 95575145d48..faedf0d290d 100644 --- a/packages/gamut/src/ConnectedForm/ConnectedForm.tsx +++ b/packages/gamut/src/ConnectedForm/ConnectedForm.tsx @@ -181,7 +181,7 @@ export const ConnectedForm = forwardRef( ); } -) as >( - props: ConnectedFormProps, - ref: React.ForwardedRef -) => React.ReactElement; + // CASS COME BACK TO THIS + // React 19 JSX types expect single-arg components; forwardRef uses (props, ref) + // eslint-disable-next-line @typescript-eslint/no-explicit-any +) as any; diff --git a/yarn.lock b/yarn.lock index 2d14d2f455c..a2a3e41de0d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11708,13 +11708,6 @@ __metadata: languageName: node linkType: hard -"csstype@npm:^3.2.2": - version: 3.2.3 - resolution: "csstype@npm:3.2.3" - checksum: 10c0/cd29c51e70fa822f1cecd8641a1445bed7063697469d35633b516e60fe8c1bde04b08f6c5b6022136bb669b64c63d4173af54864510fbb4ee23281801841a3ce - languageName: node - linkType: hard - "damerau-levenshtein@npm:^1.0.8": version: 1.0.8 resolution: "damerau-levenshtein@npm:1.0.8" From 7e2e6189187bb2541218d2b8ffb8cff2ea288fb0 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Fri, 13 Feb 2026 14:31:47 -0500 Subject: [PATCH 03/35] format --- packages/gamut-styles/src/variance/utils.ts | 6 ++---- .../src/Form/SelectDropdown/SelectDropdown.tsx | 6 +++++- packages/gamut/src/Popover/types.tsx | 7 ++++--- packages/gamut/src/PopoverContainer/hooks.ts | 14 ++++++++------ packages/gamut/src/utils/react.ts | 4 ++-- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/packages/gamut-styles/src/variance/utils.ts b/packages/gamut-styles/src/variance/utils.ts index c43cdb88633..efccefdd8cd 100644 --- a/packages/gamut-styles/src/variance/utils.ts +++ b/packages/gamut-styles/src/variance/utils.ts @@ -1,6 +1,6 @@ -import type React from 'react'; import { ThemeProps } from '@codecademy/variance'; import isPropValid from '@emotion/is-prop-valid'; +import type React from 'react'; import { all as allProps } from './config'; @@ -18,9 +18,7 @@ const validPropnames = allPropnames.filter(isPropValid); export type SystemPropNames = (typeof allPropnames)[number]; -export type ElementOrProps = - | keyof React.JSX.IntrinsicElements - | ThemeProps; +export type ElementOrProps = keyof React.JSX.IntrinsicElements | ThemeProps; export type ForwardableProps = Exclude< El extends keyof React.JSX.IntrinsicElements ? keyof React.JSX.IntrinsicElements[El] diff --git a/packages/gamut/src/Form/SelectDropdown/SelectDropdown.tsx b/packages/gamut/src/Form/SelectDropdown/SelectDropdown.tsx index a122e8258d8..4d7586121ed 100644 --- a/packages/gamut/src/Form/SelectDropdown/SelectDropdown.tsx +++ b/packages/gamut/src/Form/SelectDropdown/SelectDropdown.tsx @@ -285,7 +285,11 @@ export const SelectDropdown: React.FC = ({ styles={memoizedStyles} value={multiple ? multiValues : parsedValue} onChange={changeHandler} - onKeyDown={multiple ? (e: React.KeyboardEvent) => keyPressHandler(e) : undefined} + onKeyDown={ + multiple + ? (e: React.KeyboardEvent) => keyPressHandler(e) + : undefined + } {...rest} /> diff --git a/packages/gamut/src/Popover/types.tsx b/packages/gamut/src/Popover/types.tsx index 562361bcc52..1a605f43097 100755 --- a/packages/gamut/src/Popover/types.tsx +++ b/packages/gamut/src/Popover/types.tsx @@ -98,9 +98,10 @@ export type PopoverProps = PopoverBaseProps & /** * The target element around which the popover will be positioned. */ - targetRef: React.RefObject< - Pick | null - >; + targetRef: React.RefObject | null>; /** * The PopoverContainer which contents will be rendered into. diff --git a/packages/gamut/src/PopoverContainer/hooks.ts b/packages/gamut/src/PopoverContainer/hooks.ts index 16599224b93..8ddd9c13d35 100644 --- a/packages/gamut/src/PopoverContainer/hooks.ts +++ b/packages/gamut/src/PopoverContainer/hooks.ts @@ -3,9 +3,10 @@ import { useEffect, useMemo } from 'react'; import { findAllAdditionalScrollingParents, findResizingParent } from './utils'; export const useScrollingParentsEffect = ( - targetRef: React.RefObject< - Pick | null - >, + targetRef: React.RefObject | null>, setTargetRect: (rect: DOMRect | undefined) => void ) => { useEffect(() => { @@ -39,9 +40,10 @@ export const useScrollingParentsEffect = ( }; export const useResizingParentEffect = ( - targetRef: React.RefObject< - Pick | null - >, + targetRef: React.RefObject | null>, setTargetRect: (rect: DOMRect | undefined) => void ) => { useEffect(() => { diff --git a/packages/gamut/src/utils/react.ts b/packages/gamut/src/utils/react.ts index bbe171cb68f..4153862353e 100644 --- a/packages/gamut/src/utils/react.ts +++ b/packages/gamut/src/utils/react.ts @@ -36,10 +36,10 @@ export const extractTextContent = (children: React.ReactNode): string => { return ''; } if (isValidElement(child)) { - const props = (child as React.ReactElement<{ + const { props } = child as React.ReactElement<{ children?: React.ReactNode; text?: string; - }>).props; + }>; const textContent = props.children ?? props.text ?? ''; return extractTextContent(textContent); } From 7ad4ad1b6852f1bc7f29359d4c50b132b0628e6a Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Thu, 26 Feb 2026 10:17:05 -0500 Subject: [PATCH 04/35] add React 18 test suite --- .github/workflows/test.yml | 42 ++++++++++++ package.json | 4 ++ packages/gamut/README.md | 17 +++++ .../__snapshots__/utils.test.tsx.snap | 67 ------------------- .../gamut/src/Form/__tests__/utils.test.tsx | 46 +++++++++++-- packages/gamut/src/Tip/__tests__/helpers.tsx | 30 ++++----- script/jest/base-setup.js | 3 + script/set-react-resolutions.js | 49 ++++++++++++++ script/test-gamut-react-version.js | 49 ++++++++++++++ 9 files changed, 218 insertions(+), 89 deletions(-) delete mode 100644 packages/gamut/src/Form/__tests__/__snapshots__/utils.test.tsx.snap create mode 100644 script/set-react-resolutions.js create mode 100644 script/test-gamut-react-version.js diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3322ad9daf8..59add9494d2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -74,3 +74,45 @@ jobs: fail_ci_if_error: false directory: ./coverage report_type: test_results + + test-react-18: + name: Test suite (React 18) + runs-on: ubuntu-24.04 + timeout-minutes: 30 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + - name: Fetch main branch + run: git fetch origin main:main + if: github.event_name == 'pull_request' + - name: Setup Node.js + uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 + with: + node-version-file: .nvmrc + - name: Enable Corepack and prepare Yarn 4 + run: corepack enable + shell: bash + - name: Set React 18 resolutions + run: node script/set-react-resolutions.js 18 + - name: Install dependencies + run: yarn install + shell: bash + - name: Build all packages + run: yarn build + shell: bash + - name: Run test suite + run: | + if [ "${{ github.ref_name }}" == "main" ]; then + npx nx run-many --target=test --all --parallel=4 --ci --coverage --runInBand --skip-nx-cache + else + npx nx affected --target=test --parallel=4 --ci --coverage --runInBand + fi + shell: bash + - name: Upload test results (React 18) + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + if: ${{ !cancelled() }} + with: + name: test-results-react-18 + path: ./coverage + retention-days: 30 diff --git a/package.json b/package.json index 52699327403..f0ad1328055 100644 --- a/package.json +++ b/package.json @@ -133,6 +133,10 @@ "start": "yarn && yarn start:storybook", "start:storybook": "nx storybook styleguide", "test": "nx run-many --target=test --all", + "test:gamut": "jest --config=packages/gamut/jest.config.ts", + "test:gamut:react18": "node script/test-gamut-react-version.js 18", + "test:gamut:react19": "node script/test-gamut-react-version.js 19", + "test:gamut:all": "yarn test:gamut:react18 && yarn test:gamut:react19", "verify": "nx run-many --target=verify --parallel=3 --all", "verify-all": "yarn verify" }, diff --git a/packages/gamut/README.md b/packages/gamut/README.md index 184751a86e4..d80a6dbe83c 100644 --- a/packages/gamut/README.md +++ b/packages/gamut/README.md @@ -18,3 +18,20 @@ When considering whether to add a component to Gamut, answer these questions: Components are written using the [`:focus-visible`](https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo) selector, which is not supported in all major browsers. The neighboring `@codecademy/webpack-config` package uses [`postcss-focus-visible`](https://www.npmjs.com/package/postcss-focus-visible) to support the selector, which assumes your app uses the [`postcss-visible`](https://www.npmjs.com/package/focus-visible) polyfill. + +## Testing + +From the repo root, run the Gamut test suite: + +- **`yarn test:gamut`** – runs Jest directly with the repo’s current install (React 19 by default). Use this for normal development (recommended if `nx run gamut:test` fails with "Failed to start plugin worker"). +- **`nx run gamut:test`** – runs via Nx (requires Nx plugin worker). + +## React version compatibility + +Gamut supports **React 18.3+** and **React 19** (see `peerDependencies` in `package.json`). CI runs the full test suite (all packages) on React 19 in the main Test Suite job and on React 18 in the "Test suite (React 18)" job. + +To run the same locally from the repo root: + +- **`yarn test:gamut:react18`** – installs React 18, runs the Gamut suite, then restores package.json. +- **`yarn test:gamut:react19`** – same with React 19. +- **`yarn test:gamut:all`** – runs both (React 18 then React 19). diff --git a/packages/gamut/src/Form/__tests__/__snapshots__/utils.test.tsx.snap b/packages/gamut/src/Form/__tests__/__snapshots__/utils.test.tsx.snap deleted file mode 100644 index 2690797df50..00000000000 --- a/packages/gamut/src/Form/__tests__/__snapshots__/utils.test.tsx.snap +++ /dev/null @@ -1,67 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`parseSelectOptions creates an option list 1`] = ` -[ - , - , -] -`; - -exports[`parseSelectOptions creates an option list 2`] = ` -[ - , - , -] -`; - -exports[`parseSelectOptions creates an option list as object 1`] = ` -[ - { - "key": "test-val", - "label": "Value", - "value": "val", - }, - { - "key": "test-val2", - "label": "Value 2", - "value": "val2", - }, -] -`; - -exports[`parseSelectOptions creates an option list as object without generated labels 1`] = ` -[ - { - "label": "val", - "value": "val", - }, - { - "label": "val2", - "value": "val2", - }, -] -`; diff --git a/packages/gamut/src/Form/__tests__/utils.test.tsx b/packages/gamut/src/Form/__tests__/utils.test.tsx index cda1177880e..74359d200e8 100644 --- a/packages/gamut/src/Form/__tests__/utils.test.tsx +++ b/packages/gamut/src/Form/__tests__/utils.test.tsx @@ -1,21 +1,50 @@ import { parseOptions, parseSelectOptions } from '../utils'; describe(parseSelectOptions, () => { - it('creates an option list', () => { + it('creates an option list from object map', () => { const options = parseSelectOptions({ id: 'test', options: { val: 'Value', val2: 'Value 2' }, }); - expect(options).toMatchSnapshot(); + expect(options).toHaveLength(2); + expect(options[0].type).toBe('option'); + expect(options[0].props).toMatchObject({ + 'data-testid': 'test-val', + label: 'Value', + value: 'val', + }); + expect(options[0].props.children).toBe('Value'); + expect(options[1].type).toBe('option'); + expect(options[1].props).toMatchObject({ + 'data-testid': 'test-val2', + label: 'Value 2', + value: 'val2', + }); + expect(options[1].props.children).toBe('Value 2'); }); - it('creates an option list', () => { + + it('creates an option list from string array', () => { const options = parseSelectOptions({ id: 'test', options: ['val', 'val2'], }); - expect(options).toMatchSnapshot(); + expect(options).toHaveLength(2); + expect(options[0].type).toBe('option'); + expect(options[0].props).toMatchObject({ + 'data-testid': 'test-val', + label: 'val', + value: 'val', + }); + expect(options[0].props.children).toBe('val'); + expect(options[1].type).toBe('option'); + expect(options[1].props).toMatchObject({ + 'data-testid': 'test-val2', + label: 'val2', + value: 'val2', + }); + expect(options[1].props.children).toBe('val2'); }); it('creates an option list as object', () => { const options = parseOptions({ @@ -23,14 +52,19 @@ describe(parseSelectOptions, () => { options: { val: 'Value', val2: 'Value 2' }, }); - expect(options).toMatchSnapshot(); + expect(options).toHaveLength(2); + expect(options[0]).toMatchObject({ key: 'test-val', label: 'Value', value: 'val' }); + expect(options[1]).toMatchObject({ key: 'test-val2', label: 'Value 2', value: 'val2' }); }); + it('creates an option list as object without generated labels', () => { const options = parseOptions({ id: 'test', options: ['val', 'val2'], }); - expect(options).toMatchSnapshot(); + expect(options).toHaveLength(2); + expect(options[0]).toMatchObject({ label: 'val', value: 'val' }); + expect(options[1]).toMatchObject({ label: 'val2', value: 'val2' }); }); }); diff --git a/packages/gamut/src/Tip/__tests__/helpers.tsx b/packages/gamut/src/Tip/__tests__/helpers.tsx index 0341dbbe056..abf3df1750a 100644 --- a/packages/gamut/src/Tip/__tests__/helpers.tsx +++ b/packages/gamut/src/Tip/__tests__/helpers.tsx @@ -419,24 +419,22 @@ export const openInfoTipsWithKeyboard = async ({ }) => { const buttons = view.getAllByLabelText('Show information'); - await act(async () => { - buttons[0].focus(); - await userEvent.keyboard('{Enter}'); - - for (let i = 1; i < count; i += 1) { - // eslint-disable-next-line no-await-in-loop - await userEvent.tab(); - // eslint-disable-next-line no-await-in-loop + // Sequential: each tip must open before focusing the next (portals/effects are async) + for (let i = 0; i < count; i += 1) { + // eslint-disable-next-line no-await-in-loop -- opening tips one-by-one is intentional + await act(async () => { + buttons[i].focus(); await userEvent.keyboard('{Enter}'); - } - }); - - // Wait for all tips to finish opening - await waitFor(() => { - buttons.forEach((button) => { - expect(button).toHaveAttribute('aria-expanded', 'true'); }); - }); + // Wait for this tip to open before opening the next (portals/effects can be async) + // eslint-disable-next-line no-await-in-loop -- opening tips one-by-one is intentional + await waitFor( + () => { + expect(buttons[i]).toHaveAttribute('aria-expanded', 'true'); + }, + { timeout: 2000 } + ); + } }; export const expectTipsVisible = (tips: { text: string }[]) => { diff --git a/script/jest/base-setup.js b/script/jest/base-setup.js index 73799f78701..4909e3e9f93 100644 --- a/script/jest/base-setup.js +++ b/script/jest/base-setup.js @@ -1,3 +1,6 @@ +// Tell React 18/19 we are in an act()-aware test environment (Jest + RTL) +globalThis.IS_REACT_ACT_ENVIRONMENT = true; + // Set fixed date Date.now = jest.fn(() => new Date(2011, 6, 1).valueOf()); diff --git a/script/set-react-resolutions.js b/script/set-react-resolutions.js new file mode 100644 index 00000000000..4716704d735 --- /dev/null +++ b/script/set-react-resolutions.js @@ -0,0 +1,49 @@ +#!/usr/bin/env node +/** + * Sets package.json resolutions (and root dependencies) for React 18 or 19. + * Usage: node script/set-react-resolutions.js <18|19> + * Used by CI and by test:gamut:react18 / test:gamut:react19 for local runs. + */ + +const fs = require('fs'); +const path = require('path'); + +const version = process.argv[2]; +if (version !== '18' && version !== '19') { + console.error('Usage: node script/set-react-resolutions.js <18|19>'); + process.exit(1); +} + +const pkgPath = path.join(__dirname, '..', 'package.json'); +const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); + +const resolutions = { + 18: { + react: '^18.3.0', + 'react-dom': '^18.3.0', + '@types/react': '^18.2.0', + '@types/react-dom': '^18.2.0', + }, + 19: { + react: '^19.0.0', + 'react-dom': '^19.0.0', + '@types/react': '^19.0.0', + '@types/react-dom': '^19.0.0', + }, +}; + +const next = resolutions[version]; +if (!pkg.resolutions) pkg.resolutions = {}; +Object.assign(pkg.resolutions, next); + +if (pkg.dependencies) { + if (pkg.dependencies.react) pkg.dependencies.react = next.react; + if (pkg.dependencies['react-dom']) pkg.dependencies['react-dom'] = next['react-dom']; +} +if (pkg.devDependencies) { + if (pkg.devDependencies['@types/react']) pkg.devDependencies['@types/react'] = next['@types/react']; + if (pkg.devDependencies['@types/react-dom']) pkg.devDependencies['@types/react-dom'] = next['@types/react-dom']; +} + +fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n'); +console.log(`Set React resolutions to ${version}.x`); diff --git a/script/test-gamut-react-version.js b/script/test-gamut-react-version.js new file mode 100644 index 00000000000..2736bf8851b --- /dev/null +++ b/script/test-gamut-react-version.js @@ -0,0 +1,49 @@ +#!/usr/bin/env node +/** + * Run the Gamut test suite with a specific React major (18 or 19), then restore package.json. + * Usage: node script/test-gamut-react-version.js <18|19> + * Used by yarn test:gamut:react18 and yarn test:gamut:react19. + */ + +const fs = require('fs'); +const path = require('path'); +const { spawnSync } = require('child_process'); + +const version = process.argv[2]; +if (version !== '18' && version !== '19') { + console.error('Usage: node script/test-gamut-react-version.js <18|19>'); + process.exit(1); +} + +const repoRoot = path.join(__dirname, '..'); +const pkgPath = path.join(repoRoot, 'package.json'); +const pkgBackup = fs.readFileSync(pkgPath, 'utf8'); + +function run(cmd, args, opts = {}) { + const r = spawnSync(cmd, args, { + stdio: 'inherit', + cwd: repoRoot, + shell: true, + ...opts, + }); + return r.status; +} + +let exitCode = 0; +try { + run('node', ['script/set-react-resolutions.js', version]); + // Allow lockfile to change when switching React version (avoid immutable install failure) + const installStatus = run('yarn', ['install'], { + env: { ...process.env, CI: undefined }, + }); + if (installStatus !== 0) { + console.error('yarn install failed'); + exitCode = installStatus; + } else { + exitCode = run('yarn', ['test:gamut']); + } +} finally { + fs.writeFileSync(pkgPath, pkgBackup); + run('yarn', ['install'], { stdio: 'pipe', env: { ...process.env, CI: undefined } }); +} +process.exit(exitCode); From e860c1fa2bb494f0cfd43c964240299b444ea741 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Thu, 26 Feb 2026 10:30:01 -0500 Subject: [PATCH 05/35] not immutable for react 18 test --- .github/workflows/test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 59add9494d2..7767507e507 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -79,6 +79,9 @@ jobs: name: Test suite (React 18) runs-on: ubuntu-24.04 timeout-minutes: 30 + env: + # Allow lockfile update after resolution change (hardened mode forbids it on public PRs) + YARN_ENABLE_IMMUTABLE_INSTALLS: false steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: From b9575da51ee0923f0ee88bf43fc71e1ccb50e047 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Thu, 26 Feb 2026 10:57:34 -0500 Subject: [PATCH 06/35] type polyfill --- .../gamut/src/Form/SelectDropdown/SelectDropdown.tsx | 2 +- packages/gamut/src/react-18-ref.d.ts | 10 ++++++++++ packages/gamut/tsconfig.lib.json | 5 ++++- 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 packages/gamut/src/react-18-ref.d.ts diff --git a/packages/gamut/src/Form/SelectDropdown/SelectDropdown.tsx b/packages/gamut/src/Form/SelectDropdown/SelectDropdown.tsx index 4d7586121ed..745b0d96751 100644 --- a/packages/gamut/src/Form/SelectDropdown/SelectDropdown.tsx +++ b/packages/gamut/src/Form/SelectDropdown/SelectDropdown.tsx @@ -273,7 +273,7 @@ export const SelectDropdown: React.FC = ({ inputWidth={inputWidth} isDisabled={disabled} isMulti={multiple} - isOptionDisabled={(option: { disabled?: boolean }) => option.disabled} + isOptionDisabled={(option: { disabled?: boolean }) => option.disabled ?? false} isSearchable={isSearchable} menuAlignment={menuAlignment} name={name} diff --git a/packages/gamut/src/react-18-ref.d.ts b/packages/gamut/src/react-18-ref.d.ts new file mode 100644 index 00000000000..27b26e558ef --- /dev/null +++ b/packages/gamut/src/react-18-ref.d.ts @@ -0,0 +1,10 @@ +import 'react'; + +declare module 'react' { + export type Ref = + | import('react').RefCallback + | import('react').RefObject + | import('react').RefObject + | null; + export type LegacyRef = Ref; +} diff --git a/packages/gamut/tsconfig.lib.json b/packages/gamut/tsconfig.lib.json index 03b140a47b0..c14842b4f07 100644 --- a/packages/gamut/tsconfig.lib.json +++ b/packages/gamut/tsconfig.lib.json @@ -5,7 +5,9 @@ "outDir": "./dist", "rootDir": "./src", "paths": {}, - "types": ["node"] + "types": [ + "node" + ] }, "files": [ "../../node_modules/@nx/react/typings/cssmodule.d.ts", @@ -25,6 +27,7 @@ "include": [ "src/**/*.ts", "src/**/*.tsx", + "src/react-18-ref.d.ts", "../../packages/gamut-styles/dist/typings/theme.d.ts" ] } From 980da2a4fecbf5ae616e43db21780878d866224e Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Thu, 26 Feb 2026 12:01:59 -0500 Subject: [PATCH 07/35] test patch in CI --- .github/workflows/test.yml | 3 ++ packages/gamut/src/react-18-ref.d.ts | 10 ---- packages/gamut/tsconfig.lib.json | 1 - script/patch-react-18-ref-types.js | 45 ++++++++++++++++++ yarn.lock | 69 +++++++++++++++++----------- 5 files changed, 89 insertions(+), 39 deletions(-) delete mode 100644 packages/gamut/src/react-18-ref.d.ts create mode 100644 script/patch-react-18-ref-types.js diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7767507e507..7c87300dc75 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -101,6 +101,9 @@ jobs: - name: Install dependencies run: yarn install shell: bash + - name: Patch React 18 ref types + run: node script/patch-react-18-ref-types.js + shell: bash - name: Build all packages run: yarn build shell: bash diff --git a/packages/gamut/src/react-18-ref.d.ts b/packages/gamut/src/react-18-ref.d.ts deleted file mode 100644 index 27b26e558ef..00000000000 --- a/packages/gamut/src/react-18-ref.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import 'react'; - -declare module 'react' { - export type Ref = - | import('react').RefCallback - | import('react').RefObject - | import('react').RefObject - | null; - export type LegacyRef = Ref; -} diff --git a/packages/gamut/tsconfig.lib.json b/packages/gamut/tsconfig.lib.json index c14842b4f07..d0ddaf2685c 100644 --- a/packages/gamut/tsconfig.lib.json +++ b/packages/gamut/tsconfig.lib.json @@ -27,7 +27,6 @@ "include": [ "src/**/*.ts", "src/**/*.tsx", - "src/react-18-ref.d.ts", "../../packages/gamut-styles/dist/typings/theme.d.ts" ] } diff --git a/script/patch-react-18-ref-types.js b/script/patch-react-18-ref-types.js new file mode 100644 index 00000000000..3cd407adae9 --- /dev/null +++ b/script/patch-react-18-ref-types.js @@ -0,0 +1,45 @@ +#!/usr/bin/env node +/** + * Patches @types/react (18.x only) so Ref includes RefObject, + * fixing TS2322 when passing useRef(null) to DOM ref props. + * Run after yarn install when using React 18 (e.g. in CI test-react-18 job). + */ + +const fs = require('fs'); +const path = require('path'); + +const typesReactPath = path.join(__dirname, '..', 'node_modules', '@types', 'react'); +const pkgPath = path.join(typesReactPath, 'package.json'); + +if (!fs.existsSync(pkgPath)) { + console.warn('patch-react-18-ref-types: @types/react not found, skipping'); + process.exit(0); +} + +const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); +const major = parseInt(pkg.version.split('.')[0], 10); +if (major !== 18) { + console.log('patch-react-18-ref-types: @types/react is not 18.x, skipping'); + process.exit(0); +} + +const oldRef = 'type Ref = RefCallback | RefObject | null;'; +const newRef = 'type Ref = RefCallback | RefObject | RefObject | null;'; + +const files = ['index.d.ts', 'ts5.0/index.d.ts']; +let patched = 0; + +for (const file of files) { + const filePath = path.join(typesReactPath, file); + if (!fs.existsSync(filePath)) continue; + let content = fs.readFileSync(filePath, 'utf8'); + if (content.includes(oldRef)) { + content = content.replace(oldRef, newRef); + fs.writeFileSync(filePath, content); + patched++; + } +} + +if (patched > 0) { + console.log(`patch-react-18-ref-types: patched Ref type in ${patched} file(s)`); +} diff --git a/yarn.lock b/yarn.lock index 52b55ac406a..11dabb9c116 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8181,6 +8181,13 @@ __metadata: languageName: node linkType: hard +"@types/prop-types@npm:*": + version: 15.7.15 + resolution: "@types/prop-types@npm:15.7.15" + checksum: 10c0/b59aad1ad19bf1733cf524fd4e618196c6c7690f48ee70a327eb450a42aab8e8a063fbe59ca0a5701aebe2d92d582292c0fb845ea57474f6a15f6994b0e260b2 + languageName: node + linkType: hard + "@types/q@npm:^1.5.1": version: 1.5.8 resolution: "@types/q@npm:1.5.8" @@ -8202,12 +8209,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^19.0.0": - version: 19.2.3 - resolution: "@types/react-dom@npm:19.2.3" +"@types/react-dom@npm:^18.2.0": + version: 18.3.7 + resolution: "@types/react-dom@npm:18.3.7" peerDependencies: - "@types/react": ^19.2.0 - checksum: 10c0/b486ebe0f4e2fb35e2e108df1d8fc0927ca5d6002d5771e8a739de11239fe62d0e207c50886185253c99eb9dedfeeb956ea7429e5ba17f6693c7acb4c02f8cd1 + "@types/react": ^18.0.0 + checksum: 10c0/8bd309e2c3d1604a28a736a24f96cbadf6c05d5288cfef8883b74f4054c961b6b3a5e997fd5686e492be903c8f3380dba5ec017eff3906b1256529cd2d39603e languageName: node linkType: hard @@ -8220,12 +8227,13 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^19.0.0": - version: 19.2.14 - resolution: "@types/react@npm:19.2.14" +"@types/react@npm:^18.2.0": + version: 18.3.28 + resolution: "@types/react@npm:18.3.28" dependencies: + "@types/prop-types": "npm:*" csstype: "npm:^3.2.2" - checksum: 10c0/7d25bf41b57719452d86d2ac0570b659210402707313a36ee612666bf11275a1c69824f8c3ee1fdca077ccfe15452f6da8f1224529b917050eb2d861e52b59b7 + checksum: 10c0/683e19cd12b5c691215529af2e32b5ffbaccae3bf0ba93bfafa0e460e8dfee18423afed568be2b8eadf4b837c3749dd296a4f64e2d79f68fa66962c05f5af661 languageName: node linkType: hard @@ -14179,8 +14187,8 @@ __metadata: "@types/invariant": "npm:2.2.29" "@types/konami-code-js": "npm:^0.8.0" "@types/lodash": "npm:4.17.23" - "@types/react": "npm:^19.0.0" - "@types/react-dom": "npm:^19.0.0" + "@types/react": "npm:^18.2.0" + "@types/react-dom": "npm:^18.2.0" "@types/stylis": "npm:^4.2.0" "@typescript-eslint/eslint-plugin": "npm:^5.15.0" "@typescript-eslint/parser": "npm:^5.15.0" @@ -14212,8 +14220,8 @@ __metadata: nx-cloud: "npm:^19.1.0" onchange: "npm:^7.0.2" prettier: "npm:^2.8.7" - react: "npm:^19.0.0" - react-dom: "npm:^19.0.0" + react: "npm:^18.3.0" + react-dom: "npm:^18.3.0" react-helmet-async: "npm:^2.0.5" storybook: "npm:^8.6.15" storybook-addon-deep-controls: "npm:^0.9.5" @@ -17905,7 +17913,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.0.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -21487,14 +21495,15 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:^19.0.0": - version: 19.2.4 - resolution: "react-dom@npm:19.2.4" +"react-dom@npm:^18.3.0": + version: 18.3.1 + resolution: "react-dom@npm:18.3.1" dependencies: - scheduler: "npm:^0.27.0" + loose-envify: "npm:^1.1.0" + scheduler: "npm:^0.23.2" peerDependencies: - react: ^19.2.4 - checksum: 10c0/f0c63f1794dedb154136d4d0f59af00b41907f4859571c155940296808f4b94bf9c0c20633db75b5b2112ec13d8d7dd4f9bf57362ed48782f317b11d05a44f35 + react: ^18.3.1 + checksum: 10c0/a752496c1941f958f2e8ac56239172296fcddce1365ce45222d04a1947e0cc5547df3e8447f855a81d6d39f008d7c32eab43db3712077f09e3f67c4874973e85 languageName: node linkType: hard @@ -21774,10 +21783,12 @@ __metadata: languageName: node linkType: hard -"react@npm:^19.0.0": - version: 19.2.4 - resolution: "react@npm:19.2.4" - checksum: 10c0/cd2c9ff67a720799cc3b38a516009986f7fc4cb8d3e15716c6211cf098d1357ee3e348ab05ad0600042bbb0fd888530ba92e329198c92eafa0994f5213396596 +"react@npm:^18.3.0": + version: 18.3.1 + resolution: "react@npm:18.3.1" + dependencies: + loose-envify: "npm:^1.1.0" + checksum: 10c0/283e8c5efcf37802c9d1ce767f302dd569dd97a70d9bb8c7be79a789b9902451e0d16334b05d73299b20f048cbc3c7d288bbbde10b701fa194e2089c237dbea3 languageName: node linkType: hard @@ -22907,10 +22918,12 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:^0.27.0": - version: 0.27.0 - resolution: "scheduler@npm:0.27.0" - checksum: 10c0/4f03048cb05a3c8fddc45813052251eca00688f413a3cee236d984a161da28db28ba71bd11e7a3dd02f7af84ab28d39fb311431d3b3772fed557945beb00c452 +"scheduler@npm:^0.23.2": + version: 0.23.2 + resolution: "scheduler@npm:0.23.2" + dependencies: + loose-envify: "npm:^1.1.0" + checksum: 10c0/26383305e249651d4c58e6705d5f8425f153211aef95f15161c151f7b8de885f24751b377e4a0b3dd42cce09aad3f87a61dab7636859c0d89b7daf1a1e2a5c78 languageName: node linkType: hard From 28d3b2e42f70a1211256c781d669d8ecf4c69218 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Thu, 26 Feb 2026 12:32:37 -0500 Subject: [PATCH 08/35] test yarn --- yarn.lock | 69 ++++++++++++++++++++++--------------------------------- 1 file changed, 28 insertions(+), 41 deletions(-) diff --git a/yarn.lock b/yarn.lock index 11dabb9c116..52b55ac406a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8181,13 +8181,6 @@ __metadata: languageName: node linkType: hard -"@types/prop-types@npm:*": - version: 15.7.15 - resolution: "@types/prop-types@npm:15.7.15" - checksum: 10c0/b59aad1ad19bf1733cf524fd4e618196c6c7690f48ee70a327eb450a42aab8e8a063fbe59ca0a5701aebe2d92d582292c0fb845ea57474f6a15f6994b0e260b2 - languageName: node - linkType: hard - "@types/q@npm:^1.5.1": version: 1.5.8 resolution: "@types/q@npm:1.5.8" @@ -8209,12 +8202,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^18.2.0": - version: 18.3.7 - resolution: "@types/react-dom@npm:18.3.7" +"@types/react-dom@npm:^19.0.0": + version: 19.2.3 + resolution: "@types/react-dom@npm:19.2.3" peerDependencies: - "@types/react": ^18.0.0 - checksum: 10c0/8bd309e2c3d1604a28a736a24f96cbadf6c05d5288cfef8883b74f4054c961b6b3a5e997fd5686e492be903c8f3380dba5ec017eff3906b1256529cd2d39603e + "@types/react": ^19.2.0 + checksum: 10c0/b486ebe0f4e2fb35e2e108df1d8fc0927ca5d6002d5771e8a739de11239fe62d0e207c50886185253c99eb9dedfeeb956ea7429e5ba17f6693c7acb4c02f8cd1 languageName: node linkType: hard @@ -8227,13 +8220,12 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.0": - version: 18.3.28 - resolution: "@types/react@npm:18.3.28" +"@types/react@npm:^19.0.0": + version: 19.2.14 + resolution: "@types/react@npm:19.2.14" dependencies: - "@types/prop-types": "npm:*" csstype: "npm:^3.2.2" - checksum: 10c0/683e19cd12b5c691215529af2e32b5ffbaccae3bf0ba93bfafa0e460e8dfee18423afed568be2b8eadf4b837c3749dd296a4f64e2d79f68fa66962c05f5af661 + checksum: 10c0/7d25bf41b57719452d86d2ac0570b659210402707313a36ee612666bf11275a1c69824f8c3ee1fdca077ccfe15452f6da8f1224529b917050eb2d861e52b59b7 languageName: node linkType: hard @@ -14187,8 +14179,8 @@ __metadata: "@types/invariant": "npm:2.2.29" "@types/konami-code-js": "npm:^0.8.0" "@types/lodash": "npm:4.17.23" - "@types/react": "npm:^18.2.0" - "@types/react-dom": "npm:^18.2.0" + "@types/react": "npm:^19.0.0" + "@types/react-dom": "npm:^19.0.0" "@types/stylis": "npm:^4.2.0" "@typescript-eslint/eslint-plugin": "npm:^5.15.0" "@typescript-eslint/parser": "npm:^5.15.0" @@ -14220,8 +14212,8 @@ __metadata: nx-cloud: "npm:^19.1.0" onchange: "npm:^7.0.2" prettier: "npm:^2.8.7" - react: "npm:^18.3.0" - react-dom: "npm:^18.3.0" + react: "npm:^19.0.0" + react-dom: "npm:^19.0.0" react-helmet-async: "npm:^2.0.5" storybook: "npm:^8.6.15" storybook-addon-deep-controls: "npm:^0.9.5" @@ -17913,7 +17905,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.0.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -21495,15 +21487,14 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:^18.3.0": - version: 18.3.1 - resolution: "react-dom@npm:18.3.1" +"react-dom@npm:^19.0.0": + version: 19.2.4 + resolution: "react-dom@npm:19.2.4" dependencies: - loose-envify: "npm:^1.1.0" - scheduler: "npm:^0.23.2" + scheduler: "npm:^0.27.0" peerDependencies: - react: ^18.3.1 - checksum: 10c0/a752496c1941f958f2e8ac56239172296fcddce1365ce45222d04a1947e0cc5547df3e8447f855a81d6d39f008d7c32eab43db3712077f09e3f67c4874973e85 + react: ^19.2.4 + checksum: 10c0/f0c63f1794dedb154136d4d0f59af00b41907f4859571c155940296808f4b94bf9c0c20633db75b5b2112ec13d8d7dd4f9bf57362ed48782f317b11d05a44f35 languageName: node linkType: hard @@ -21783,12 +21774,10 @@ __metadata: languageName: node linkType: hard -"react@npm:^18.3.0": - version: 18.3.1 - resolution: "react@npm:18.3.1" - dependencies: - loose-envify: "npm:^1.1.0" - checksum: 10c0/283e8c5efcf37802c9d1ce767f302dd569dd97a70d9bb8c7be79a789b9902451e0d16334b05d73299b20f048cbc3c7d288bbbde10b701fa194e2089c237dbea3 +"react@npm:^19.0.0": + version: 19.2.4 + resolution: "react@npm:19.2.4" + checksum: 10c0/cd2c9ff67a720799cc3b38a516009986f7fc4cb8d3e15716c6211cf098d1357ee3e348ab05ad0600042bbb0fd888530ba92e329198c92eafa0994f5213396596 languageName: node linkType: hard @@ -22918,12 +22907,10 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:^0.23.2": - version: 0.23.2 - resolution: "scheduler@npm:0.23.2" - dependencies: - loose-envify: "npm:^1.1.0" - checksum: 10c0/26383305e249651d4c58e6705d5f8425f153211aef95f15161c151f7b8de885f24751b377e4a0b3dd42cce09aad3f87a61dab7636859c0d89b7daf1a1e2a5c78 +"scheduler@npm:^0.27.0": + version: 0.27.0 + resolution: "scheduler@npm:0.27.0" + checksum: 10c0/4f03048cb05a3c8fddc45813052251eca00688f413a3cee236d984a161da28db28ba71bd11e7a3dd02f7af84ab28d39fb311431d3b3772fed557945beb00c452 languageName: node linkType: hard From 8b417dfd95ba7f9c2df619d3da05690433471316 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Thu, 26 Feb 2026 13:11:19 -0500 Subject: [PATCH 09/35] fixed --- .../src/__tests__/AssetProvider.test.tsx | 58 ++++++++++--------- .../src/__tests__/fontLoading.test.tsx | 30 +++++----- .../src/__tests__/preloadLinks.ts | 10 ++++ 3 files changed, 56 insertions(+), 42 deletions(-) create mode 100644 packages/gamut-styles/src/__tests__/preloadLinks.ts diff --git a/packages/gamut-styles/src/__tests__/AssetProvider.test.tsx b/packages/gamut-styles/src/__tests__/AssetProvider.test.tsx index 8588c23304d..6280f4aa005 100644 --- a/packages/gamut-styles/src/__tests__/AssetProvider.test.tsx +++ b/packages/gamut-styles/src/__tests__/AssetProvider.test.tsx @@ -5,6 +5,7 @@ import { render } from '@testing-library/react'; import { AssetProvider, createFontLinks } from '../AssetProvider'; import { coreTheme, percipioTheme } from '../themes'; +import { clearPreloadLinks, getPreloadLinks } from './preloadLinks'; const renderView = setupRtl(AssetProvider, {}); @@ -48,6 +49,7 @@ const mockGetFonts = require('../utils/fontUtils').getFonts; describe('AssetProvider', () => { beforeEach(() => { jest.clearAllMocks(); + clearPreloadLinks(); }); describe('createFontLinks', () => { @@ -65,8 +67,8 @@ describe('AssetProvider', () => { }, ]; - const { container } = render(<>{createFontLinks(fonts)}); - const links = container.querySelectorAll('link[rel="preload"]'); + render(<>{createFontLinks(fonts)}); + const links = getPreloadLinks(); expect(links).toHaveLength(1); expect(links[0]).toHaveAttribute( @@ -79,14 +81,14 @@ describe('AssetProvider', () => { }); it('should handle empty fonts array', () => { - const { container } = render(<>{createFontLinks([])}); - const links = container.querySelectorAll('link[rel="preload"]'); + render(<>{createFontLinks([])}); + const links = getPreloadLinks(); expect(links).toHaveLength(0); }); it('should handle undefined fonts parameter', () => { - const { container } = render(<>{createFontLinks(undefined)}); - const links = container.querySelectorAll('link[rel="preload"]'); + render(<>{createFontLinks(undefined)}); + const links = getPreloadLinks(); expect(links).toHaveLength(2); }); @@ -109,8 +111,8 @@ describe('AssetProvider', () => { }, ]; - const { container } = render(<>{createFontLinks(fonts)}); - const links = container.querySelectorAll('link[rel="preload"]'); + render(<>{createFontLinks(fonts)}); + const links = getPreloadLinks(); expect(links).toHaveLength(1); expect(links[0]).toHaveAttribute( 'href', @@ -138,8 +140,8 @@ describe('AssetProvider', () => { }, ]; - const { container } = render(<>{createFontLinks(fonts)}); - const links = container.querySelectorAll('link[rel="preload"]'); + render(<>{createFontLinks(fonts)}); + const links = getPreloadLinks(); expect(links).toHaveLength(2); }); }); @@ -154,8 +156,8 @@ describe('AssetProvider', () => { }, ]); - const { view } = renderView(); - const links = view.container.querySelectorAll('link[rel="preload"]'); + renderView(); + const links = getPreloadLinks(); expect(links).toHaveLength(1); expect(links[0]).toHaveAttribute( @@ -174,8 +176,8 @@ describe('AssetProvider', () => { }, ]); - const { view } = renderView({ theme: percipioTheme as any }); - const links = view.container.querySelectorAll('link[rel="preload"]'); + renderView({ theme: percipioTheme as any }); + const links = getPreloadLinks(); expect(links).toHaveLength(1); expect(links[0]).toHaveAttribute( @@ -206,32 +208,32 @@ describe('AssetProvider', () => { throw new Error('Font loading failed'); }); - const { view } = renderView(); - const links = view.container.querySelectorAll('link[rel="preload"]'); + renderView(); + const links = getPreloadLinks(); expect(links).toHaveLength(0); }); it('should fallback to core fonts when getFonts returns undefined', () => { mockGetFonts.mockReturnValue(undefined); - const { view } = renderView(); - const links = view.container.querySelectorAll('link[rel="preload"]'); + renderView(); + const links = getPreloadLinks(); expect(links).toHaveLength(2); }); it('should fallback to core fonts when getFonts returns null', () => { mockGetFonts.mockReturnValue(null); - const { view } = renderView(); - const links = view.container.querySelectorAll('link[rel="preload"]'); + renderView(); + const links = getPreloadLinks(); expect(links).toHaveLength(2); }); it('should fallback to core fonts when getFonts returns non-array', () => { mockGetFonts.mockReturnValue('not-an-array'); - const { view } = renderView(); - const links = view.container.querySelectorAll('link[rel="preload"]'); + renderView(); + const links = getPreloadLinks(); expect(links).toHaveLength(0); }); @@ -254,8 +256,8 @@ describe('AssetProvider', () => { }, ]); - const { view } = renderView(); - const links = view.container.querySelectorAll('link[rel="preload"]'); + renderView(); + const links = getPreloadLinks(); expect(links).toHaveLength(3); expect(links[0]).toHaveAttribute( @@ -291,8 +293,8 @@ describe('AssetProvider', () => { } as any, ]); - const { view } = renderView(); - const links = view.container.querySelectorAll('link[rel="preload"]'); + renderView(); + const links = getPreloadLinks(); expect(links).toHaveLength(1); expect(links[0]).toHaveAttribute( @@ -320,8 +322,8 @@ describe('AssetProvider', () => { }, ]); - const { view } = renderView(); - const links = view.container.querySelectorAll('link[rel="preload"]'); + renderView(); + const links = getPreloadLinks(); expect(links).toHaveLength(1); expect(links[0]).toHaveAttribute( diff --git a/packages/gamut-styles/src/__tests__/fontLoading.test.tsx b/packages/gamut-styles/src/__tests__/fontLoading.test.tsx index 6a46a50c3ab..2aa6e0651dd 100644 --- a/packages/gamut-styles/src/__tests__/fontLoading.test.tsx +++ b/packages/gamut-styles/src/__tests__/fontLoading.test.tsx @@ -2,6 +2,7 @@ import { render } from '@testing-library/react'; import { AssetProvider } from '../AssetProvider'; import { coreTheme, percipioTheme } from '../themes'; +import { clearPreloadLinks, getPreloadLinks } from './preloadLinks'; // Type assertion to satisfy Theme interface in GamutProvider from theme.d.ts - this lib is typed to the CoreTheme interface const typedPercipioTheme = percipioTheme as any; @@ -53,6 +54,7 @@ describe('Font Loading and Error Handling', () => { mockDocumentFonts.load.mockClear(); mockDocumentFonts.check.mockClear(); mockFetch.mockClear(); + clearPreloadLinks(); }); describe('Font Preloading', () => { @@ -65,9 +67,9 @@ describe('Font Loading and Error Handling', () => { }, ]); - const { container } = render(); + render(); - const links = container.querySelectorAll('link[rel="preload"]'); + const links = getPreloadLinks(); expect(links).toHaveLength(1); expect(links[0]).toHaveAttribute( 'href', @@ -91,9 +93,9 @@ describe('Font Loading and Error Handling', () => { }, ]); - const { container } = render(); + render(); - const links = container.querySelectorAll('link[rel="preload"]'); + const links = getPreloadLinks(); expect(links).toHaveLength(2); expect(links[0]).toHaveAttribute( 'href', @@ -112,10 +114,10 @@ describe('Font Loading and Error Handling', () => { throw new Error('Font loading failed'); }); - const { container } = render(); + render(); // Should not render any links when getFonts fails - const links = container.querySelectorAll('link[rel="preload"]'); + const links = getPreloadLinks(); expect(links).toHaveLength(0); }); @@ -139,9 +141,9 @@ describe('Font Loading and Error Handling', () => { }, ]); - const { container } = render(); + render(); - const links = container.querySelectorAll('link[rel="preload"]'); + const links = getPreloadLinks(); expect(links).toHaveLength(2); }); }); @@ -161,10 +163,10 @@ describe('Font Loading and Error Handling', () => { }, ]); - const { container } = render(); + render(); // Should render preload links for all fonts - const links = container.querySelectorAll('link[rel="preload"]'); + const links = getPreloadLinks(); expect(links).toHaveLength(2); expect(links[0]).toHaveAttribute( 'href', @@ -193,9 +195,9 @@ describe('Font Loading and Error Handling', () => { }, ]); - const { container } = render(); + render(); - const links = container.querySelectorAll('link[rel="preload"]'); + const links = getPreloadLinks(); expect(links).toHaveLength(1); Object.defineProperty(document, 'fonts', { @@ -216,9 +218,9 @@ describe('Font Loading and Error Handling', () => { }, ]); - const { container } = render(); + render(); - const links = container.querySelectorAll('link[rel="preload"]'); + const links = getPreloadLinks(); expect(links).toHaveLength(1); global.fetch = originalFetch; diff --git a/packages/gamut-styles/src/__tests__/preloadLinks.ts b/packages/gamut-styles/src/__tests__/preloadLinks.ts new file mode 100644 index 00000000000..a24336c7a00 --- /dev/null +++ b/packages/gamut-styles/src/__tests__/preloadLinks.ts @@ -0,0 +1,10 @@ +/** + * React 19 hoists into document.head, so tests must query document + * for preload links and clear them between tests. + */ +export const getPreloadLinks = (): NodeListOf => + document.querySelectorAll('link[rel="preload"]'); + +export const clearPreloadLinks = (): void => { + getPreloadLinks().forEach((el) => el.remove()); +}; From fca2a320bb1c3d71f73e038e797ddb0c053f9ea9 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Thu, 26 Feb 2026 15:47:07 -0500 Subject: [PATCH 10/35] fix lint + format commands --- .eslintrc.js | 13 ++ .gitignore | 3 + package.json | 12 +- .../Form/SelectDropdown/SelectDropdown.tsx | 4 +- .../gamut/src/Form/__tests__/utils.test.tsx | 12 +- packages/gamut/tsconfig.lib.json | 4 +- script/patch-react-18-ref-types.js | 15 +- script/set-react-resolutions.js | 9 +- script/test-gamut-react-version.js | 5 +- yarn.lock | 212 +++++++++--------- 10 files changed, 169 insertions(+), 120 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 6aac8591e81..57cafb693f5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -49,6 +49,11 @@ module.exports = { '@typescript-eslint/no-unsafe-return': 'off', '@typescript-eslint/restrict-plus-operands': 'off', '@typescript-eslint/restrict-template-expressions': 'off', + // v7 recommended rules we keep off for now + '@typescript-eslint/no-unsafe-enum-comparison': 'off', + '@typescript-eslint/no-duplicate-type-constituents': 'off', + '@typescript-eslint/no-base-to-string': 'off', + '@typescript-eslint/no-redundant-type-constituents': 'off', 'import/no-cycle': 'off', 'react/no-unknown-property': [ 'error', @@ -81,5 +86,13 @@ module.exports = { 'gamut/no-kbd-element': 'error', }, }, + { + files: ['script/**/*.js'], + env: { node: true, es2020: true }, + rules: { + 'no-console': 'off', + 'no-plusplus': 'off', + }, + }, ], }; diff --git a/.gitignore b/.gitignore index 724fad2facd..f522ac58336 100644 --- a/.gitignore +++ b/.gitignore @@ -51,6 +51,9 @@ tmp dist/storybook dist/docs +# ESLint cache +.eslintcache + # NX dist/out-tsc *.tsbuildinfo diff --git a/package.json b/package.json index f0ad1328055..4dd14e2c712 100644 --- a/package.json +++ b/package.json @@ -55,15 +55,15 @@ "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", "@types/stylis": "^4.2.0", - "@typescript-eslint/eslint-plugin": "^5.15.0", - "@typescript-eslint/parser": "^5.15.0", + "@typescript-eslint/eslint-plugin": "^7.0.0", + "@typescript-eslint/parser": "^7.0.0", "babel-jest": "29.6.4", "babel-plugin-macros": "3.0.1", "component-test-setup": "^0.3.1", "conventional-changelog-cli": "^2.0.34", "conventional-changelog-conventionalcommits": "^4.3.0", "cpy-cli": "^4.1.0", - "eslint": "^8.11.0", + "eslint": "^8.56.0", "eslint-plugin-gamut": "^2.0.0", "eslint-plugin-local-rules": "^1.1.0", "eslint-plugin-lodash": "^7.4.0", @@ -112,7 +112,9 @@ "resolutions": { "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", - "@typescript-eslint/utils": "^5.15.0", + "@typescript-eslint/eslint-plugin": "^7.0.0", + "@typescript-eslint/parser": "^7.0.0", + "@typescript-eslint/utils": "^7.0.0", "error-ex": "1.3.4", "react": "^19.0.0", "react-dom": "^19.0.0" @@ -127,7 +129,7 @@ "deploy": "rm -rf ./dist/docs && mv ./dist/storybook/styleguide ./dist/docs && cp -r ./dist/static/* ./dist/docs && gh-pages -b gh-pages -d dist", "format": "yarn lint:fix && yarn prettier --write", "format:verify": "yarn prettier --check", - "lint": "eslint --ignore-path .eslintignore \"./**/*.{mdx,js,ts,tsx,json}\" --max-warnings 0", + "lint": "eslint --cache --cache-location .eslintcache --ignore-path .eslintignore \"./**/*.{mdx,js,ts,tsx,json}\" --max-warnings 0", "lint:fix": "yarn lint --fix", "prettier": "prettier --ignore-path .prettierignore \"./**/*.{mdx,js,ts,tsx,json,css,scss}\"", "start": "yarn && yarn start:storybook", diff --git a/packages/gamut/src/Form/SelectDropdown/SelectDropdown.tsx b/packages/gamut/src/Form/SelectDropdown/SelectDropdown.tsx index 745b0d96751..c4a4a736a60 100644 --- a/packages/gamut/src/Form/SelectDropdown/SelectDropdown.tsx +++ b/packages/gamut/src/Form/SelectDropdown/SelectDropdown.tsx @@ -273,7 +273,9 @@ export const SelectDropdown: React.FC = ({ inputWidth={inputWidth} isDisabled={disabled} isMulti={multiple} - isOptionDisabled={(option: { disabled?: boolean }) => option.disabled ?? false} + isOptionDisabled={(option: { disabled?: boolean }) => + option.disabled ?? false + } isSearchable={isSearchable} menuAlignment={menuAlignment} name={name} diff --git a/packages/gamut/src/Form/__tests__/utils.test.tsx b/packages/gamut/src/Form/__tests__/utils.test.tsx index 74359d200e8..9fe1103dd1a 100644 --- a/packages/gamut/src/Form/__tests__/utils.test.tsx +++ b/packages/gamut/src/Form/__tests__/utils.test.tsx @@ -53,8 +53,16 @@ describe(parseSelectOptions, () => { }); expect(options).toHaveLength(2); - expect(options[0]).toMatchObject({ key: 'test-val', label: 'Value', value: 'val' }); - expect(options[1]).toMatchObject({ key: 'test-val2', label: 'Value 2', value: 'val2' }); + expect(options[0]).toMatchObject({ + key: 'test-val', + label: 'Value', + value: 'val', + }); + expect(options[1]).toMatchObject({ + key: 'test-val2', + label: 'Value 2', + value: 'val2', + }); }); it('creates an option list as object without generated labels', () => { diff --git a/packages/gamut/tsconfig.lib.json b/packages/gamut/tsconfig.lib.json index d0ddaf2685c..03b140a47b0 100644 --- a/packages/gamut/tsconfig.lib.json +++ b/packages/gamut/tsconfig.lib.json @@ -5,9 +5,7 @@ "outDir": "./dist", "rootDir": "./src", "paths": {}, - "types": [ - "node" - ] + "types": ["node"] }, "files": [ "../../node_modules/@nx/react/typings/cssmodule.d.ts", diff --git a/script/patch-react-18-ref-types.js b/script/patch-react-18-ref-types.js index 3cd407adae9..a4e235c5c39 100644 --- a/script/patch-react-18-ref-types.js +++ b/script/patch-react-18-ref-types.js @@ -8,7 +8,13 @@ const fs = require('fs'); const path = require('path'); -const typesReactPath = path.join(__dirname, '..', 'node_modules', '@types', 'react'); +const typesReactPath = path.join( + __dirname, + '..', + 'node_modules', + '@types', + 'react' +); const pkgPath = path.join(typesReactPath, 'package.json'); if (!fs.existsSync(pkgPath)) { @@ -24,7 +30,8 @@ if (major !== 18) { } const oldRef = 'type Ref = RefCallback | RefObject | null;'; -const newRef = 'type Ref = RefCallback | RefObject | RefObject | null;'; +const newRef = + 'type Ref = RefCallback | RefObject | RefObject | null;'; const files = ['index.d.ts', 'ts5.0/index.d.ts']; let patched = 0; @@ -41,5 +48,7 @@ for (const file of files) { } if (patched > 0) { - console.log(`patch-react-18-ref-types: patched Ref type in ${patched} file(s)`); + console.log( + `patch-react-18-ref-types: patched Ref type in ${patched} file(s)` + ); } diff --git a/script/set-react-resolutions.js b/script/set-react-resolutions.js index 4716704d735..e21a1d070af 100644 --- a/script/set-react-resolutions.js +++ b/script/set-react-resolutions.js @@ -38,11 +38,14 @@ Object.assign(pkg.resolutions, next); if (pkg.dependencies) { if (pkg.dependencies.react) pkg.dependencies.react = next.react; - if (pkg.dependencies['react-dom']) pkg.dependencies['react-dom'] = next['react-dom']; + if (pkg.dependencies['react-dom']) + pkg.dependencies['react-dom'] = next['react-dom']; } if (pkg.devDependencies) { - if (pkg.devDependencies['@types/react']) pkg.devDependencies['@types/react'] = next['@types/react']; - if (pkg.devDependencies['@types/react-dom']) pkg.devDependencies['@types/react-dom'] = next['@types/react-dom']; + if (pkg.devDependencies['@types/react']) + pkg.devDependencies['@types/react'] = next['@types/react']; + if (pkg.devDependencies['@types/react-dom']) + pkg.devDependencies['@types/react-dom'] = next['@types/react-dom']; } fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n'); diff --git a/script/test-gamut-react-version.js b/script/test-gamut-react-version.js index 2736bf8851b..f4d5fe801f9 100644 --- a/script/test-gamut-react-version.js +++ b/script/test-gamut-react-version.js @@ -44,6 +44,9 @@ try { } } finally { fs.writeFileSync(pkgPath, pkgBackup); - run('yarn', ['install'], { stdio: 'pipe', env: { ...process.env, CI: undefined } }); + run('yarn', ['install'], { + stdio: 'pipe', + env: { ...process.env, CI: undefined }, + }); } process.exit(exitCode); diff --git a/yarn.lock b/yarn.lock index 52b55ac406a..faca32c9722 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2432,7 +2432,25 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.4.0, @eslint-community/regexpp@npm:^4.6.1": +"@eslint-community/eslint-utils@npm:^4.4.0": + version: 4.9.1 + resolution: "@eslint-community/eslint-utils@npm:4.9.1" + dependencies: + eslint-visitor-keys: "npm:^3.4.3" + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + checksum: 10c0/dc4ab5e3e364ef27e33666b11f4b86e1a6c1d7cbf16f0c6ff87b1619b3562335e9201a3d6ce806221887ff780ec9d828962a290bb910759fd40a674686503f02 + languageName: node + linkType: hard + +"@eslint-community/regexpp@npm:^4.10.0": + version: 4.12.2 + resolution: "@eslint-community/regexpp@npm:4.12.2" + checksum: 10c0/fddcbc66851b308478d04e302a4d771d6917a0b3740dc351513c0da9ca2eab8a1adf99f5e0aa7ab8b13fa0df005c81adeee7e63a92f3effd7d367a163b721c2d + languageName: node + linkType: hard + +"@eslint-community/regexpp@npm:^4.6.1": version: 4.12.1 resolution: "@eslint-community/regexpp@npm:4.12.1" checksum: 10c0/a03d98c246bcb9109aec2c08e4d10c8d010256538dcb3f56610191607214523d4fb1b00aa81df830b6dffb74c5fa0be03642513a289c567949d3e550ca11cdf6 @@ -8250,7 +8268,7 @@ __metadata: languageName: node linkType: hard -"@types/semver@npm:7.5.8, @types/semver@npm:^7.3.12, @types/semver@npm:^7.3.4": +"@types/semver@npm:7.5.8, @types/semver@npm:^7.3.4": version: 7.5.8 resolution: "@types/semver@npm:7.5.8" checksum: 10c0/8663ff927234d1c5fcc04b33062cb2b9fcfbe0f5f351ed26c4d1e1581657deebd506b41ff7fdf89e787e3d33ce05854bc01686379b89e9c49b564c4cfa988efa @@ -8372,27 +8390,26 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^5.15.0": - version: 5.62.0 - resolution: "@typescript-eslint/eslint-plugin@npm:5.62.0" +"@typescript-eslint/eslint-plugin@npm:^7.0.0": + version: 7.18.0 + resolution: "@typescript-eslint/eslint-plugin@npm:7.18.0" dependencies: - "@eslint-community/regexpp": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:5.62.0" - "@typescript-eslint/type-utils": "npm:5.62.0" - "@typescript-eslint/utils": "npm:5.62.0" - debug: "npm:^4.3.4" + "@eslint-community/regexpp": "npm:^4.10.0" + "@typescript-eslint/scope-manager": "npm:7.18.0" + "@typescript-eslint/type-utils": "npm:7.18.0" + "@typescript-eslint/utils": "npm:7.18.0" + "@typescript-eslint/visitor-keys": "npm:7.18.0" graphemer: "npm:^1.4.0" - ignore: "npm:^5.2.0" - natural-compare-lite: "npm:^1.4.0" - semver: "npm:^7.3.7" - tsutils: "npm:^3.21.0" + ignore: "npm:^5.3.1" + natural-compare: "npm:^1.4.0" + ts-api-utils: "npm:^1.3.0" peerDependencies: - "@typescript-eslint/parser": ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + "@typescript-eslint/parser": ^7.0.0 + eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10c0/3f40cb6bab5a2833c3544e4621b9fdacd8ea53420cadc1c63fac3b89cdf5c62be1e6b7bcf56976dede5db4c43830de298ced3db60b5494a3b961ca1b4bff9f2a + checksum: 10c0/2b37948fa1b0dab77138909dabef242a4d49ab93e4019d4ef930626f0a7d96b03e696cd027fa0087881c20e73be7be77c942606b4a76fa599e6b37f6985304c3 languageName: node linkType: hard @@ -8407,100 +8424,98 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/parser@npm:^5.15.0": - version: 5.62.0 - resolution: "@typescript-eslint/parser@npm:5.62.0" +"@typescript-eslint/parser@npm:^7.0.0": + version: 7.18.0 + resolution: "@typescript-eslint/parser@npm:7.18.0" dependencies: - "@typescript-eslint/scope-manager": "npm:5.62.0" - "@typescript-eslint/types": "npm:5.62.0" - "@typescript-eslint/typescript-estree": "npm:5.62.0" + "@typescript-eslint/scope-manager": "npm:7.18.0" + "@typescript-eslint/types": "npm:7.18.0" + "@typescript-eslint/typescript-estree": "npm:7.18.0" + "@typescript-eslint/visitor-keys": "npm:7.18.0" debug: "npm:^4.3.4" peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10c0/315194b3bf39beb9bd16c190956c46beec64b8371e18d6bb72002108b250983eb1e186a01d34b77eb4045f4941acbb243b16155fbb46881105f65e37dc9e24d4 + checksum: 10c0/370e73fca4278091bc1b657f85e7d74cd52b24257ea20c927a8e17546107ce04fbf313fec99aed0cc2a145ddbae1d3b12e9cc2c1320117636dc1281bcfd08059 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/scope-manager@npm:5.62.0" +"@typescript-eslint/scope-manager@npm:7.18.0": + version: 7.18.0 + resolution: "@typescript-eslint/scope-manager@npm:7.18.0" dependencies: - "@typescript-eslint/types": "npm:5.62.0" - "@typescript-eslint/visitor-keys": "npm:5.62.0" - checksum: 10c0/861253235576c1c5c1772d23cdce1418c2da2618a479a7de4f6114a12a7ca853011a1e530525d0931c355a8fd237b9cd828fac560f85f9623e24054fd024726f + "@typescript-eslint/types": "npm:7.18.0" + "@typescript-eslint/visitor-keys": "npm:7.18.0" + checksum: 10c0/038cd58c2271de146b3a594afe2c99290034033326d57ff1f902976022c8b0138ffd3cb893ae439ae41003b5e4bcc00cabf6b244ce40e8668f9412cc96d97b8e languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/type-utils@npm:5.62.0" +"@typescript-eslint/type-utils@npm:7.18.0": + version: 7.18.0 + resolution: "@typescript-eslint/type-utils@npm:7.18.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:5.62.0" - "@typescript-eslint/utils": "npm:5.62.0" + "@typescript-eslint/typescript-estree": "npm:7.18.0" + "@typescript-eslint/utils": "npm:7.18.0" debug: "npm:^4.3.4" - tsutils: "npm:^3.21.0" + ts-api-utils: "npm:^1.3.0" peerDependencies: - eslint: "*" + eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10c0/93112e34026069a48f0484b98caca1c89d9707842afe14e08e7390af51cdde87378df29d213d3bbd10a7cfe6f91b228031b56218515ce077bdb62ddea9d9f474 + checksum: 10c0/ad92a38007be620f3f7036f10e234abdc2fdc518787b5a7227e55fd12896dacf56e8b34578723fbf9bea8128df2510ba8eb6739439a3879eda9519476d5783fd languageName: node linkType: hard -"@typescript-eslint/types@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/types@npm:5.62.0" - checksum: 10c0/7febd3a7f0701c0b927e094f02e82d8ee2cada2b186fcb938bc2b94ff6fbad88237afc304cbaf33e82797078bbbb1baf91475f6400912f8b64c89be79bfa4ddf +"@typescript-eslint/types@npm:7.18.0": + version: 7.18.0 + resolution: "@typescript-eslint/types@npm:7.18.0" + checksum: 10c0/eb7371ac55ca77db8e59ba0310b41a74523f17e06f485a0ef819491bc3dd8909bb930120ff7d30aaf54e888167e0005aa1337011f3663dc90fb19203ce478054 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/typescript-estree@npm:5.62.0" +"@typescript-eslint/typescript-estree@npm:7.18.0": + version: 7.18.0 + resolution: "@typescript-eslint/typescript-estree@npm:7.18.0" dependencies: - "@typescript-eslint/types": "npm:5.62.0" - "@typescript-eslint/visitor-keys": "npm:5.62.0" + "@typescript-eslint/types": "npm:7.18.0" + "@typescript-eslint/visitor-keys": "npm:7.18.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" - semver: "npm:^7.3.7" - tsutils: "npm:^3.21.0" + minimatch: "npm:^9.0.4" + semver: "npm:^7.6.0" + ts-api-utils: "npm:^1.3.0" peerDependenciesMeta: typescript: optional: true - checksum: 10c0/d7984a3e9d56897b2481940ec803cb8e7ead03df8d9cfd9797350be82ff765dfcf3cfec04e7355e1779e948da8f02bc5e11719d07a596eb1cb995c48a95e38cf + checksum: 10c0/0c7f109a2e460ec8a1524339479cf78ff17814d23c83aa5112c77fb345e87b3642616291908dcddea1e671da63686403dfb712e4a4435104f92abdfddf9aba81 languageName: node linkType: hard -"@typescript-eslint/utils@npm:^5.15.0": - version: 5.62.0 - resolution: "@typescript-eslint/utils@npm:5.62.0" +"@typescript-eslint/utils@npm:^7.0.0": + version: 7.18.0 + resolution: "@typescript-eslint/utils@npm:7.18.0" dependencies: - "@eslint-community/eslint-utils": "npm:^4.2.0" - "@types/json-schema": "npm:^7.0.9" - "@types/semver": "npm:^7.3.12" - "@typescript-eslint/scope-manager": "npm:5.62.0" - "@typescript-eslint/types": "npm:5.62.0" - "@typescript-eslint/typescript-estree": "npm:5.62.0" - eslint-scope: "npm:^5.1.1" - semver: "npm:^7.3.7" + "@eslint-community/eslint-utils": "npm:^4.4.0" + "@typescript-eslint/scope-manager": "npm:7.18.0" + "@typescript-eslint/types": "npm:7.18.0" + "@typescript-eslint/typescript-estree": "npm:7.18.0" peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 10c0/f09b7d9952e4a205eb1ced31d7684dd55cee40bf8c2d78e923aa8a255318d97279825733902742c09d8690f37a50243f4c4d383ab16bd7aefaf9c4b438f785e1 + eslint: ^8.56.0 + checksum: 10c0/a25a6d50eb45c514469a01ff01f215115a4725fb18401055a847ddf20d1b681409c4027f349033a95c4ff7138d28c3b0a70253dfe8262eb732df4b87c547bd1e languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/visitor-keys@npm:5.62.0" +"@typescript-eslint/visitor-keys@npm:7.18.0": + version: 7.18.0 + resolution: "@typescript-eslint/visitor-keys@npm:7.18.0" dependencies: - "@typescript-eslint/types": "npm:5.62.0" - eslint-visitor-keys: "npm:^3.3.0" - checksum: 10c0/7c3b8e4148e9b94d9b7162a596a1260d7a3efc4e65199693b8025c71c4652b8042501c0bc9f57654c1e2943c26da98c0f77884a746c6ae81389fcb0b513d995d + "@typescript-eslint/types": "npm:7.18.0" + eslint-visitor-keys: "npm:^3.4.3" + checksum: 10c0/538b645f8ff1d9debf264865c69a317074eaff0255e63d7407046176b0f6a6beba34a6c51d511f12444bae12a98c69891eb6f403c9f54c6c2e2849d1c1cb73c0 languageName: node linkType: hard @@ -13183,7 +13198,7 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:5.1.1, eslint-scope@npm:^5.1.1": +"eslint-scope@npm:5.1.1": version: 5.1.1 resolution: "eslint-scope@npm:5.1.1" dependencies: @@ -13203,14 +13218,14 @@ __metadata: languageName: node linkType: hard -"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": +"eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": version: 3.4.3 resolution: "eslint-visitor-keys@npm:3.4.3" checksum: 10c0/92708e882c0a5ffd88c23c0b404ac1628cf20104a108c745f240a13c332a11aac54f49a22d5762efbffc18ecbc9a580d1b7ad034bf5f3cc3307e5cbff2ec9820 languageName: node linkType: hard -"eslint@npm:^8.11.0": +"eslint@npm:^8.56.0": version: 8.57.1 resolution: "eslint@npm:8.57.1" dependencies: @@ -14182,8 +14197,8 @@ __metadata: "@types/react": "npm:^19.0.0" "@types/react-dom": "npm:^19.0.0" "@types/stylis": "npm:^4.2.0" - "@typescript-eslint/eslint-plugin": "npm:^5.15.0" - "@typescript-eslint/parser": "npm:^5.15.0" + "@typescript-eslint/eslint-plugin": "npm:^7.0.0" + "@typescript-eslint/parser": "npm:^7.0.0" "@vidstack/react": "npm:^1.12.12" babel-jest: "npm:29.6.4" babel-plugin-macros: "npm:3.0.1" @@ -14192,7 +14207,7 @@ __metadata: conventional-changelog-conventionalcommits: "npm:^4.3.0" core-js: "npm:3.7.0" cpy-cli: "npm:^4.1.0" - eslint: "npm:^8.11.0" + eslint: "npm:^8.56.0" eslint-plugin-gamut: "npm:^2.0.0" eslint-plugin-local-rules: "npm:^1.1.0" eslint-plugin-lodash: "npm:^7.4.0" @@ -15286,7 +15301,7 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.0.4, ignore@npm:^5.1.1, ignore@npm:^5.1.4, ignore@npm:^5.1.9, ignore@npm:^5.2.0, ignore@npm:^5.2.4": +"ignore@npm:^5.0.4, ignore@npm:^5.1.1, ignore@npm:^5.1.4, ignore@npm:^5.1.9, ignore@npm:^5.2.0, ignore@npm:^5.2.4, ignore@npm:^5.3.1": version: 5.3.2 resolution: "ignore@npm:5.3.2" checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 @@ -18807,13 +18822,6 @@ __metadata: languageName: node linkType: hard -"natural-compare-lite@npm:^1.4.0": - version: 1.4.0 - resolution: "natural-compare-lite@npm:1.4.0" - checksum: 10c0/f6cef26f5044515754802c0fc475d81426f3b90fe88c20fabe08771ce1f736ce46e0397c10acb569a4dd0acb84c7f1ee70676122f95d5bfdd747af3a6c6bbaa8 - languageName: node - linkType: hard - "natural-compare@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare@npm:1.4.0" @@ -23026,6 +23034,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.6.0": + version: 7.7.4 + resolution: "semver@npm:7.7.4" + bin: + semver: bin/semver.js + checksum: 10c0/5215ad0234e2845d4ea5bb9d836d42b03499546ddafb12075566899fc617f68794bb6f146076b6881d755de17d6c6cc73372555879ec7dce2c2feee947866ad2 + languageName: node + linkType: hard + "send@npm:0.19.0": version: 0.19.0 resolution: "send@npm:0.19.0" @@ -24477,6 +24494,15 @@ __metadata: languageName: node linkType: hard +"ts-api-utils@npm:^1.3.0": + version: 1.4.3 + resolution: "ts-api-utils@npm:1.4.3" + peerDependencies: + typescript: ">=4.2.0" + checksum: 10c0/e65dc6e7e8141140c23e1dc94984bf995d4f6801919c71d6dc27cf0cd51b100a91ffcfe5217626193e5bea9d46831e8586febdc7e172df3f1091a7384299e23a + languageName: node + linkType: hard + "ts-dedent@npm:^2.0.0": version: 2.2.0 resolution: "ts-dedent@npm:2.2.0" @@ -24626,13 +24652,6 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^1.8.1": - version: 1.14.1 - resolution: "tslib@npm:1.14.1" - checksum: 10c0/69ae09c49eea644bc5ebe1bca4fa4cc2c82b7b3e02f43b84bd891504edf66dbc6b2ec0eef31a957042de2269139e4acff911e6d186a258fb14069cd7f6febce2 - languageName: node - linkType: hard - "tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.6.2, tslib@npm:^2.8.0": version: 2.8.1 resolution: "tslib@npm:2.8.1" @@ -24647,17 +24666,6 @@ __metadata: languageName: node linkType: hard -"tsutils@npm:^3.21.0": - version: 3.21.0 - resolution: "tsutils@npm:3.21.0" - dependencies: - tslib: "npm:^1.8.1" - peerDependencies: - typescript: ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - checksum: 10c0/02f19e458ec78ead8fffbf711f834ad8ecd2cc6ade4ec0320790713dccc0a412b99e7fd907c4cda2a1dc602c75db6f12e0108e87a5afad4b2f9e90a24cabd5a2 - languageName: node - linkType: hard - "tuf-js@npm:^1.1.7": version: 1.1.7 resolution: "tuf-js@npm:1.1.7" From 48deaaf253bfd0594b855c98c130826ced919954 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Thu, 26 Feb 2026 16:11:48 -0500 Subject: [PATCH 11/35] upgrade eslint plugin --- packages/eslint-plugin-gamut/src/gamut-import-paths.ts | 2 +- packages/eslint-plugin-gamut/src/no-css-standalone.test.ts | 6 +++--- packages/eslint-plugin-gamut/src/no-css-standalone.ts | 2 +- packages/eslint-plugin-gamut/src/no-inline-style.test.ts | 6 +++--- packages/eslint-plugin-gamut/src/no-inline-style.ts | 2 +- packages/eslint-plugin-gamut/src/no-kbd-element.test.ts | 6 +++--- packages/eslint-plugin-gamut/src/no-kbd-element.ts | 2 +- packages/eslint-plugin-gamut/src/prefer-themed.test.ts | 6 +++--- packages/eslint-plugin-gamut/src/prefer-themed.ts | 2 +- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/eslint-plugin-gamut/src/gamut-import-paths.ts b/packages/eslint-plugin-gamut/src/gamut-import-paths.ts index a7fcb9601fb..df175e930f9 100644 --- a/packages/eslint-plugin-gamut/src/gamut-import-paths.ts +++ b/packages/eslint-plugin-gamut/src/gamut-import-paths.ts @@ -59,7 +59,7 @@ export default createRule({ meta: { docs: { description: 'Ensure Gamut import statements have proper module paths.', - recommended: 'error', + recommended: 'recommended', }, fixable: 'code', messages: { diff --git a/packages/eslint-plugin-gamut/src/no-css-standalone.test.ts b/packages/eslint-plugin-gamut/src/no-css-standalone.test.ts index cada3987044..1094f1e4993 100644 --- a/packages/eslint-plugin-gamut/src/no-css-standalone.test.ts +++ b/packages/eslint-plugin-gamut/src/no-css-standalone.test.ts @@ -1,9 +1,9 @@ -import { ESLintUtils } from '@typescript-eslint/utils'; +import { TSESLint } from '@typescript-eslint/utils'; import rule from './no-css-standalone'; -const ruleTester = new ESLintUtils.RuleTester({ - parser: '@typescript-eslint/parser', +const ruleTester = new TSESLint.RuleTester({ + parser: require.resolve('@typescript-eslint/parser'), }); ruleTester.run('no-css-standalone', rule, { diff --git a/packages/eslint-plugin-gamut/src/no-css-standalone.ts b/packages/eslint-plugin-gamut/src/no-css-standalone.ts index fe1c66a8656..1dc2c8c20b8 100644 --- a/packages/eslint-plugin-gamut/src/no-css-standalone.ts +++ b/packages/eslint-plugin-gamut/src/no-css-standalone.ts @@ -15,7 +15,7 @@ export default createRule({ meta: { docs: { description: 'Ensure no standalone .css or .scss files.', - recommended: 'error', + recommended: 'recommended', }, messages: { noCssStandalone: diff --git a/packages/eslint-plugin-gamut/src/no-inline-style.test.ts b/packages/eslint-plugin-gamut/src/no-inline-style.test.ts index a1c24e75981..ab7c5c53e13 100644 --- a/packages/eslint-plugin-gamut/src/no-inline-style.test.ts +++ b/packages/eslint-plugin-gamut/src/no-inline-style.test.ts @@ -1,9 +1,9 @@ -import { ESLintUtils } from '@typescript-eslint/utils'; +import { TSESLint } from '@typescript-eslint/utils'; import rule from './no-inline-style'; -const ruleTester = new ESLintUtils.RuleTester({ - parser: '@typescript-eslint/parser', +const ruleTester = new TSESLint.RuleTester({ + parser: require.resolve('@typescript-eslint/parser'), parserOptions: { ecmaFeatures: { jsx: true, diff --git a/packages/eslint-plugin-gamut/src/no-inline-style.ts b/packages/eslint-plugin-gamut/src/no-inline-style.ts index 8e063bbde13..6d7d8492aa6 100644 --- a/packages/eslint-plugin-gamut/src/no-inline-style.ts +++ b/packages/eslint-plugin-gamut/src/no-inline-style.ts @@ -17,7 +17,7 @@ export default createRule({ meta: { docs: { description: 'Disallow inline style props on JSX elements.', - recommended: 'error', + recommended: 'recommended', }, messages: { noInlineStyle: diff --git a/packages/eslint-plugin-gamut/src/no-kbd-element.test.ts b/packages/eslint-plugin-gamut/src/no-kbd-element.test.ts index fc2c7f13da1..30dee531773 100644 --- a/packages/eslint-plugin-gamut/src/no-kbd-element.test.ts +++ b/packages/eslint-plugin-gamut/src/no-kbd-element.test.ts @@ -1,9 +1,9 @@ -import { ESLintUtils } from '@typescript-eslint/utils'; +import { TSESLint } from '@typescript-eslint/utils'; import rule from './no-kbd-element'; -const ruleTester = new ESLintUtils.RuleTester({ - parser: '@typescript-eslint/parser', +const ruleTester = new TSESLint.RuleTester({ + parser: require.resolve('@typescript-eslint/parser'), parserOptions: { ecmaFeatures: { jsx: true, diff --git a/packages/eslint-plugin-gamut/src/no-kbd-element.ts b/packages/eslint-plugin-gamut/src/no-kbd-element.ts index f90de6d1cbc..53e1beb44a2 100644 --- a/packages/eslint-plugin-gamut/src/no-kbd-element.ts +++ b/packages/eslint-plugin-gamut/src/no-kbd-element.ts @@ -18,7 +18,7 @@ export default createRule({ docs: { description: 'Intended to be used in Storybook docs to disallow use of the `kbd` HTML element in favor of the `KeyboardKey` component for styling purposes.', - recommended: 'error', + recommended: 'recommended', }, messages: { noKbdElement: 'Please use the `KeyboardKey` component instead.', diff --git a/packages/eslint-plugin-gamut/src/prefer-themed.test.ts b/packages/eslint-plugin-gamut/src/prefer-themed.test.ts index 1a438cd3247..3d9383afb0c 100644 --- a/packages/eslint-plugin-gamut/src/prefer-themed.test.ts +++ b/packages/eslint-plugin-gamut/src/prefer-themed.test.ts @@ -1,9 +1,9 @@ -import { ESLintUtils } from '@typescript-eslint/utils'; +import { TSESLint } from '@typescript-eslint/utils'; import rule from './prefer-themed'; -const ruleTester = new ESLintUtils.RuleTester({ - parser: '@typescript-eslint/parser', +const ruleTester = new TSESLint.RuleTester({ + parser: require.resolve('@typescript-eslint/parser'), }); ruleTester.run('prefer-themed', rule, { diff --git a/packages/eslint-plugin-gamut/src/prefer-themed.ts b/packages/eslint-plugin-gamut/src/prefer-themed.ts index 45892f197e5..9ff4c6a2a99 100644 --- a/packages/eslint-plugin-gamut/src/prefer-themed.ts +++ b/packages/eslint-plugin-gamut/src/prefer-themed.ts @@ -48,7 +48,7 @@ export default createRule({ meta: { docs: { description: 'Prefer themed style utility', - recommended: 'error', + recommended: 'recommended', }, fixable: 'code', messages: { From 375dcc2d614bbf90b2a1add90879e30892f9051c Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Thu, 26 Feb 2026 16:14:10 -0500 Subject: [PATCH 12/35] deduped --- yarn.lock | 33 +++------------------------------ 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/yarn.lock b/yarn.lock index faca32c9722..e763cb9f159 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2421,18 +2421,7 @@ __metadata: languageName: node linkType: hard -"@eslint-community/eslint-utils@npm:^4.2.0": - version: 4.4.1 - resolution: "@eslint-community/eslint-utils@npm:4.4.1" - dependencies: - eslint-visitor-keys: "npm:^3.4.3" - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: 10c0/2aa0ac2fc50ff3f234408b10900ed4f1a0b19352f21346ad4cc3d83a1271481bdda11097baa45d484dd564c895e0762a27a8240be7a256b3ad47129e96528252 - languageName: node - linkType: hard - -"@eslint-community/eslint-utils@npm:^4.4.0": +"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": version: 4.9.1 resolution: "@eslint-community/eslint-utils@npm:4.9.1" dependencies: @@ -2443,20 +2432,13 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.10.0": +"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.6.1": version: 4.12.2 resolution: "@eslint-community/regexpp@npm:4.12.2" checksum: 10c0/fddcbc66851b308478d04e302a4d771d6917a0b3740dc351513c0da9ca2eab8a1adf99f5e0aa7ab8b13fa0df005c81adeee7e63a92f3effd7d367a163b721c2d languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.6.1": - version: 4.12.1 - resolution: "@eslint-community/regexpp@npm:4.12.1" - checksum: 10c0/a03d98c246bcb9109aec2c08e4d10c8d010256538dcb3f56610191607214523d4fb1b00aa81df830b6dffb74c5fa0be03642513a289c567949d3e550ca11cdf6 - languageName: node - linkType: hard - "@eslint/eslintrc@npm:^2.1.4": version: 2.1.4 resolution: "@eslint/eslintrc@npm:2.1.4" @@ -23025,16 +23007,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.2, semver@npm:^7.6.3, semver@npm:^7.7.2": - version: 7.7.2 - resolution: "semver@npm:7.7.2" - bin: - semver: bin/semver.js - checksum: 10c0/aca305edfbf2383c22571cb7714f48cadc7ac95371b4b52362fb8eeffdfbc0de0669368b82b2b15978f8848f01d7114da65697e56cd8c37b0dab8c58e543f9ea - languageName: node - linkType: hard - -"semver@npm:^7.6.0": +"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.2, semver@npm:^7.6.3, semver@npm:^7.7.2": version: 7.7.4 resolution: "semver@npm:7.7.4" bin: From bff0cc038d050558e31555c89829098697f5cc75 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Fri, 27 Feb 2026 10:19:19 -0500 Subject: [PATCH 13/35] fix Text type --- packages/eslint-plugin-gamut/package.json | 3 +++ packages/gamut/src/Typography/Text.tsx | 17 ++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/eslint-plugin-gamut/package.json b/packages/eslint-plugin-gamut/package.json index 2c14378072c..2487cffc21a 100644 --- a/packages/eslint-plugin-gamut/package.json +++ b/packages/eslint-plugin-gamut/package.json @@ -6,6 +6,9 @@ "dependencies": { "@typescript-eslint/utils": "^5.15.0" }, + "devDependencies": { + "@typescript-eslint/rule-tester": "^7.0.0" + }, "files": [ "dist" ], diff --git a/packages/gamut/src/Typography/Text.tsx b/packages/gamut/src/Typography/Text.tsx index 173661b8632..b6f47a96c4d 100644 --- a/packages/gamut/src/Typography/Text.tsx +++ b/packages/gamut/src/Typography/Text.tsx @@ -125,7 +125,11 @@ export interface BaseTextProps StyleProps, StyleProps, StyleProps, - StyleProps {} + StyleProps { + /** Optional so ellipsis-only truncation doesn't require scroll handlers (React 19+) */ + onScrollEnd?: (event: React.UIEvent) => void; + onScrollEndCapture?: (event: React.UIEvent) => void; +} // if you're going to truncate, you need to provide both of these props or neither export interface TextTruncateProps extends BaseTextProps { @@ -147,9 +151,8 @@ const StyledText = styled('span', styledOptions<'span'>())( textProps ); -export const Text = forwardRef< - HTMLSpanElement, - ComponentProps ->(({ as = 'span', m = 0, ...rest }, ref) => ( - -)); +export const Text = forwardRef>( + ({ as = 'span', m = 0, ...rest }, ref) => ( + + ) +); From b947460d35368e058686ec48ee94be9f5fc417a1 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Fri, 27 Feb 2026 10:27:10 -0500 Subject: [PATCH 14/35] add Text type tests --- .../src/Typography/__tests__/Text.test.tsx | 40 +++++++++++++++++++ yarn.lock | 32 ++++++++++++++- 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 packages/gamut/src/Typography/__tests__/Text.test.tsx diff --git a/packages/gamut/src/Typography/__tests__/Text.test.tsx b/packages/gamut/src/Typography/__tests__/Text.test.tsx new file mode 100644 index 00000000000..37244ecdc45 --- /dev/null +++ b/packages/gamut/src/Typography/__tests__/Text.test.tsx @@ -0,0 +1,40 @@ +import { setupRtl } from '@codecademy/gamut-tests'; +import { fireEvent } from '@testing-library/dom'; + +import { Text } from '../Text'; + +const renderView = setupRtl(Text, { + children: 'Content', + truncate: 'ellipsis', + truncateLines: 1, +}); + +describe('Text', () => { + it('renders ellipsis truncation without requiring scroll handlers', () => { + // Type-safety: ellipsis-only truncation must not require onScrollEnd/onScrollEndCapture. + // If this fails to compile, the Text props have regressed (e.g. React 19 scroll types). + const { view } = renderView({ + children: 'Long content that gets truncated', + whiteSpace: 'nowrap', + title: 'truncated', + }); + + view.getByText('Long content that gets truncated'); + }); + + it('accepts optional onScrollEnd when provided', () => { + const { view } = renderView({ title: 'with handler' }); + + view.getByText('Content'); + }); + + it('calls onScrollEnd when scrollend event fires', () => { + const onScrollEnd = jest.fn(); + const { view } = renderView({ onScrollEnd }); + + const textElement = view.getByText('Content'); + fireEvent(textElement, new Event('scrollend', { bubbles: true })); + + expect(onScrollEnd).toHaveBeenCalledTimes(1); + }); +}); diff --git a/yarn.lock b/yarn.lock index e763cb9f159..2eca6887dc2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8424,6 +8424,23 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/rule-tester@npm:^7.0.0": + version: 7.18.0 + resolution: "@typescript-eslint/rule-tester@npm:7.18.0" + dependencies: + "@typescript-eslint/typescript-estree": "npm:7.18.0" + "@typescript-eslint/utils": "npm:7.18.0" + ajv: "npm:^6.12.6" + json-stable-stringify-without-jsonify: "npm:^1.0.1" + lodash.merge: "npm:4.6.2" + semver: "npm:^7.6.0" + peerDependencies: + "@eslint/eslintrc": ">=2" + eslint: ^8.56.0 + checksum: 10c0/ca18e6cb8957583228c01da2c3f96c3ba9b33f2460f0ee20ebb29260122cacae017545871fa5149dd1098b236df94b3d438382a80b54cb866619fdfa4bf82aa3 + languageName: node + linkType: hard + "@typescript-eslint/scope-manager@npm:7.18.0": version: 7.18.0 resolution: "@typescript-eslint/scope-manager@npm:7.18.0" @@ -9069,6 +9086,18 @@ __metadata: languageName: node linkType: hard +"ajv@npm:^6.12.6": + version: 6.14.0 + resolution: "ajv@npm:6.14.0" + dependencies: + fast-deep-equal: "npm:^3.1.1" + fast-json-stable-stringify: "npm:^2.0.0" + json-schema-traverse: "npm:^0.4.1" + uri-js: "npm:^4.2.2" + checksum: 10c0/a2bc39b0555dc9802c899f86990eb8eed6e366cddbf65be43d5aa7e4f3c4e1a199d5460fd7ca4fb3d864000dbbc049253b72faa83b3b30e641ca52cb29a68c22 + languageName: node + linkType: hard + "ajv@npm:^8.0.0, ajv@npm:^8.12.0, ajv@npm:^8.9.0": version: 8.17.1 resolution: "ajv@npm:8.17.1" @@ -13001,6 +13030,7 @@ __metadata: version: 0.0.0-use.local resolution: "eslint-plugin-gamut@workspace:packages/eslint-plugin-gamut" dependencies: + "@typescript-eslint/rule-tester": "npm:^7.0.0" "@typescript-eslint/utils": "npm:^5.15.0" languageName: unknown linkType: soft @@ -17831,7 +17861,7 @@ __metadata: languageName: node linkType: hard -"lodash.merge@npm:^4.6.2": +"lodash.merge@npm:4.6.2, lodash.merge@npm:^4.6.2": version: 4.6.2 resolution: "lodash.merge@npm:4.6.2" checksum: 10c0/402fa16a1edd7538de5b5903a90228aa48eb5533986ba7fa26606a49db2572bf414ff73a2c9f5d5fd36b31c46a5d5c7e1527749c07cbcf965ccff5fbdf32c506 From 727e695d9ba79f76eef90e111d4826045f26bb49 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Fri, 27 Feb 2026 10:28:57 -0500 Subject: [PATCH 15/35] dedupe? --- yarn.lock | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/yarn.lock b/yarn.lock index 2eca6887dc2..9e8a4444b27 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9074,19 +9074,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^6.12.4, ajv@npm:^6.12.5": - version: 6.12.6 - resolution: "ajv@npm:6.12.6" - dependencies: - fast-deep-equal: "npm:^3.1.1" - fast-json-stable-stringify: "npm:^2.0.0" - json-schema-traverse: "npm:^0.4.1" - uri-js: "npm:^4.2.2" - checksum: 10c0/41e23642cbe545889245b9d2a45854ebba51cda6c778ebced9649420d9205f2efb39cb43dbc41e358409223b1ea43303ae4839db682c848b891e4811da1a5a71 - languageName: node - linkType: hard - -"ajv@npm:^6.12.6": +"ajv@npm:^6.12.4, ajv@npm:^6.12.5, ajv@npm:^6.12.6": version: 6.14.0 resolution: "ajv@npm:6.14.0" dependencies: From 304078185063471a219ea6df9c9879cd591145a2 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Fri, 27 Feb 2026 10:29:07 -0500 Subject: [PATCH 16/35] dedupe? --- packages/gamut/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gamut/project.json b/packages/gamut/project.json index 3e2bef14b11..d88f123cb28 100644 --- a/packages/gamut/project.json +++ b/packages/gamut/project.json @@ -20,7 +20,7 @@ } }, "test": { - "dependsOn": ["^build"], + "dependsOn": ["^build", "verify"], "executor": "@nx/jest:jest", "outputs": ["{workspaceRoot}/coverage/packages/gamut"], "options": { From aa65a7dedb17031ca81b22b67807fda44717a361 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Fri, 27 Feb 2026 10:50:05 -0500 Subject: [PATCH 17/35] formatted --- packages/gamut/src/Typography/Text.tsx | 11 ++--- .../src/Typography/__tests__/Text.test.tsx | 40 ------------------- 2 files changed, 6 insertions(+), 45 deletions(-) delete mode 100644 packages/gamut/src/Typography/__tests__/Text.test.tsx diff --git a/packages/gamut/src/Typography/Text.tsx b/packages/gamut/src/Typography/Text.tsx index b6f47a96c4d..d04be4e4c07 100644 --- a/packages/gamut/src/Typography/Text.tsx +++ b/packages/gamut/src/Typography/Text.tsx @@ -151,8 +151,9 @@ const StyledText = styled('span', styledOptions<'span'>())( textProps ); -export const Text = forwardRef>( - ({ as = 'span', m = 0, ...rest }, ref) => ( - - ) -); +export const Text = forwardRef< + HTMLSpanElement, + ComponentProps +>(({ as = 'span', m = 0, ...rest }, ref) => ( + +)); diff --git a/packages/gamut/src/Typography/__tests__/Text.test.tsx b/packages/gamut/src/Typography/__tests__/Text.test.tsx deleted file mode 100644 index 37244ecdc45..00000000000 --- a/packages/gamut/src/Typography/__tests__/Text.test.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { setupRtl } from '@codecademy/gamut-tests'; -import { fireEvent } from '@testing-library/dom'; - -import { Text } from '../Text'; - -const renderView = setupRtl(Text, { - children: 'Content', - truncate: 'ellipsis', - truncateLines: 1, -}); - -describe('Text', () => { - it('renders ellipsis truncation without requiring scroll handlers', () => { - // Type-safety: ellipsis-only truncation must not require onScrollEnd/onScrollEndCapture. - // If this fails to compile, the Text props have regressed (e.g. React 19 scroll types). - const { view } = renderView({ - children: 'Long content that gets truncated', - whiteSpace: 'nowrap', - title: 'truncated', - }); - - view.getByText('Long content that gets truncated'); - }); - - it('accepts optional onScrollEnd when provided', () => { - const { view } = renderView({ title: 'with handler' }); - - view.getByText('Content'); - }); - - it('calls onScrollEnd when scrollend event fires', () => { - const onScrollEnd = jest.fn(); - const { view } = renderView({ onScrollEnd }); - - const textElement = view.getByText('Content'); - fireEvent(textElement, new Event('scrollend', { bubbles: true })); - - expect(onScrollEnd).toHaveBeenCalledTimes(1); - }); -}); From c4fc3c345a1dbce3625676503701077ec2c4b4c1 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Fri, 27 Feb 2026 11:19:03 -0500 Subject: [PATCH 18/35] test compatible types --- .github/workflows/test.yml | 3 + package.json | 16 ++--- packages/gamut/src/Box/props.ts | 5 +- packages/gamut/src/ButtonBase/ButtonBase.tsx | 10 +-- packages/gamut/src/Form/elements/Form.tsx | 6 +- .../gamut/src/Form/elements/FormError.tsx | 5 +- .../gamut/src/List/Header/ListHeaderCol.tsx | 5 +- packages/gamut/src/List/List.tsx | 5 +- packages/gamut/src/List/ListCol.tsx | 5 +- packages/gamut/src/List/ListRow.tsx | 6 +- packages/gamut/src/List/TableHeader.tsx | 5 +- packages/gamut/src/Modals/types.ts | 5 +- packages/gamut/src/Typography/Text.tsx | 9 ++- packages/gamut/src/utils/types.ts | 26 +++++++ script/verify-gamut-react18-types.js | 62 +++++++++++++++++ yarn.lock | 69 +++++++++++-------- 16 files changed, 178 insertions(+), 64 deletions(-) create mode 100644 script/verify-gamut-react18-types.js diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7c87300dc75..969d173ece9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -107,6 +107,9 @@ jobs: - name: Build all packages run: yarn build shell: bash + - name: Typecheck Gamut (React 18) + run: yarn nx run gamut:verify + shell: bash - name: Run test suite run: | if [ "${{ github.ref_name }}" == "main" ]; then diff --git a/package.json b/package.json index 4dd14e2c712..9089f69a65c 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "@vidstack/react": "^1.12.12", "core-js": "3.7.0", "lodash": "^4.17.23", - "react": "^19.0.0", - "react-dom": "^19.0.0", + "react": "^18.3.0", + "react-dom": "^18.3.0", "react-helmet-async": "^2.0.5" }, "devDependencies": { @@ -52,8 +52,8 @@ "@types/invariant": "2.2.29", "@types/konami-code-js": "^0.8.0", "@types/lodash": "4.17.23", - "@types/react": "^19.0.0", - "@types/react-dom": "^19.0.0", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0", "@types/stylis": "^4.2.0", "@typescript-eslint/eslint-plugin": "^7.0.0", "@typescript-eslint/parser": "^7.0.0", @@ -110,14 +110,14 @@ "private": true, "repository": "git@github.com:Codecademy/gamut.git", "resolutions": { - "@types/react": "^19.0.0", - "@types/react-dom": "^19.0.0", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0", "@typescript-eslint/eslint-plugin": "^7.0.0", "@typescript-eslint/parser": "^7.0.0", "@typescript-eslint/utils": "^7.0.0", "error-ex": "1.3.4", - "react": "^19.0.0", - "react-dom": "^19.0.0" + "react": "^18.3.0", + "react-dom": "^18.3.0" }, "scripts": { "build": "nx run-many --target=build --all", diff --git a/packages/gamut/src/Box/props.ts b/packages/gamut/src/Box/props.ts index 536ff575392..bd14439218e 100644 --- a/packages/gamut/src/Box/props.ts +++ b/packages/gamut/src/Box/props.ts @@ -1,7 +1,7 @@ import { system } from '@codecademy/gamut-styles'; import { StyleProps, variance } from '@codecademy/variance'; -import { WithChildrenProp } from '../utils'; +import { OptionalScrollProps, WithChildrenProp } from '../utils'; export const boxProps = variance.compose( system.space, @@ -64,7 +64,8 @@ export const gridStates = system.states({ export interface BoxProps extends StyleProps, StyleProps, - WithChildrenProp {} + WithChildrenProp, + OptionalScrollProps {} export interface FlexBoxProps extends BoxProps, StyleProps {} export interface GridBoxProps extends BoxProps, StyleProps {} diff --git a/packages/gamut/src/ButtonBase/ButtonBase.tsx b/packages/gamut/src/ButtonBase/ButtonBase.tsx index 3441636cf52..df9fea3603d 100644 --- a/packages/gamut/src/ButtonBase/ButtonBase.tsx +++ b/packages/gamut/src/ButtonBase/ButtonBase.tsx @@ -1,6 +1,8 @@ import { css, styledOptions } from '@codecademy/gamut-styles'; import styled from '@emotion/styled'; -import { ComponentProps, forwardRef, HTMLProps, MutableRefObject } from 'react'; +import { forwardRef, HTMLProps, MutableRefObject } from 'react'; + +import { CompatibleComponentProps } from '../utils'; export type ButtonBaseElements = HTMLAnchorElement | HTMLButtonElement; export type ButtonBaseRef = @@ -58,9 +60,9 @@ const ResetElement = styled('button', styledOptions<'button'>())(resetStyles); const ResetElementAnchor = styled('a', styledOptions<'a'>())(resetStyles); type ButtonBaseProps = - | ComponentProps - | (Exclude, 'ref'> & - ComponentProps); + | CompatibleComponentProps + | (Exclude, 'ref'> & + CompatibleComponentProps); export const ButtonBase = forwardRef< HTMLButtonElement | HTMLAnchorElement, diff --git a/packages/gamut/src/Form/elements/Form.tsx b/packages/gamut/src/Form/elements/Form.tsx index b697bb03445..efef8c74df7 100644 --- a/packages/gamut/src/Form/elements/Form.tsx +++ b/packages/gamut/src/Form/elements/Form.tsx @@ -1,9 +1,11 @@ import { styledOptions, system } from '@codecademy/gamut-styles'; import { variance } from '@codecademy/variance'; import styled from '@emotion/styled'; -import { ComponentProps, forwardRef } from 'react'; +import { forwardRef } from 'react'; import * as React from 'react'; +import { CompatibleComponentProps } from '../../utils'; + const formSystemProps = variance.compose( system.space, system.border, @@ -15,7 +17,7 @@ const formSystemProps = variance.compose( const StyledForm = styled('form', styledOptions<'form'>())(formSystemProps); -export type FormProps = ComponentProps; +export type FormProps = CompatibleComponentProps; export const Form: React.FC = forwardRef( ({ method = 'post', ...props }, ref) => { diff --git a/packages/gamut/src/Form/elements/FormError.tsx b/packages/gamut/src/Form/elements/FormError.tsx index cafd0b72651..f52e507270a 100644 --- a/packages/gamut/src/Form/elements/FormError.tsx +++ b/packages/gamut/src/Form/elements/FormError.tsx @@ -1,9 +1,10 @@ import { theme, variant } from '@codecademy/gamut-styles'; import { StyleProps } from '@codecademy/variance'; import styled from '@emotion/styled'; -import { HTMLAttributes } from 'react'; import * as React from 'react'; +import { CompatibleComponentProps } from '../../utils'; + const errorSpanVariants = variant({ base: { left: 0, @@ -30,7 +31,7 @@ const errorSpanVariants = variant({ const ErrorSpan = styled.span(errorSpanVariants); type FormErrorProps = StyleProps & - HTMLAttributes; + CompatibleComponentProps<'span'>; export const FormError: React.FC = (props) => { return ; diff --git a/packages/gamut/src/List/Header/ListHeaderCol.tsx b/packages/gamut/src/List/Header/ListHeaderCol.tsx index 1b06be35502..3e981fc6de1 100644 --- a/packages/gamut/src/List/Header/ListHeaderCol.tsx +++ b/packages/gamut/src/List/Header/ListHeaderCol.tsx @@ -1,11 +1,12 @@ -import { ComponentProps, forwardRef } from 'react'; +import { forwardRef } from 'react'; +import { CompatibleComponentProps } from '../../utils'; import { ColEl } from '../elements'; import { useListContext } from '../ListProvider'; import { PublicListProps } from '../types'; export interface ListColProps - extends PublicListProps> {} + extends PublicListProps> {} export const ListCol = forwardRef( ({ type, ...rest }, ref) => { diff --git a/packages/gamut/src/List/List.tsx b/packages/gamut/src/List/List.tsx index f4afee3ebd6..6a15992722d 100644 --- a/packages/gamut/src/List/List.tsx +++ b/packages/gamut/src/List/List.tsx @@ -1,10 +1,11 @@ import { DotLoose } from '@codecademy/gamut-patterns'; import { timingValues } from '@codecademy/gamut-styles'; import isArray from 'lodash/isArray'; -import { ComponentProps, forwardRef, useEffect } from 'react'; +import { forwardRef, useEffect } from 'react'; import * as React from 'react'; import { Box, BoxProps, FlexBox } from '../Box'; +import { CompatibleComponentProps } from '../utils'; import { AnimatedListWrapper, hiddenVariant, @@ -16,7 +17,7 @@ import { useScrollabilityCheck } from './hooks'; import { ListProvider, useList } from './ListProvider'; import { AllListProps } from './types'; -export interface ListProps extends AllListProps> { +export interface ListProps extends AllListProps> { /** Whether List should be an ol, ul element, or table */ as?: 'ol' | 'ul' | 'table'; /** Whether a placeholder width should be set when loading */ diff --git a/packages/gamut/src/List/ListCol.tsx b/packages/gamut/src/List/ListCol.tsx index 0aa54bcedc0..3824beacecf 100644 --- a/packages/gamut/src/List/ListCol.tsx +++ b/packages/gamut/src/List/ListCol.tsx @@ -1,11 +1,12 @@ -import { ComponentProps, forwardRef } from 'react'; +import { forwardRef } from 'react'; +import { CompatibleComponentProps } from '../utils'; import { ColEl, StickyHeaderColWrapper } from './elements'; import { useListContext } from './ListProvider'; import { PublicListProps } from './types'; export interface ListColProps - extends PublicListProps> {} + extends PublicListProps> {} export const ListCol = forwardRef( ({ type, columnHeader, 'aria-sort': ariaSort, ...rest }, ref) => { diff --git a/packages/gamut/src/List/ListRow.tsx b/packages/gamut/src/List/ListRow.tsx index a682da3a112..565ea1cd0ce 100644 --- a/packages/gamut/src/List/ListRow.tsx +++ b/packages/gamut/src/List/ListRow.tsx @@ -1,17 +1,17 @@ import { css } from '@codecademy/gamut-styles'; import styled from '@emotion/styled'; import { AnimatePresence, motion } from 'framer-motion'; -import { ComponentProps, forwardRef, MouseEvent } from 'react'; +import { forwardRef, MouseEvent } from 'react'; import * as React from 'react'; import { Box } from '../Box'; -import { WithChildrenProp } from '../utils'; +import { CompatibleComponentProps, WithChildrenProp } from '../utils'; import { RowEl } from './elements'; import { useListContext } from './ListProvider'; import { PublicListProps } from './types'; export interface RowProps - extends Partial>> { + extends Partial>> { header?: boolean; } diff --git a/packages/gamut/src/List/TableHeader.tsx b/packages/gamut/src/List/TableHeader.tsx index 60810da9c91..ea52ca0c392 100644 --- a/packages/gamut/src/List/TableHeader.tsx +++ b/packages/gamut/src/List/TableHeader.tsx @@ -1,12 +1,13 @@ -import { ComponentProps, forwardRef } from 'react'; +import { forwardRef } from 'react'; import { Box } from '../Box'; +import { CompatibleComponentProps } from '../utils'; import { HeaderRowEl } from './elements'; import { useListContext } from './ListProvider'; import { PublicListProps } from './types'; export interface TableHeaderProps - extends Partial>> {} + extends Partial>> {} export const TableHeader = forwardRef( ({ children, ...rest }, ref) => { diff --git a/packages/gamut/src/Modals/types.ts b/packages/gamut/src/Modals/types.ts index a7c5ed4b2f0..07763d83914 100644 --- a/packages/gamut/src/Modals/types.ts +++ b/packages/gamut/src/Modals/types.ts @@ -1,8 +1,9 @@ -import { ComponentProps, Ref } from 'react'; +import { Ref } from 'react'; import * as React from 'react'; import { OverlayProps } from '../Overlay'; import { TipCenterAlignment } from '../Tip/shared/types'; +import { CompatibleComponentProps } from '../utils'; import { ModalContainer } from './elements'; export interface ModalOverlayProps @@ -18,7 +19,7 @@ export interface ModalOverlayProps export interface ModalBaseProps extends ModalOverlayProps, - Omit, 'title'> { + Omit, 'title'> { title?: React.ReactNode; /** * Heading titles for the Modal. They should almost always be the default `h2`, but should sometimes be `h1` if the Modal takes up the entire page diff --git a/packages/gamut/src/Typography/Text.tsx b/packages/gamut/src/Typography/Text.tsx index d04be4e4c07..07c68904a1b 100644 --- a/packages/gamut/src/Typography/Text.tsx +++ b/packages/gamut/src/Typography/Text.tsx @@ -8,6 +8,7 @@ import { StyleProps, variance } from '@codecademy/variance'; import styled from '@emotion/styled'; import { ComponentProps, forwardRef } from 'react'; +import { OptionalScrollProps } from '../utils'; import { typographyElementVariants, typographyStyleVariants } from './variants'; const displayVariants = variant({ @@ -120,16 +121,14 @@ const textProps = variance.compose( truncateLinesProps ); +// CASSIE, come back to this export interface BaseTextProps extends StyleProps, StyleProps, StyleProps, StyleProps, - StyleProps { - /** Optional so ellipsis-only truncation doesn't require scroll handlers (React 19+) */ - onScrollEnd?: (event: React.UIEvent) => void; - onScrollEndCapture?: (event: React.UIEvent) => void; -} + StyleProps, + OptionalScrollProps {} // if you're going to truncate, you need to provide both of these props or neither export interface TextTruncateProps extends BaseTextProps { diff --git a/packages/gamut/src/utils/types.ts b/packages/gamut/src/utils/types.ts index 84e1c8c9046..27f7e34fb43 100644 --- a/packages/gamut/src/utils/types.ts +++ b/packages/gamut/src/utils/types.ts @@ -1,7 +1,33 @@ import { GamutIconProps } from '@codecademy/gamut-icons'; +import type { ComponentProps, ElementType } from 'react'; export interface WithChildrenProp { children?: React.ReactNode | React.ReactNode[]; } export type IconComponentType = { icon: React.ComponentType }; + +/** + * Optional scroll event handlers (React 19+). + * Explicitly optional so consumers on React 18 don't get type errors + * when Gamut is built with React 19 types. + */ +export interface OptionalScrollProps { + onScrollEnd?: (event: React.UIEvent) => void; + onScrollEndCapture?: (event: React.UIEvent) => void; +} + +/** Makes onScrollEnd/onScrollEndCapture optional when merging with React 19 DOM types. */ +export type WithOptionalScrollProps = Omit< + T, + 'onScrollEnd' | 'onScrollEndCapture' +> & + OptionalScrollProps; + +/** + * Component props compatible with React 18 consumers when Gamut is built with React 19 types. + * Use instead of ComponentProps for DOM-based components so onScrollEnd/onScrollEndCapture + * stay optional. Downstream types that extend or reference these props get the same compatibility. + */ +export type CompatibleComponentProps = + WithOptionalScrollProps>; diff --git a/script/verify-gamut-react18-types.js b/script/verify-gamut-react18-types.js new file mode 100644 index 00000000000..591e1f49783 --- /dev/null +++ b/script/verify-gamut-react18-types.js @@ -0,0 +1,62 @@ +#!/usr/bin/env node +/** + * Run type-check (verify) with React 18 types to find components that still + * require onScrollEnd/onScrollEndCapture for React 18 consumers. + * + * Usage: node script/verify-gamut-react18-types.js + * + * Switches to React 18, runs `yarn nx run gamut:verify` (or root verify), + * then restores package.json. If type errors mention onScrollEnd or + * onScrollEndCapture, those components need OptionalScrollProps (or to + * extend a type that already has it). + */ + +const fs = require('fs'); +const path = require('path'); +const { spawnSync } = require('child_process'); + +const repoRoot = path.join(__dirname, '..'); +const pkgPath = path.join(repoRoot, 'package.json'); +const pkgBackup = fs.readFileSync(pkgPath, 'utf8'); + +function run(cmd, args, opts = {}) { + return spawnSync(cmd, args, { + cwd: repoRoot, + shell: true, + encoding: 'utf8', + ...opts, + }); +} + +let exitCode = 0; +try { + run('node', ['script/set-react-resolutions.js', '18']); + run('yarn', ['install'], { + stdio: 'pipe', + env: { ...process.env, CI: undefined }, + }); + + const result = run('yarn', ['nx', 'run', 'gamut:verify'], { + encoding: 'utf8', + stdio: 'pipe', + }); + + if (result.status !== 0 && result.stderr) { + const out = (result.stderr + result.stdout).toLowerCase(); + if (out.includes('onscrollend')) { + console.error( + '\nReact 18 type check failed with onScrollEnd/onScrollEndCapture errors.\n' + + 'Search the output above for "onScrollEnd" to see which component props need OptionalScrollProps.\n' + ); + } + } + exitCode = result.status; +} finally { + fs.writeFileSync(pkgPath, pkgBackup); + run('yarn', ['install'], { + stdio: 'pipe', + env: { ...process.env, CI: undefined }, + }); +} + +process.exit(exitCode); diff --git a/yarn.lock b/yarn.lock index 9e8a4444b27..0af4bdc50c1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8181,6 +8181,13 @@ __metadata: languageName: node linkType: hard +"@types/prop-types@npm:*": + version: 15.7.15 + resolution: "@types/prop-types@npm:15.7.15" + checksum: 10c0/b59aad1ad19bf1733cf524fd4e618196c6c7690f48ee70a327eb450a42aab8e8a063fbe59ca0a5701aebe2d92d582292c0fb845ea57474f6a15f6994b0e260b2 + languageName: node + linkType: hard + "@types/q@npm:^1.5.1": version: 1.5.8 resolution: "@types/q@npm:1.5.8" @@ -8202,12 +8209,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^19.0.0": - version: 19.2.3 - resolution: "@types/react-dom@npm:19.2.3" +"@types/react-dom@npm:^18.2.0": + version: 18.3.7 + resolution: "@types/react-dom@npm:18.3.7" peerDependencies: - "@types/react": ^19.2.0 - checksum: 10c0/b486ebe0f4e2fb35e2e108df1d8fc0927ca5d6002d5771e8a739de11239fe62d0e207c50886185253c99eb9dedfeeb956ea7429e5ba17f6693c7acb4c02f8cd1 + "@types/react": ^18.0.0 + checksum: 10c0/8bd309e2c3d1604a28a736a24f96cbadf6c05d5288cfef8883b74f4054c961b6b3a5e997fd5686e492be903c8f3380dba5ec017eff3906b1256529cd2d39603e languageName: node linkType: hard @@ -8220,12 +8227,13 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^19.0.0": - version: 19.2.14 - resolution: "@types/react@npm:19.2.14" +"@types/react@npm:^18.2.0": + version: 18.3.28 + resolution: "@types/react@npm:18.3.28" dependencies: + "@types/prop-types": "npm:*" csstype: "npm:^3.2.2" - checksum: 10c0/7d25bf41b57719452d86d2ac0570b659210402707313a36ee612666bf11275a1c69824f8c3ee1fdca077ccfe15452f6da8f1224529b917050eb2d861e52b59b7 + checksum: 10c0/683e19cd12b5c691215529af2e32b5ffbaccae3bf0ba93bfafa0e460e8dfee18423afed568be2b8eadf4b837c3749dd296a4f64e2d79f68fa66962c05f5af661 languageName: node linkType: hard @@ -14194,8 +14202,8 @@ __metadata: "@types/invariant": "npm:2.2.29" "@types/konami-code-js": "npm:^0.8.0" "@types/lodash": "npm:4.17.23" - "@types/react": "npm:^19.0.0" - "@types/react-dom": "npm:^19.0.0" + "@types/react": "npm:^18.2.0" + "@types/react-dom": "npm:^18.2.0" "@types/stylis": "npm:^4.2.0" "@typescript-eslint/eslint-plugin": "npm:^7.0.0" "@typescript-eslint/parser": "npm:^7.0.0" @@ -14227,8 +14235,8 @@ __metadata: nx-cloud: "npm:^19.1.0" onchange: "npm:^7.0.2" prettier: "npm:^2.8.7" - react: "npm:^19.0.0" - react-dom: "npm:^19.0.0" + react: "npm:^18.3.0" + react-dom: "npm:^18.3.0" react-helmet-async: "npm:^2.0.5" storybook: "npm:^8.6.15" storybook-addon-deep-controls: "npm:^0.9.5" @@ -17920,7 +17928,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.0.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -21495,14 +21503,15 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:^19.0.0": - version: 19.2.4 - resolution: "react-dom@npm:19.2.4" +"react-dom@npm:^18.3.0": + version: 18.3.1 + resolution: "react-dom@npm:18.3.1" dependencies: - scheduler: "npm:^0.27.0" + loose-envify: "npm:^1.1.0" + scheduler: "npm:^0.23.2" peerDependencies: - react: ^19.2.4 - checksum: 10c0/f0c63f1794dedb154136d4d0f59af00b41907f4859571c155940296808f4b94bf9c0c20633db75b5b2112ec13d8d7dd4f9bf57362ed48782f317b11d05a44f35 + react: ^18.3.1 + checksum: 10c0/a752496c1941f958f2e8ac56239172296fcddce1365ce45222d04a1947e0cc5547df3e8447f855a81d6d39f008d7c32eab43db3712077f09e3f67c4874973e85 languageName: node linkType: hard @@ -21782,10 +21791,12 @@ __metadata: languageName: node linkType: hard -"react@npm:^19.0.0": - version: 19.2.4 - resolution: "react@npm:19.2.4" - checksum: 10c0/cd2c9ff67a720799cc3b38a516009986f7fc4cb8d3e15716c6211cf098d1357ee3e348ab05ad0600042bbb0fd888530ba92e329198c92eafa0994f5213396596 +"react@npm:^18.3.0": + version: 18.3.1 + resolution: "react@npm:18.3.1" + dependencies: + loose-envify: "npm:^1.1.0" + checksum: 10c0/283e8c5efcf37802c9d1ce767f302dd569dd97a70d9bb8c7be79a789b9902451e0d16334b05d73299b20f048cbc3c7d288bbbde10b701fa194e2089c237dbea3 languageName: node linkType: hard @@ -22915,10 +22926,12 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:^0.27.0": - version: 0.27.0 - resolution: "scheduler@npm:0.27.0" - checksum: 10c0/4f03048cb05a3c8fddc45813052251eca00688f413a3cee236d984a161da28db28ba71bd11e7a3dd02f7af84ab28d39fb311431d3b3772fed557945beb00c452 +"scheduler@npm:^0.23.2": + version: 0.23.2 + resolution: "scheduler@npm:0.23.2" + dependencies: + loose-envify: "npm:^1.1.0" + checksum: 10c0/26383305e249651d4c58e6705d5f8425f153211aef95f15161c151f7b8de885f24751b377e4a0b3dd42cce09aad3f87a61dab7636859c0d89b7daf1a1e2a5c78 languageName: node linkType: hard From cd244b555acf7fdedcb88da8ef786fc75489172e Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Fri, 27 Feb 2026 11:50:45 -0500 Subject: [PATCH 19/35] better --- script/patch-react-18-ref-types.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/script/patch-react-18-ref-types.js b/script/patch-react-18-ref-types.js index a4e235c5c39..e27b0acfe50 100644 --- a/script/patch-react-18-ref-types.js +++ b/script/patch-react-18-ref-types.js @@ -29,8 +29,13 @@ if (major !== 18) { process.exit(0); } -const oldRef = 'type Ref = RefCallback | RefObject | null;'; -const newRef = +// Match the Ref type line with optional leading whitespace (indentation) +const refTypeRegex = /^(\s*)type Ref = RefCallback \| RefObject \| null;$/m; +const refTypeReplacement = + '$1type Ref = RefCallback | RefObject | RefObject | null;'; + +const oldRefExact = 'type Ref = RefCallback | RefObject | null;'; +const newRefExact = 'type Ref = RefCallback | RefObject | RefObject | null;'; const files = ['index.d.ts', 'ts5.0/index.d.ts']; @@ -40,9 +45,12 @@ for (const file of files) { const filePath = path.join(typesReactPath, file); if (!fs.existsSync(filePath)) continue; let content = fs.readFileSync(filePath, 'utf8'); - if (content.includes(oldRef)) { - content = content.replace(oldRef, newRef); - fs.writeFileSync(filePath, content); + let newContent = content.replace(refTypeRegex, refTypeReplacement); + if (newContent === content && content.includes(oldRefExact)) { + newContent = content.replace(oldRefExact, newRefExact); + } + if (newContent !== content) { + fs.writeFileSync(filePath, newContent); patched++; } } From 5a6d51cff046b299fb6d3d3c952b73c827b850eb Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Fri, 27 Feb 2026 12:04:42 -0500 Subject: [PATCH 20/35] patch update --- packages/gamut/src/List/List.tsx | 3 ++- packages/gamut/src/List/TableHeader.tsx | 4 +++- script/patch-react-18-ref-types.js | 5 +++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/gamut/src/List/List.tsx b/packages/gamut/src/List/List.tsx index 6a15992722d..c448fc48818 100644 --- a/packages/gamut/src/List/List.tsx +++ b/packages/gamut/src/List/List.tsx @@ -17,7 +17,8 @@ import { useScrollabilityCheck } from './hooks'; import { ListProvider, useList } from './ListProvider'; import { AllListProps } from './types'; -export interface ListProps extends AllListProps> { +export interface ListProps + extends AllListProps> { /** Whether List should be an ol, ul element, or table */ as?: 'ol' | 'ul' | 'table'; /** Whether a placeholder width should be set when loading */ diff --git a/packages/gamut/src/List/TableHeader.tsx b/packages/gamut/src/List/TableHeader.tsx index ea52ca0c392..2c94afb9d3a 100644 --- a/packages/gamut/src/List/TableHeader.tsx +++ b/packages/gamut/src/List/TableHeader.tsx @@ -7,7 +7,9 @@ import { useListContext } from './ListProvider'; import { PublicListProps } from './types'; export interface TableHeaderProps - extends Partial>> {} + extends Partial< + PublicListProps> + > {} export const TableHeader = forwardRef( ({ children, ...rest }, ref) => { diff --git a/script/patch-react-18-ref-types.js b/script/patch-react-18-ref-types.js index e27b0acfe50..42830000200 100644 --- a/script/patch-react-18-ref-types.js +++ b/script/patch-react-18-ref-types.js @@ -30,7 +30,8 @@ if (major !== 18) { } // Match the Ref type line with optional leading whitespace (indentation) -const refTypeRegex = /^(\s*)type Ref = RefCallback \| RefObject \| null;$/m; +const refTypeRegex = + /^(\s*)type Ref = RefCallback \| RefObject \| null;$/m; const refTypeReplacement = '$1type Ref = RefCallback | RefObject | RefObject | null;'; @@ -44,7 +45,7 @@ let patched = 0; for (const file of files) { const filePath = path.join(typesReactPath, file); if (!fs.existsSync(filePath)) continue; - let content = fs.readFileSync(filePath, 'utf8'); + const content = fs.readFileSync(filePath, 'utf8'); let newContent = content.replace(refTypeRegex, refTypeReplacement); if (newContent === content && content.includes(oldRefExact)) { newContent = content.replace(oldRefExact, newRefExact); From 8e424310303975412fec2cc85b147fa1e65c0f8c Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Fri, 27 Feb 2026 12:21:56 -0500 Subject: [PATCH 21/35] back to 19 --- .github/actions/yarn/action.yml | 3 ++ package.json | 16 ++++---- yarn.lock | 69 +++++++++++++-------------------- 3 files changed, 39 insertions(+), 49 deletions(-) diff --git a/.github/actions/yarn/action.yml b/.github/actions/yarn/action.yml index 2aa211a518b..7c9ed60f675 100644 --- a/.github/actions/yarn/action.yml +++ b/.github/actions/yarn/action.yml @@ -14,3 +14,6 @@ runs: - name: Install dependencies shell: bash run: yarn install --immutable + - name: Patch React 18 ref types + run: node script/patch-react-18-ref-types.js + shell: bash diff --git a/package.json b/package.json index 9089f69a65c..4dd14e2c712 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "@vidstack/react": "^1.12.12", "core-js": "3.7.0", "lodash": "^4.17.23", - "react": "^18.3.0", - "react-dom": "^18.3.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", "react-helmet-async": "^2.0.5" }, "devDependencies": { @@ -52,8 +52,8 @@ "@types/invariant": "2.2.29", "@types/konami-code-js": "^0.8.0", "@types/lodash": "4.17.23", - "@types/react": "^18.2.0", - "@types/react-dom": "^18.2.0", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", "@types/stylis": "^4.2.0", "@typescript-eslint/eslint-plugin": "^7.0.0", "@typescript-eslint/parser": "^7.0.0", @@ -110,14 +110,14 @@ "private": true, "repository": "git@github.com:Codecademy/gamut.git", "resolutions": { - "@types/react": "^18.2.0", - "@types/react-dom": "^18.2.0", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", "@typescript-eslint/eslint-plugin": "^7.0.0", "@typescript-eslint/parser": "^7.0.0", "@typescript-eslint/utils": "^7.0.0", "error-ex": "1.3.4", - "react": "^18.3.0", - "react-dom": "^18.3.0" + "react": "^19.0.0", + "react-dom": "^19.0.0" }, "scripts": { "build": "nx run-many --target=build --all", diff --git a/yarn.lock b/yarn.lock index 0af4bdc50c1..9e8a4444b27 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8181,13 +8181,6 @@ __metadata: languageName: node linkType: hard -"@types/prop-types@npm:*": - version: 15.7.15 - resolution: "@types/prop-types@npm:15.7.15" - checksum: 10c0/b59aad1ad19bf1733cf524fd4e618196c6c7690f48ee70a327eb450a42aab8e8a063fbe59ca0a5701aebe2d92d582292c0fb845ea57474f6a15f6994b0e260b2 - languageName: node - linkType: hard - "@types/q@npm:^1.5.1": version: 1.5.8 resolution: "@types/q@npm:1.5.8" @@ -8209,12 +8202,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^18.2.0": - version: 18.3.7 - resolution: "@types/react-dom@npm:18.3.7" +"@types/react-dom@npm:^19.0.0": + version: 19.2.3 + resolution: "@types/react-dom@npm:19.2.3" peerDependencies: - "@types/react": ^18.0.0 - checksum: 10c0/8bd309e2c3d1604a28a736a24f96cbadf6c05d5288cfef8883b74f4054c961b6b3a5e997fd5686e492be903c8f3380dba5ec017eff3906b1256529cd2d39603e + "@types/react": ^19.2.0 + checksum: 10c0/b486ebe0f4e2fb35e2e108df1d8fc0927ca5d6002d5771e8a739de11239fe62d0e207c50886185253c99eb9dedfeeb956ea7429e5ba17f6693c7acb4c02f8cd1 languageName: node linkType: hard @@ -8227,13 +8220,12 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.0": - version: 18.3.28 - resolution: "@types/react@npm:18.3.28" +"@types/react@npm:^19.0.0": + version: 19.2.14 + resolution: "@types/react@npm:19.2.14" dependencies: - "@types/prop-types": "npm:*" csstype: "npm:^3.2.2" - checksum: 10c0/683e19cd12b5c691215529af2e32b5ffbaccae3bf0ba93bfafa0e460e8dfee18423afed568be2b8eadf4b837c3749dd296a4f64e2d79f68fa66962c05f5af661 + checksum: 10c0/7d25bf41b57719452d86d2ac0570b659210402707313a36ee612666bf11275a1c69824f8c3ee1fdca077ccfe15452f6da8f1224529b917050eb2d861e52b59b7 languageName: node linkType: hard @@ -14202,8 +14194,8 @@ __metadata: "@types/invariant": "npm:2.2.29" "@types/konami-code-js": "npm:^0.8.0" "@types/lodash": "npm:4.17.23" - "@types/react": "npm:^18.2.0" - "@types/react-dom": "npm:^18.2.0" + "@types/react": "npm:^19.0.0" + "@types/react-dom": "npm:^19.0.0" "@types/stylis": "npm:^4.2.0" "@typescript-eslint/eslint-plugin": "npm:^7.0.0" "@typescript-eslint/parser": "npm:^7.0.0" @@ -14235,8 +14227,8 @@ __metadata: nx-cloud: "npm:^19.1.0" onchange: "npm:^7.0.2" prettier: "npm:^2.8.7" - react: "npm:^18.3.0" - react-dom: "npm:^18.3.0" + react: "npm:^19.0.0" + react-dom: "npm:^19.0.0" react-helmet-async: "npm:^2.0.5" storybook: "npm:^8.6.15" storybook-addon-deep-controls: "npm:^0.9.5" @@ -17928,7 +17920,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.0.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -21503,15 +21495,14 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:^18.3.0": - version: 18.3.1 - resolution: "react-dom@npm:18.3.1" +"react-dom@npm:^19.0.0": + version: 19.2.4 + resolution: "react-dom@npm:19.2.4" dependencies: - loose-envify: "npm:^1.1.0" - scheduler: "npm:^0.23.2" + scheduler: "npm:^0.27.0" peerDependencies: - react: ^18.3.1 - checksum: 10c0/a752496c1941f958f2e8ac56239172296fcddce1365ce45222d04a1947e0cc5547df3e8447f855a81d6d39f008d7c32eab43db3712077f09e3f67c4874973e85 + react: ^19.2.4 + checksum: 10c0/f0c63f1794dedb154136d4d0f59af00b41907f4859571c155940296808f4b94bf9c0c20633db75b5b2112ec13d8d7dd4f9bf57362ed48782f317b11d05a44f35 languageName: node linkType: hard @@ -21791,12 +21782,10 @@ __metadata: languageName: node linkType: hard -"react@npm:^18.3.0": - version: 18.3.1 - resolution: "react@npm:18.3.1" - dependencies: - loose-envify: "npm:^1.1.0" - checksum: 10c0/283e8c5efcf37802c9d1ce767f302dd569dd97a70d9bb8c7be79a789b9902451e0d16334b05d73299b20f048cbc3c7d288bbbde10b701fa194e2089c237dbea3 +"react@npm:^19.0.0": + version: 19.2.4 + resolution: "react@npm:19.2.4" + checksum: 10c0/cd2c9ff67a720799cc3b38a516009986f7fc4cb8d3e15716c6211cf098d1357ee3e348ab05ad0600042bbb0fd888530ba92e329198c92eafa0994f5213396596 languageName: node linkType: hard @@ -22926,12 +22915,10 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:^0.23.2": - version: 0.23.2 - resolution: "scheduler@npm:0.23.2" - dependencies: - loose-envify: "npm:^1.1.0" - checksum: 10c0/26383305e249651d4c58e6705d5f8425f153211aef95f15161c151f7b8de885f24751b377e4a0b3dd42cce09aad3f87a61dab7636859c0d89b7daf1a1e2a5c78 +"scheduler@npm:^0.27.0": + version: 0.27.0 + resolution: "scheduler@npm:0.27.0" + checksum: 10c0/4f03048cb05a3c8fddc45813052251eca00688f413a3cee236d984a161da28db28ba71bd11e7a3dd02f7af84ab28d39fb311431d3b3772fed557945beb00c452 languageName: node linkType: hard From d86ceaa8048619587f01a183f042cb222b19b51b Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Fri, 27 Feb 2026 12:22:57 -0500 Subject: [PATCH 22/35] action --- .github/actions/yarn/action.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/actions/yarn/action.yml b/.github/actions/yarn/action.yml index 7c9ed60f675..2aa211a518b 100644 --- a/.github/actions/yarn/action.yml +++ b/.github/actions/yarn/action.yml @@ -14,6 +14,3 @@ runs: - name: Install dependencies shell: bash run: yarn install --immutable - - name: Patch React 18 ref types - run: node script/patch-react-18-ref-types.js - shell: bash From a11d655c2b48140e13f73ad794c7b2a877085ef7 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Fri, 27 Feb 2026 13:42:46 -0500 Subject: [PATCH 23/35] test as compat --- packages/gamut/src/Anchor/index.tsx | 25 ++++++++++++---- packages/gamut/src/Box/Box.tsx | 12 +++++++- packages/gamut/src/Box/FlexBox.tsx | 12 +++++++- packages/gamut/src/Box/GridBox.tsx | 12 +++++++- packages/gamut/src/Typography/Text.tsx | 11 +++++-- packages/gamut/src/utils/types.ts | 40 ++++++++++++++++++++++++++ 6 files changed, 101 insertions(+), 11 deletions(-) diff --git a/packages/gamut/src/Anchor/index.tsx b/packages/gamut/src/Anchor/index.tsx index 287ff0e6d37..910defc725d 100644 --- a/packages/gamut/src/Anchor/index.tsx +++ b/packages/gamut/src/Anchor/index.tsx @@ -1,10 +1,20 @@ import { styledOptions, system, variant } from '@codecademy/gamut-styles'; import { StyleProps, variance } from '@codecademy/variance'; import styled from '@emotion/styled'; -import { ComponentProps, forwardRef, HTMLProps, RefObject } from 'react'; +import { + forwardRef, + ForwardRefExoticComponent, + HTMLProps, + RefObject, +} from 'react'; import { ButtonBase, ButtonSelectors } from '../ButtonBase/ButtonBase'; import { AppendedIconProps, appendIconToContent } from '../helpers'; +import { + CompatibleComponentProps, + CompatibleRefAttributes, + WithOptionalScrollProps, +} from '../utils'; export interface AnchorProps extends StyleProps, @@ -113,13 +123,13 @@ export const AnchorBase = styled('a', styledOptions<'a'>())( ); type AnchorBaseProps = - | ComponentProps - | (Exclude, 'ref'> & - ComponentProps); + | CompatibleComponentProps + | (Exclude, 'ref'> & + CompatibleComponentProps); type AnchorExtProps = Partial & AnchorBaseProps; -export const Anchor = forwardRef< +const AnchorComponent = forwardRef< HTMLAnchorElement | HTMLButtonElement, AnchorExtProps >( @@ -170,3 +180,8 @@ export const Anchor = forwardRef< ); } ); + +export const Anchor: ForwardRefExoticComponent< + WithOptionalScrollProps & + CompatibleRefAttributes +> = AnchorComponent; diff --git a/packages/gamut/src/Box/Box.tsx b/packages/gamut/src/Box/Box.tsx index da6263f7e9b..8f2eb47782b 100644 --- a/packages/gamut/src/Box/Box.tsx +++ b/packages/gamut/src/Box/Box.tsx @@ -1,11 +1,21 @@ import { styledOptions } from '@codecademy/gamut-styles'; import styled from '@emotion/styled'; +import { + asCompatibleForwardRefComponent, + CompatibleStyledComponentProps, +} from '../utils'; import { BoxProps, boxProps, sharedStates } from './props'; -export const Box = styled('div', styledOptions(['fit']))( +const StyledBox = styled('div', styledOptions(['fit']))( sharedStates, boxProps ); +export const Box = + asCompatibleForwardRefComponent>(StyledBox); + export type { BoxProps } from './props'; diff --git a/packages/gamut/src/Box/FlexBox.tsx b/packages/gamut/src/Box/FlexBox.tsx index 8bb11d94fe1..d4d3b4b3046 100644 --- a/packages/gamut/src/Box/FlexBox.tsx +++ b/packages/gamut/src/Box/FlexBox.tsx @@ -1,11 +1,21 @@ import { css, styledOptions } from '@codecademy/gamut-styles'; import styled from '@emotion/styled'; +import { + asCompatibleForwardRefComponent, + CompatibleStyledComponentProps, +} from '../utils'; import { boxProps, FlexBoxProps, flexStates, sharedStates } from './props'; -export const FlexBox = styled( +const StyledFlexBox = styled( 'div', styledOptions(['fit', 'wrap', 'center', 'column', 'row', 'inline']) )(css({ display: 'flex' }), sharedStates, flexStates, boxProps); +export const FlexBox = + asCompatibleForwardRefComponent>(StyledFlexBox); + export type { FlexBoxProps } from './props'; diff --git a/packages/gamut/src/Box/GridBox.tsx b/packages/gamut/src/Box/GridBox.tsx index b005a768020..b3e4249f618 100644 --- a/packages/gamut/src/Box/GridBox.tsx +++ b/packages/gamut/src/Box/GridBox.tsx @@ -1,9 +1,13 @@ import { styledOptions, system } from '@codecademy/gamut-styles'; import styled from '@emotion/styled'; +import { + asCompatibleForwardRefComponent, + CompatibleStyledComponentProps, +} from '../utils'; import { boxProps, GridBoxProps, gridStates, sharedStates } from './props'; -export const GridBox = styled( +const StyledGridBox = styled( 'div', styledOptions(['fit', 'center', 'fitContent']) )( @@ -12,3 +16,9 @@ export const GridBox = styled( gridStates, boxProps ); + +export const GridBox = + asCompatibleForwardRefComponent>(StyledGridBox); diff --git a/packages/gamut/src/Typography/Text.tsx b/packages/gamut/src/Typography/Text.tsx index 07c68904a1b..fe4dd5fba41 100644 --- a/packages/gamut/src/Typography/Text.tsx +++ b/packages/gamut/src/Typography/Text.tsx @@ -8,7 +8,7 @@ import { StyleProps, variance } from '@codecademy/variance'; import styled from '@emotion/styled'; import { ComponentProps, forwardRef } from 'react'; -import { OptionalScrollProps } from '../utils'; +import { OptionalScrollProps, WithOptionalScrollProps } from '../utils'; import { typographyElementVariants, typographyStyleVariants } from './variants'; const displayVariants = variant({ @@ -152,7 +152,12 @@ const StyledText = styled('span', styledOptions<'span'>())( export const Text = forwardRef< HTMLSpanElement, - ComponentProps + WithOptionalScrollProps> >(({ as = 'span', m = 0, ...rest }, ref) => ( - + )} + /> )); diff --git a/packages/gamut/src/utils/types.ts b/packages/gamut/src/utils/types.ts index 27f7e34fb43..d9e173743d3 100644 --- a/packages/gamut/src/utils/types.ts +++ b/packages/gamut/src/utils/types.ts @@ -31,3 +31,43 @@ export type WithOptionalScrollProps = Omit< */ export type CompatibleComponentProps = WithOptionalScrollProps>; + +/** + * Ref type compatible with React 18 and 19. + * In React 18 @types/react, Ref does not include RefObject, so useRef(null) + * can cause TS2322. Using this type in component ref props avoids that without patching @types/react. + */ +export type CompatibleRef = + | React.RefCallback + | React.RefObject + | React.RefObject + | null; + +/** + * RefAttributes with ref typed as CompatibleRef so React 18 consumers can pass + * useRef(null) without type errors. Use with ForwardRefExoticComponent. + */ +export type CompatibleRefAttributes = Omit, 'ref'> & { + ref?: CompatibleRef; +}; + +/** + * Props type for a styled layout/DOM component with React 18–compatible scroll and ref. + * Use with asCompatibleForwardRefComponent so call sites don’t need casts. + */ +export type CompatibleStyledComponentProps< + C extends React.ComponentType, + R extends HTMLElement +> = WithOptionalScrollProps> & + CompatibleRefAttributes; + +/** + * Treats a styled component (Emotion StyledComponent) as a ForwardRefExoticComponent + * with compatible props. Emotion’s type doesn’t extend React’s ForwardRefExoticComponent, + * so this centralizes the type assertion instead of repeating it in each file. + */ +export function asCompatibleForwardRefComponent

>( + component: React.ComponentType

+): React.ForwardRefExoticComponent

{ + return component as unknown as React.ForwardRefExoticComponent

; +} From 5d01d4fd128acbe2bfa15454336a910b73682b6d Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Mon, 2 Mar 2026 13:27:43 -0500 Subject: [PATCH 24/35] motion upgrade + patch --- package.json | 18 +- packages/gamut-styles/package.json | 2 +- packages/gamut-styles/src/GamutProvider.tsx | 2 +- .../__snapshots__/gamut.test.ts.snap | 5 + packages/gamut/package.json | 2 +- .../src/AccordionAreaDeprecated/index.tsx | 2 +- packages/gamut/src/Alert/Alert.tsx | 2 +- packages/gamut/src/Alert/elements.tsx | 2 +- packages/gamut/src/Anchor/index.tsx | 19 +- .../src/Animation/ExpandInCollapseOut.tsx | 2 +- .../gamut/src/Animation/FadeInSlideOut.tsx | 2 +- packages/gamut/src/Animation/Rotation.tsx | 2 +- packages/gamut/src/Box/Box.tsx | 2 +- packages/gamut/src/Box/FlexBox.tsx | 2 +- packages/gamut/src/Box/GridBox.tsx | 2 +- packages/gamut/src/Card/elements.tsx | 14 +- packages/gamut/src/Card/index.tsx | 11 +- packages/gamut/src/Card/styles.tsx | 16 +- packages/gamut/src/Disclosure/index.tsx | 2 +- packages/gamut/src/Drawer/index.tsx | 2 +- .../__tests__/FeatureShimmer.test.tsx | 4 +- packages/gamut/src/FeatureShimmer/index.tsx | 8 +- packages/gamut/src/List/ListRow.tsx | 2 +- packages/gamut/src/List/elements.tsx | 6 +- packages/gamut/src/Pagination/utils.tsx | 6 +- packages/gamut/src/Popover/elements.tsx | 2 +- packages/gamut/src/Tip/shared/FloatingTip.tsx | 2 +- packages/gamut/src/Toaster/index.tsx | 2 +- packages/gamut/src/utils/index.ts | 8 +- packages/gamut/src/utils/types.ts | 9 +- .../components/Elements/ImageGallery.tsx | 2 +- .../ExpandInCollapseOut.stories.tsx | 2 +- .../FadeInSlideOut/FadeInSlideOut.stories.tsx | 2 +- .../styleguide/src/lib/Meta/ESLint rules.mdx | 2 +- patches/@types+react+18.3.28.patch | 13 + yarn.lock | 285 +++++++++++++++--- 36 files changed, 345 insertions(+), 121 deletions(-) create mode 100644 patches/@types+react+18.3.28.patch diff --git a/package.json b/package.json index 4dd14e2c712..fcfdc45e14b 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "@vidstack/react": "^1.12.12", "core-js": "3.7.0", "lodash": "^4.17.23", - "react": "^19.0.0", - "react-dom": "^19.0.0", + "react": "^18.3.0", + "react-dom": "^18.3.0", "react-helmet-async": "^2.0.5" }, "devDependencies": { @@ -52,8 +52,8 @@ "@types/invariant": "2.2.29", "@types/konami-code-js": "^0.8.0", "@types/lodash": "4.17.23", - "@types/react": "^19.0.0", - "@types/react-dom": "^19.0.0", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0", "@types/stylis": "^4.2.0", "@typescript-eslint/eslint-plugin": "^7.0.0", "@typescript-eslint/parser": "^7.0.0", @@ -81,6 +81,7 @@ "nx": "21.4.0", "nx-cloud": "^19.1.0", "onchange": "^7.0.2", + "patch-package": "^8.0.0", "prettier": "^2.8.7", "storybook": "^8.6.15", "storybook-addon-deep-controls": "^0.9.5", @@ -110,16 +111,17 @@ "private": true, "repository": "git@github.com:Codecademy/gamut.git", "resolutions": { - "@types/react": "^19.0.0", - "@types/react-dom": "^19.0.0", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0", "@typescript-eslint/eslint-plugin": "^7.0.0", "@typescript-eslint/parser": "^7.0.0", "@typescript-eslint/utils": "^7.0.0", "error-ex": "1.3.4", - "react": "^19.0.0", - "react-dom": "^19.0.0" + "react": "^18.3.0", + "react-dom": "^18.3.0" }, "scripts": { + "postinstall": "patch-package", "build": "nx run-many --target=build --all", "build-all": "yarn build", "build-storybook": "nx run styleguide:build-storybook", diff --git a/packages/gamut-styles/package.json b/packages/gamut-styles/package.json index 7f883071751..7032c9cefc2 100644 --- a/packages/gamut-styles/package.json +++ b/packages/gamut-styles/package.json @@ -6,8 +6,8 @@ "dependencies": { "@codecademy/variance": "0.25.2", "@emotion/is-prop-valid": "^1.1.0", - "framer-motion": "^11.18.0", "get-nonce": "^1.0.0", + "motion": "^12.0.0", "polished": "^4.1.2" }, "files": [ diff --git a/packages/gamut-styles/src/GamutProvider.tsx b/packages/gamut-styles/src/GamutProvider.tsx index a3d771325c4..241cd091aa3 100644 --- a/packages/gamut-styles/src/GamutProvider.tsx +++ b/packages/gamut-styles/src/GamutProvider.tsx @@ -5,8 +5,8 @@ import { Theme, ThemeProvider, } from '@emotion/react'; -import { MotionConfig } from 'framer-motion'; import { setNonce } from 'get-nonce'; +import { MotionConfig } from 'motion/react'; import { useContext, useEffect, useRef } from 'react'; import * as React from 'react'; diff --git a/packages/gamut/__tests__/__snapshots__/gamut.test.ts.snap b/packages/gamut/__tests__/__snapshots__/gamut.test.ts.snap index 8511c5708f6..6eb7cd19f35 100644 --- a/packages/gamut/__tests__/__snapshots__/gamut.test.ts.snap +++ b/packages/gamut/__tests__/__snapshots__/gamut.test.ts.snap @@ -17,6 +17,7 @@ exports[`Gamut Exported Keys 1`] = ` "Checkbox", "Coachmark", "Column", + "CompatibleComponentProps", "ConnectedCheckbox", "ConnectedForm", "ConnectedFormGroup", @@ -59,6 +60,7 @@ exports[`Gamut Exported Keys 1`] = ` "GridFormContent", "HiddenText", "IconButton", + "IconComponentType", "iFrameWrapper", "InfoTip", "Input", @@ -73,6 +75,7 @@ exports[`Gamut Exported Keys 1`] = ` "MenuSeparator", "Modal", "omitProps", + "OptionalScrollProps", "Overlay", "Pagination", "Popover", @@ -120,5 +123,7 @@ exports[`Gamut Exported Keys 1`] = ` "useLocalQuery", "useSubmitState", "Video", + "WithChildrenProp", + "WithOptionalScrollProps", ] `; diff --git a/packages/gamut/package.json b/packages/gamut/package.json index dee00d10f7f..fdaa8b58910 100644 --- a/packages/gamut/package.json +++ b/packages/gamut/package.json @@ -13,11 +13,11 @@ "@types/marked": "^4.0.8", "@vidstack/react": "^1.12.12", "classnames": "^2.2.5", - "framer-motion": "^11.18.0", "html-to-react": "^1.6.0", "invariant": "^2.2.4", "lodash": "^4.17.23", "marked": "^4.3.0", + "motion": "^12.0.0", "polished": "^4.1.2", "react-aria-components": "1.15.1", "react-aria-tabpanel": "^4.4.0", diff --git a/packages/gamut/src/AccordionAreaDeprecated/index.tsx b/packages/gamut/src/AccordionAreaDeprecated/index.tsx index 19cd0d13170..9dae28ea977 100644 --- a/packages/gamut/src/AccordionAreaDeprecated/index.tsx +++ b/packages/gamut/src/AccordionAreaDeprecated/index.tsx @@ -1,5 +1,5 @@ import styled from '@emotion/styled'; -import { motion } from 'framer-motion'; +import { motion } from 'motion/react'; import { useState } from 'react'; import * as React from 'react'; import { useIsomorphicLayoutEffect } from 'react-use'; diff --git a/packages/gamut/src/Alert/Alert.tsx b/packages/gamut/src/Alert/Alert.tsx index 7ae02e8cfb5..c3e89b53c22 100644 --- a/packages/gamut/src/Alert/Alert.tsx +++ b/packages/gamut/src/Alert/Alert.tsx @@ -211,7 +211,7 @@ export const Alert: React.FC = ({ initial={toggleState} transition={{ duration: 0.2, - ease: 'easeInOut', + ease: 'easeInOut' as const, }} variants={{ collapsed: { height: '2rem' }, diff --git a/packages/gamut/src/Alert/elements.tsx b/packages/gamut/src/Alert/elements.tsx index 4802d4a5506..ab1d2c5e95e 100644 --- a/packages/gamut/src/Alert/elements.tsx +++ b/packages/gamut/src/Alert/elements.tsx @@ -1,6 +1,6 @@ import { Background, css } from '@codecademy/gamut-styles'; import styled from '@emotion/styled'; -import { motion } from 'framer-motion'; +import { motion } from 'motion/react'; import { ComponentProps, forwardRef } from 'react'; import { Box } from '../Box'; diff --git a/packages/gamut/src/Anchor/index.tsx b/packages/gamut/src/Anchor/index.tsx index 910defc725d..2105fe0b4d7 100644 --- a/packages/gamut/src/Anchor/index.tsx +++ b/packages/gamut/src/Anchor/index.tsx @@ -1,24 +1,16 @@ import { styledOptions, system, variant } from '@codecademy/gamut-styles'; import { StyleProps, variance } from '@codecademy/variance'; import styled from '@emotion/styled'; -import { - forwardRef, - ForwardRefExoticComponent, - HTMLProps, - RefObject, -} from 'react'; +import { forwardRef, HTMLProps, RefObject } from 'react'; import { ButtonBase, ButtonSelectors } from '../ButtonBase/ButtonBase'; import { AppendedIconProps, appendIconToContent } from '../helpers'; -import { - CompatibleComponentProps, - CompatibleRefAttributes, - WithOptionalScrollProps, -} from '../utils'; +import { CompatibleComponentProps } from '../utils'; export interface AnchorProps extends StyleProps, StyleProps { + disabled?: boolean; onClick?: HTMLProps['onClick']; } @@ -181,7 +173,4 @@ const AnchorComponent = forwardRef< } ); -export const Anchor: ForwardRefExoticComponent< - WithOptionalScrollProps & - CompatibleRefAttributes -> = AnchorComponent; +export const Anchor = AnchorComponent; diff --git a/packages/gamut/src/Animation/ExpandInCollapseOut.tsx b/packages/gamut/src/Animation/ExpandInCollapseOut.tsx index 21c55cd60fc..c878882cc79 100644 --- a/packages/gamut/src/Animation/ExpandInCollapseOut.tsx +++ b/packages/gamut/src/Animation/ExpandInCollapseOut.tsx @@ -1,5 +1,5 @@ import { timingValues } from '@codecademy/gamut-styles'; -import { motion } from 'framer-motion'; +import { motion } from 'motion/react'; import { WithChildrenProp } from '../utils'; diff --git a/packages/gamut/src/Animation/FadeInSlideOut.tsx b/packages/gamut/src/Animation/FadeInSlideOut.tsx index f8a9bff26d7..92bc7b91311 100644 --- a/packages/gamut/src/Animation/FadeInSlideOut.tsx +++ b/packages/gamut/src/Animation/FadeInSlideOut.tsx @@ -1,5 +1,5 @@ import { timingValues } from '@codecademy/gamut-styles'; -import { motion } from 'framer-motion'; +import { motion } from 'motion/react'; import * as React from 'react'; import { Box } from '../Box'; diff --git a/packages/gamut/src/Animation/Rotation.tsx b/packages/gamut/src/Animation/Rotation.tsx index 2f514ffe45c..eddf6456dd9 100644 --- a/packages/gamut/src/Animation/Rotation.tsx +++ b/packages/gamut/src/Animation/Rotation.tsx @@ -1,5 +1,5 @@ import { timingValues } from '@codecademy/gamut-styles'; -import { motion } from 'framer-motion'; +import { motion } from 'motion/react'; import * as React from 'react'; import { WithChildrenProp } from '../utils'; diff --git a/packages/gamut/src/Box/Box.tsx b/packages/gamut/src/Box/Box.tsx index 8f2eb47782b..9bae2bf8ee8 100644 --- a/packages/gamut/src/Box/Box.tsx +++ b/packages/gamut/src/Box/Box.tsx @@ -4,7 +4,7 @@ import styled from '@emotion/styled'; import { asCompatibleForwardRefComponent, CompatibleStyledComponentProps, -} from '../utils'; +} from '../utils/types'; import { BoxProps, boxProps, sharedStates } from './props'; const StyledBox = styled('div', styledOptions(['fit']))( diff --git a/packages/gamut/src/Box/FlexBox.tsx b/packages/gamut/src/Box/FlexBox.tsx index d4d3b4b3046..fe6060bd213 100644 --- a/packages/gamut/src/Box/FlexBox.tsx +++ b/packages/gamut/src/Box/FlexBox.tsx @@ -4,7 +4,7 @@ import styled from '@emotion/styled'; import { asCompatibleForwardRefComponent, CompatibleStyledComponentProps, -} from '../utils'; +} from '../utils/types'; import { boxProps, FlexBoxProps, flexStates, sharedStates } from './props'; const StyledFlexBox = styled( diff --git a/packages/gamut/src/Box/GridBox.tsx b/packages/gamut/src/Box/GridBox.tsx index b3e4249f618..96a22302a92 100644 --- a/packages/gamut/src/Box/GridBox.tsx +++ b/packages/gamut/src/Box/GridBox.tsx @@ -4,7 +4,7 @@ import styled from '@emotion/styled'; import { asCompatibleForwardRefComponent, CompatibleStyledComponentProps, -} from '../utils'; +} from '../utils/types'; import { boxProps, GridBoxProps, gridStates, sharedStates } from './props'; const StyledGridBox = styled( diff --git a/packages/gamut/src/Card/elements.tsx b/packages/gamut/src/Card/elements.tsx index b75b77ba402..3d9ec6e84ba 100644 --- a/packages/gamut/src/Card/elements.tsx +++ b/packages/gamut/src/Card/elements.tsx @@ -1,12 +1,22 @@ import { Background } from '@codecademy/gamut-styles'; import styled from '@emotion/styled'; -import { motion } from 'framer-motion'; +import { motion } from 'motion/react'; +import type { Variants } from 'motion/react'; +import * as React from 'react'; import { Box } from '../Box'; import { cardVariants, shadowVariants } from './styles'; import { CardWrapperProps } from './types'; -export const MotionBox = motion.create(Box); +/** Minimal motion props used by Card; avoids TS4023 in declaration emit (React 19). */ +type MotionBoxProps = React.ComponentProps & { + initial?: string; + animate?: string; + whileHover?: string; + variants?: Variants; +}; + +export const MotionBox = motion.create(Box) as React.ComponentType; export const DynamicCardWrapper = styled(MotionBox)( cardVariants, diff --git a/packages/gamut/src/Card/index.tsx b/packages/gamut/src/Card/index.tsx index 4098940d18c..03b36d64e59 100644 --- a/packages/gamut/src/Card/index.tsx +++ b/packages/gamut/src/Card/index.tsx @@ -19,6 +19,15 @@ export const Card: React.FC = ({ height = '100%', ...rest }) => { + // Omit event handlers that conflict between React types and Motion types + const { + onAnimationStart: _a, + onAnimationEnd: _b, + onDragStart: _c, + onDrag: _d, + onDragEnd: _e, + ...restProps + } = rest; const defaultBorderRadius: BorderRadiusToken = isInteractive ? 'md' : 'none'; const trueBorderRadius = borderRadius ?? defaultBorderRadius; const resolvedBorderRadius = @@ -76,7 +85,7 @@ export const Card: React.FC = ({ shadow={shadow} variant={variant} variants={setHoverShadow} - {...rest} + {...restProps} > {children} diff --git a/packages/gamut/src/Card/styles.tsx b/packages/gamut/src/Card/styles.tsx index 1a080095ea7..aa64aab6a30 100644 --- a/packages/gamut/src/Card/styles.tsx +++ b/packages/gamut/src/Card/styles.tsx @@ -49,14 +49,14 @@ export const patternFadeInOut = { opacity: 1, transition: { duration: timingValues.medium / 1000, - ease: 'easeOut', + ease: 'easeOut' as const, }, }, animate: { opacity: 0, transition: { duration: timingValues.medium / 1000, - ease: 'easeIn', + ease: 'easeIn' as const, }, }, }; @@ -67,7 +67,7 @@ export const hoverShadowLeft = (borderRadius?: string) => ({ borderRadius, transition: { duration: timingValues.fast / 1000, - ease: 'easeOut', + ease: 'easeOut' as const, }, }, initialOutline: { @@ -75,7 +75,7 @@ export const hoverShadowLeft = (borderRadius?: string) => ({ borderRadius, transition: { duration: timingValues.fast / 1000, - ease: 'easeOut', + ease: 'easeOut' as const, }, }, animate: { @@ -84,7 +84,7 @@ export const hoverShadowLeft = (borderRadius?: string) => ({ borderRadius, transition: { duration: timingValues.fast / 1000, - ease: 'easeIn', + ease: 'easeIn' as const, }, }, animateOutline: { @@ -93,7 +93,7 @@ export const hoverShadowLeft = (borderRadius?: string) => ({ borderRadius, transition: { duration: timingValues.fast / 1000, - ease: 'easeIn', + ease: 'easeIn' as const, }, }, }); @@ -104,7 +104,7 @@ export const hoverShadowRight = (borderRadius?: string) => ({ borderRadius, transition: { duration: timingValues.fast / 1000, - ease: 'easeOut', + ease: 'easeOut' as const, }, }, animate: { @@ -113,7 +113,7 @@ export const hoverShadowRight = (borderRadius?: string) => ({ borderRadius, transition: { duration: timingValues.fast / 1000, - ease: 'easeIn', + ease: 'easeIn' as const, }, }, }); diff --git a/packages/gamut/src/Disclosure/index.tsx b/packages/gamut/src/Disclosure/index.tsx index 599dc611a96..bc37650dded 100644 --- a/packages/gamut/src/Disclosure/index.tsx +++ b/packages/gamut/src/Disclosure/index.tsx @@ -1,4 +1,4 @@ -import { AnimatePresence } from 'framer-motion'; +import { AnimatePresence } from 'motion/react'; import { useState } from 'react'; import * as React from 'react'; diff --git a/packages/gamut/src/Drawer/index.tsx b/packages/gamut/src/Drawer/index.tsx index 3dea3771b3e..331e87719ba 100644 --- a/packages/gamut/src/Drawer/index.tsx +++ b/packages/gamut/src/Drawer/index.tsx @@ -1,6 +1,6 @@ import { breakpoints, css, timingValues } from '@codecademy/gamut-styles'; import styled from '@emotion/styled'; -import { AnimatePresence, motion } from 'framer-motion'; +import { AnimatePresence, motion } from 'motion/react'; import { useEffect, useRef } from 'react'; import { useMedia } from 'react-use'; diff --git a/packages/gamut/src/FeatureShimmer/__tests__/FeatureShimmer.test.tsx b/packages/gamut/src/FeatureShimmer/__tests__/FeatureShimmer.test.tsx index c5bb6d7704a..d371b91eae7 100644 --- a/packages/gamut/src/FeatureShimmer/__tests__/FeatureShimmer.test.tsx +++ b/packages/gamut/src/FeatureShimmer/__tests__/FeatureShimmer.test.tsx @@ -4,8 +4,8 @@ import { FeatureShimmer } from '..'; const mockIntersectionObserver = jest.fn(); const mockUseReducedMotion = jest.fn(); -jest.mock('framer-motion', () => ({ - ...jest.requireActual('framer-motion'), +jest.mock('motion/react', () => ({ + ...jest.requireActual('motion/react'), get useReducedMotion() { return mockUseReducedMotion; }, diff --git a/packages/gamut/src/FeatureShimmer/index.tsx b/packages/gamut/src/FeatureShimmer/index.tsx index 78218b1ceca..c8807d87d5d 100644 --- a/packages/gamut/src/FeatureShimmer/index.tsx +++ b/packages/gamut/src/FeatureShimmer/index.tsx @@ -1,6 +1,6 @@ import { css } from '@codecademy/gamut-styles'; import styled from '@emotion/styled'; -import { motion, useReducedMotion } from 'framer-motion'; +import { motion, useReducedMotion } from 'motion/react'; import { Box, BoxProps } from '../Box'; @@ -24,7 +24,7 @@ const boxVariants = { backgroundColor: 'rgba(0, 0, 0, 0)', borderColor: 'rgba(0, 0, 0, 0)', transition: { - ease: 'easeOut', + ease: 'easeOut' as const, duration: 0.3, delay: 4, }, @@ -37,12 +37,12 @@ const shimmerVariants = { backgroundColor: 'rgba(0, 0, 0, 0)', transition: { left: { - ease: 'easeInOut', + ease: 'easeInOut' as const, duration: 2, delay: 2, }, backgroundColor: { - ease: 'easeOut', + ease: 'easeOut' as const, duration: 1, delay: 4, }, diff --git a/packages/gamut/src/List/ListRow.tsx b/packages/gamut/src/List/ListRow.tsx index 565ea1cd0ce..05e4663bc5c 100644 --- a/packages/gamut/src/List/ListRow.tsx +++ b/packages/gamut/src/List/ListRow.tsx @@ -1,6 +1,6 @@ import { css } from '@codecademy/gamut-styles'; import styled from '@emotion/styled'; -import { AnimatePresence, motion } from 'framer-motion'; +import { AnimatePresence, motion } from 'motion/react'; import { forwardRef, MouseEvent } from 'react'; import * as React from 'react'; diff --git a/packages/gamut/src/List/elements.tsx b/packages/gamut/src/List/elements.tsx index 86d8ee6cb70..5c6eecd78d2 100644 --- a/packages/gamut/src/List/elements.tsx +++ b/packages/gamut/src/List/elements.tsx @@ -8,7 +8,8 @@ import { } from '@codecademy/gamut-styles'; import { StyleProps, variance } from '@codecademy/variance'; import styled from '@emotion/styled'; -import { motion } from 'framer-motion'; +import { motion } from 'motion/react'; +import * as React from 'react'; import { Box } from '../Box'; @@ -518,10 +519,11 @@ const listStates = states({ export const StaticListWrapper = styled(Box)(listStyles, listStates); +// Type assertion avoids TS4023 (UNDEFINED_VOID_ONLY) in declaration emit with React 19 types export const AnimatedListWrapper = styled(motion.create(Box))( listStyles, listStates -); +) as React.ComponentType & Record>; export const hiddenVariant = { background: `linear-gradient(90deg, transparent 0%, transparent 40%, ${theme.colors['background-selected']} 50%, ${theme.colors['border-tertiary']} 100%)`, diff --git a/packages/gamut/src/Pagination/utils.tsx b/packages/gamut/src/Pagination/utils.tsx index 618a944bfac..4bebe6b0a20 100644 --- a/packages/gamut/src/Pagination/utils.tsx +++ b/packages/gamut/src/Pagination/utils.tsx @@ -1,4 +1,4 @@ -import { AnimatePresence, motion } from 'framer-motion'; +import { AnimatePresence, motion } from 'motion/react'; import { useEffect, useRef } from 'react'; import * as React from 'react'; @@ -91,10 +91,12 @@ const fadeAnimationVariants = { shown: { opacity: 1, cursor: 'pointer', + visibility: 'visible' as const, }, hidden: { opacity: 0, cursor: 'default', + visibility: 'hidden' as const, }, }; @@ -111,10 +113,8 @@ export const createAnimatedFadeButton = ( disabled={props.showButton === 'hidden'} initial={false} transition={{ - transitionStart: { visibility: 'visible' }, duration: 0.3, ease: [0.04, 0.62, 0.23, 0.98], - transitionEnd: { visibility: 'hidden' }, }} variants={fadeAnimationVariants} {...props} diff --git a/packages/gamut/src/Popover/elements.tsx b/packages/gamut/src/Popover/elements.tsx index 04908315050..8873eba943f 100644 --- a/packages/gamut/src/Popover/elements.tsx +++ b/packages/gamut/src/Popover/elements.tsx @@ -1,7 +1,7 @@ import { timingValues, variant } from '@codecademy/gamut-styles'; import { StyleProps } from '@codecademy/variance'; import styled from '@emotion/styled'; -import { AnimatePresence, motion } from 'framer-motion'; +import { AnimatePresence, motion } from 'motion/react'; import { BodyPortal } from '../BodyPortal'; import { Box, FlexBox } from '../Box'; diff --git a/packages/gamut/src/Tip/shared/FloatingTip.tsx b/packages/gamut/src/Tip/shared/FloatingTip.tsx index aa30dea6f0e..23ff041957b 100644 --- a/packages/gamut/src/Tip/shared/FloatingTip.tsx +++ b/packages/gamut/src/Tip/shared/FloatingTip.tsx @@ -175,7 +175,7 @@ export const FloatingTip: React.FC = ({ horizNarrow={narrow && isHorizontalCenter} isHoverType={isHoverType} narrow={narrow && !isHorizontalCenter} - ref={childRef as unknown as React.RefObject} + ref={childRef} > {contents} diff --git a/packages/gamut/src/Toaster/index.tsx b/packages/gamut/src/Toaster/index.tsx index 809d08aade6..30aadd29ae5 100644 --- a/packages/gamut/src/Toaster/index.tsx +++ b/packages/gamut/src/Toaster/index.tsx @@ -1,5 +1,5 @@ import { ColorMode, ColorModes } from '@codecademy/gamut-styles'; -import { AnimatePresence } from 'framer-motion'; +import { AnimatePresence } from 'motion/react'; import { ReactNode } from 'react'; import * as React from 'react'; diff --git a/packages/gamut/src/utils/index.ts b/packages/gamut/src/utils/index.ts index b4db92e3726..42e0a8535cf 100644 --- a/packages/gamut/src/utils/index.ts +++ b/packages/gamut/src/utils/index.ts @@ -3,4 +3,10 @@ export * from './focus'; export * from './generateResponsiveClassnames'; export * from './omitProps'; export * from './useIsMounted'; -export * from './types'; +export { + CompatibleComponentProps, + IconComponentType, + OptionalScrollProps, + WithChildrenProp, + WithOptionalScrollProps, +} from './types'; diff --git a/packages/gamut/src/utils/types.ts b/packages/gamut/src/utils/types.ts index d9e173743d3..9b8a0132700 100644 --- a/packages/gamut/src/utils/types.ts +++ b/packages/gamut/src/utils/types.ts @@ -33,9 +33,9 @@ export type CompatibleComponentProps = WithOptionalScrollProps>; /** - * Ref type compatible with React 18 and 19. - * In React 18 @types/react, Ref does not include RefObject, so useRef(null) - * can cause TS2322. Using this type in component ref props avoids that without patching @types/react. + * Ref type for component ref props so useRef(null) is accepted. + * Our @types/react patch fixed LegacyRef for DOM/forwardRef; Ref is unchanged and still + * does not include RefObject. Use this type when declaring ref props (e.g. on Box). */ export type CompatibleRef = | React.RefCallback @@ -65,9 +65,10 @@ export type CompatibleStyledComponentProps< * Treats a styled component (Emotion StyledComponent) as a ForwardRefExoticComponent * with compatible props. Emotion’s type doesn’t extend React’s ForwardRefExoticComponent, * so this centralizes the type assertion instead of repeating it in each file. + * Parameter accepts ComponentType so Emotion's StyledComponent (ref: LegacyRef) is accepted. */ export function asCompatibleForwardRefComponent

>( - component: React.ComponentType

+ component: React.ComponentType

| React.ComponentType ): React.ForwardRefExoticComponent

{ return component as unknown as React.ForwardRefExoticComponent

; } diff --git a/packages/styleguide/.storybook/components/Elements/ImageGallery.tsx b/packages/styleguide/.storybook/components/Elements/ImageGallery.tsx index 1f08b40e8dd..e89f1c2a87e 100644 --- a/packages/styleguide/.storybook/components/Elements/ImageGallery.tsx +++ b/packages/styleguide/.storybook/components/Elements/ImageGallery.tsx @@ -3,7 +3,7 @@ import { GamutIconProps } from '@codecademy/gamut-icons'; import { IllustrationProps } from '@codecademy/gamut-illustrations'; import { PatternProps } from '@codecademy/gamut-patterns'; import { css, timingValues } from '@codecademy/gamut-styles'; -import { motion, AnimatePresence } from 'framer-motion'; +import { motion, AnimatePresence } from 'motion/react'; import * as React from 'react'; import { useState } from 'react'; import styled from '@emotion/styled'; diff --git a/packages/styleguide/src/lib/Atoms/Animations/ExpandInCollapseOut/ExpandInCollapseOut.stories.tsx b/packages/styleguide/src/lib/Atoms/Animations/ExpandInCollapseOut/ExpandInCollapseOut.stories.tsx index db90b3908ee..8839131d03e 100644 --- a/packages/styleguide/src/lib/Atoms/Animations/ExpandInCollapseOut/ExpandInCollapseOut.stories.tsx +++ b/packages/styleguide/src/lib/Atoms/Animations/ExpandInCollapseOut/ExpandInCollapseOut.stories.tsx @@ -5,7 +5,7 @@ import { FlexBox, } from '@codecademy/gamut'; import type { Meta } from '@storybook/react'; -import { AnimatePresence } from 'framer-motion'; +import { AnimatePresence } from 'motion/react'; import { PropsWithChildren, useState } from 'react'; const meta: Meta = { diff --git a/packages/styleguide/src/lib/Atoms/Animations/FadeInSlideOut/FadeInSlideOut.stories.tsx b/packages/styleguide/src/lib/Atoms/Animations/FadeInSlideOut/FadeInSlideOut.stories.tsx index f10502f0da6..b7d2955a595 100644 --- a/packages/styleguide/src/lib/Atoms/Animations/FadeInSlideOut/FadeInSlideOut.stories.tsx +++ b/packages/styleguide/src/lib/Atoms/Animations/FadeInSlideOut/FadeInSlideOut.stories.tsx @@ -1,6 +1,6 @@ import { Box, FadeInSlideOut, FillButton, FlexBox } from '@codecademy/gamut'; import type { Meta } from '@storybook/react'; -import { AnimatePresence } from 'framer-motion'; +import { AnimatePresence } from 'motion/react'; import { useState } from 'react'; const meta: Meta = { diff --git a/packages/styleguide/src/lib/Meta/ESLint rules.mdx b/packages/styleguide/src/lib/Meta/ESLint rules.mdx index c459e5960bb..e21c95719b6 100644 --- a/packages/styleguide/src/lib/Meta/ESLint rules.mdx +++ b/packages/styleguide/src/lib/Meta/ESLint rules.mdx @@ -79,7 +79,7 @@ const ExpandableContainer = styled.Box( #### Disabling the rule -For third-party components or edge cases where inline styles are necessary (e.g., framer-motion animations), you can disable the rule: +For third-party components or edge cases where inline styles are necessary (e.g., motion animations), you can disable the rule: ```tsx // eslint-disable-next-line gamut/no-inline-style diff --git a/patches/@types+react+18.3.28.patch b/patches/@types+react+18.3.28.patch new file mode 100644 index 00000000000..4515ba6b6f4 --- /dev/null +++ b/patches/@types+react+18.3.28.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/@types/react/index.d.ts b/node_modules/@types/react/index.d.ts +--- a/node_modules/@types/react/index.d.ts ++++ b/node_modules/@types/react/index.d.ts +@@ -200,7 +200,8 @@ + * ``` + */ + // TODO: Remove the string ref special case from `PropsWithRef` once we remove LegacyRef +- type LegacyRef = string | Ref; ++ // Gamut polyfill: accept RefObject so useRef(null) is assignable to ref (React 18/19 compat) ++ type LegacyRef = string | Ref | RefObject; + + /** + * Retrieves the type of the 'ref' prop for a given component type or tag name. diff --git a/yarn.lock b/yarn.lock index 6c104be7baf..20ad46db3df 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1680,8 +1680,8 @@ __metadata: dependencies: "@codecademy/variance": "npm:0.25.2" "@emotion/is-prop-valid": "npm:^1.1.0" - framer-motion: "npm:^11.18.0" get-nonce: "npm:^1.0.0" + motion: "npm:^12.0.0" polished: "npm:^4.1.2" peerDependencies: "@emotion/cache": ^11.4.0 @@ -1718,11 +1718,11 @@ __metadata: "@types/marked": "npm:^4.0.8" "@vidstack/react": "npm:^1.12.12" classnames: "npm:^2.2.5" - framer-motion: "npm:^11.18.0" html-to-react: "npm:^1.6.0" invariant: "npm:^2.2.4" lodash: "npm:^4.17.23" marked: "npm:^4.3.0" + motion: "npm:^12.0.0" polished: "npm:^4.1.2" react-aria-components: "npm:1.15.1" react-aria-tabpanel: "npm:^4.4.0" @@ -8218,6 +8218,13 @@ __metadata: languageName: node linkType: hard +"@types/prop-types@npm:*": + version: 15.7.15 + resolution: "@types/prop-types@npm:15.7.15" + checksum: 10c0/b59aad1ad19bf1733cf524fd4e618196c6c7690f48ee70a327eb450a42aab8e8a063fbe59ca0a5701aebe2d92d582292c0fb845ea57474f6a15f6994b0e260b2 + languageName: node + linkType: hard + "@types/q@npm:^1.5.1": version: 1.5.8 resolution: "@types/q@npm:1.5.8" @@ -8239,12 +8246,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^19.0.0": - version: 19.2.3 - resolution: "@types/react-dom@npm:19.2.3" +"@types/react-dom@npm:^18.2.0": + version: 18.3.7 + resolution: "@types/react-dom@npm:18.3.7" peerDependencies: - "@types/react": ^19.2.0 - checksum: 10c0/b486ebe0f4e2fb35e2e108df1d8fc0927ca5d6002d5771e8a739de11239fe62d0e207c50886185253c99eb9dedfeeb956ea7429e5ba17f6693c7acb4c02f8cd1 + "@types/react": ^18.0.0 + checksum: 10c0/8bd309e2c3d1604a28a736a24f96cbadf6c05d5288cfef8883b74f4054c961b6b3a5e997fd5686e492be903c8f3380dba5ec017eff3906b1256529cd2d39603e languageName: node linkType: hard @@ -8257,12 +8264,13 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^19.0.0": - version: 19.2.14 - resolution: "@types/react@npm:19.2.14" +"@types/react@npm:^18.2.0": + version: 18.3.28 + resolution: "@types/react@npm:18.3.28" dependencies: + "@types/prop-types": "npm:*" csstype: "npm:^3.2.2" - checksum: 10c0/7d25bf41b57719452d86d2ac0570b659210402707313a36ee612666bf11275a1c69824f8c3ee1fdca077ccfe15452f6da8f1224529b917050eb2d861e52b59b7 + checksum: 10c0/683e19cd12b5c691215529af2e32b5ffbaccae3bf0ba93bfafa0e460e8dfee18423afed568be2b8eadf4b837c3749dd296a4f64e2d79f68fa66962c05f5af661 languageName: node linkType: hard @@ -9505,6 +9513,20 @@ __metadata: languageName: node linkType: hard +"async-function@npm:^1.0.0": + version: 1.0.0 + resolution: "async-function@npm:1.0.0" + checksum: 10c0/669a32c2cb7e45091330c680e92eaeb791bc1d4132d827591e499cd1f776ff5a873e77e5f92d0ce795a8d60f10761dec9ddfe7225a5de680f5d357f67b1aac73 + languageName: node + linkType: hard + +"async-generator-function@npm:^1.0.0": + version: 1.0.0 + resolution: "async-generator-function@npm:1.0.0" + checksum: 10c0/2c50ef856c543ad500d8d8777d347e3c1ba623b93e99c9263ecc5f965c1b12d2a140e2ab6e43c3d0b85366110696f28114649411cbcd10b452a92a2318394186 + languageName: node + linkType: hard + "async@npm:^2.6.4": version: 2.6.4 resolution: "async@npm:2.6.4" @@ -10155,7 +10177,7 @@ __metadata: languageName: node linkType: hard -"call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": +"call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": version: 1.0.2 resolution: "call-bind-apply-helpers@npm:1.0.2" dependencies: @@ -10178,6 +10200,28 @@ __metadata: languageName: node linkType: hard +"call-bind@npm:^1.0.8": + version: 1.0.8 + resolution: "call-bind@npm:1.0.8" + dependencies: + call-bind-apply-helpers: "npm:^1.0.0" + es-define-property: "npm:^1.0.0" + get-intrinsic: "npm:^1.2.4" + set-function-length: "npm:^1.2.2" + checksum: 10c0/a13819be0681d915144467741b69875ae5f4eba8961eb0bf322aab63ec87f8250eb6d6b0dcbb2e1349876412a56129ca338592b3829ef4343527f5f18a0752d4 + languageName: node + linkType: hard + +"call-bound@npm:^1.0.4": + version: 1.0.4 + resolution: "call-bound@npm:1.0.4" + dependencies: + call-bind-apply-helpers: "npm:^1.0.2" + get-intrinsic: "npm:^1.3.0" + checksum: 10c0/f4796a6a0941e71c766aea672f63b72bc61234c4f4964dc6d7606e3664c307e7d77845328a8f3359ce39ddb377fed67318f9ee203dea1d47e46165dcf2917644 + languageName: node + linkType: hard + "callsites@npm:^3.0.0, callsites@npm:^3.1.0": version: 3.1.0 resolution: "callsites@npm:3.1.0" @@ -10404,7 +10448,7 @@ __metadata: languageName: node linkType: hard -"ci-info@npm:^3.2.0, ci-info@npm:^3.6.1": +"ci-info@npm:^3.2.0, ci-info@npm:^3.6.1, ci-info@npm:^3.7.0": version: 3.9.0 resolution: "ci-info@npm:3.9.0" checksum: 10c0/6f0109e36e111684291d46123d491bc4e7b7a1934c3a20dea28cba89f1d4a03acd892f5f6a81ed3855c38647e285a150e3c9ba062e38943bef57fee6c1554c3a @@ -13853,6 +13897,15 @@ __metadata: languageName: node linkType: hard +"find-yarn-workspace-root@npm:^2.0.0": + version: 2.0.0 + resolution: "find-yarn-workspace-root@npm:2.0.0" + dependencies: + micromatch: "npm:^4.0.2" + checksum: 10c0/b0d3843013fbdaf4e57140e0165889d09fa61745c9e85da2af86e54974f4cc9f1967e40f0d8fc36a79d53091f0829c651d06607d552582e53976f3cd8f4e5689 + languageName: node + linkType: hard + "flat-cache@npm:^3.0.4": version: 3.2.0 resolution: "flat-cache@npm:3.2.0" @@ -14002,12 +14055,12 @@ __metadata: languageName: node linkType: hard -"framer-motion@npm:^11.18.0": - version: 11.18.2 - resolution: "framer-motion@npm:11.18.2" +"framer-motion@npm:^12.34.4": + version: 12.34.4 + resolution: "framer-motion@npm:12.34.4" dependencies: - motion-dom: "npm:^11.18.1" - motion-utils: "npm:^11.18.1" + motion-dom: "npm:^12.34.3" + motion-utils: "npm:^12.29.2" tslib: "npm:^2.4.0" peerDependencies: "@emotion/is-prop-valid": "*" @@ -14020,7 +14073,7 @@ __metadata: optional: true react-dom: optional: true - checksum: 10c0/41b1ef1b4e54ea13adaf01d61812a8783d2352f74641c91b50519775704bc6274db6b6863ff494a1f705fa6c6ed8f4df3497292327c906d53ea0129cef3ec361 + checksum: 10c0/28732e24a0dee80649eb70205e961a70e73d4dbfd3b6c1ed9afbb6910b59a2c626cc73931cf67e9cc1af1488fd7232f49a852a92148798cabd4deb46082b6d4e languageName: node linkType: hard @@ -14231,8 +14284,8 @@ __metadata: "@types/invariant": "npm:2.2.29" "@types/konami-code-js": "npm:^0.8.0" "@types/lodash": "npm:4.17.23" - "@types/react": "npm:^19.0.0" - "@types/react-dom": "npm:^19.0.0" + "@types/react": "npm:^18.2.0" + "@types/react-dom": "npm:^18.2.0" "@types/stylis": "npm:^4.2.0" "@typescript-eslint/eslint-plugin": "npm:^7.0.0" "@typescript-eslint/parser": "npm:^7.0.0" @@ -14263,9 +14316,10 @@ __metadata: nx: "npm:21.4.0" nx-cloud: "npm:^19.1.0" onchange: "npm:^7.0.2" + patch-package: "npm:^8.0.0" prettier: "npm:^2.8.7" - react: "npm:^19.0.0" - react-dom: "npm:^19.0.0" + react: "npm:^18.3.0" + react-dom: "npm:^18.3.0" react-helmet-async: "npm:^2.0.5" storybook: "npm:^8.6.15" storybook-addon-deep-controls: "npm:^0.9.5" @@ -14295,6 +14349,13 @@ __metadata: languageName: node linkType: hard +"generator-function@npm:^2.0.0": + version: 2.0.1 + resolution: "generator-function@npm:2.0.1" + checksum: 10c0/8a9f59df0f01cfefafdb3b451b80555e5cf6d76487095db91ac461a0e682e4ff7a9dbce15f4ecec191e53586d59eece01949e05a4b4492879600bbbe8e28d6b8 + languageName: node + linkType: hard + "generic-names@npm:^4.0.0": version: 4.0.0 resolution: "generic-names@npm:4.0.0" @@ -14336,6 +14397,27 @@ __metadata: languageName: node linkType: hard +"get-intrinsic@npm:^1.3.0": + version: 1.3.1 + resolution: "get-intrinsic@npm:1.3.1" + dependencies: + async-function: "npm:^1.0.0" + async-generator-function: "npm:^1.0.0" + call-bind-apply-helpers: "npm:^1.0.2" + es-define-property: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.1.1" + function-bind: "npm:^1.1.2" + generator-function: "npm:^2.0.0" + get-proto: "npm:^1.0.1" + gopd: "npm:^1.2.0" + has-symbols: "npm:^1.1.0" + hasown: "npm:^2.0.2" + math-intrinsics: "npm:^1.1.0" + checksum: 10c0/9f4ab0cf7efe0fd2c8185f52e6f637e708f3a112610c88869f8f041bb9ecc2ce44bf285dfdbdc6f4f7c277a5b88d8e94a432374d97cca22f3de7fc63795deb5d + languageName: node + linkType: hard + "get-nonce@npm:^1.0.0": version: 1.0.1 resolution: "get-nonce@npm:1.0.1" @@ -16102,7 +16184,7 @@ __metadata: languageName: node linkType: hard -"is-wsl@npm:^2.2.0": +"is-wsl@npm:^2.1.1, is-wsl@npm:^2.2.0": version: 2.2.0 resolution: "is-wsl@npm:2.2.0" dependencies: @@ -17274,6 +17356,19 @@ __metadata: languageName: node linkType: hard +"json-stable-stringify@npm:^1.0.2": + version: 1.3.0 + resolution: "json-stable-stringify@npm:1.3.0" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.4" + isarray: "npm:^2.0.5" + jsonify: "npm:^0.0.1" + object-keys: "npm:^1.1.1" + checksum: 10c0/8b3ff19e4c23c0ad591a49bc3a015d89a538db787d12fe9c4072e1d64d8cfa481f8c37719c629c3d84e848847617bf49f5fee894cf1d25959ab5b67e1c517f31 + languageName: node + linkType: hard + "json-stringify-safe@npm:^5.0.1": version: 5.0.1 resolution: "json-stringify-safe@npm:5.0.1" @@ -17333,6 +17428,13 @@ __metadata: languageName: node linkType: hard +"jsonify@npm:^0.0.1": + version: 0.0.1 + resolution: "jsonify@npm:0.0.1" + checksum: 10c0/7f5499cdd59a0967ed35bda48b7cec43d850bbc8fb955cdd3a1717bb0efadbe300724d5646de765bb7a99fc1c3ab06eb80d93503c6faaf99b4ff50a3326692f6 + languageName: node + linkType: hard + "jsonparse@npm:^1.2.0, jsonparse@npm:^1.3.1": version: 1.3.1 resolution: "jsonparse@npm:1.3.1" @@ -17384,6 +17486,15 @@ __metadata: languageName: node linkType: hard +"klaw-sync@npm:^6.0.0": + version: 6.0.0 + resolution: "klaw-sync@npm:6.0.0" + dependencies: + graceful-fs: "npm:^4.1.11" + checksum: 10c0/00d8e4c48d0d699b743b3b028e807295ea0b225caf6179f51029e19783a93ad8bb9bccde617d169659fbe99559d73fb35f796214de031d0023c26b906cecd70a + languageName: node + linkType: hard + "kleur@npm:^3.0.3": version: 3.0.3 resolution: "kleur@npm:3.0.3" @@ -17957,7 +18068,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.0.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -18739,19 +18850,40 @@ __metadata: languageName: node linkType: hard -"motion-dom@npm:^11.18.1": - version: 11.18.1 - resolution: "motion-dom@npm:11.18.1" +"motion-dom@npm:^12.34.3": + version: 12.34.3 + resolution: "motion-dom@npm:12.34.3" dependencies: - motion-utils: "npm:^11.18.1" - checksum: 10c0/98378bdf9d77870829cdf3624c5eff02e48cfa820dfc74450364d7421884700048d60e277bfbf477df33270fbae4c1980e5914586f5b6dff28d4921fdca8ac47 + motion-utils: "npm:^12.29.2" + checksum: 10c0/9a336be96dbb24a2ea3cafe401043553bc326274d118b86d6414e505cd394f26c071cd420d2e71c2cf19e76abc89bfdac4a7c5c1b3842eca56b11d6b8687dfdc languageName: node linkType: hard -"motion-utils@npm:^11.18.1": - version: 11.18.1 - resolution: "motion-utils@npm:11.18.1" - checksum: 10c0/dac083bdeb6e433a277ac4362211b0fdce59ff09d6f7897f0f49d1e3561209c6481f676876daf99a33485054bc7e4b1d1b8d1de16f7b1e5c6f117fe76358ca00 +"motion-utils@npm:^12.29.2": + version: 12.29.2 + resolution: "motion-utils@npm:12.29.2" + checksum: 10c0/8058fbb3467602e8263a8a6df0e5d318d00d30d7148415d2ebc13c78a3c7a1b0cbec0808bb62e82c34714979ecbed15b9fffb91bde654dbf3602c84b7d66a5b6 + languageName: node + linkType: hard + +"motion@npm:^12.0.0": + version: 12.34.4 + resolution: "motion@npm:12.34.4" + dependencies: + framer-motion: "npm:^12.34.4" + tslib: "npm:^2.4.0" + peerDependencies: + "@emotion/is-prop-valid": "*" + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@emotion/is-prop-valid": + optional: true + react: + optional: true + react-dom: + optional: true + checksum: 10c0/ab1b0c5f62b0781620bfd3ec9f22647666ff07fa1ae845f147d9f78e3250c121a0915b12c96186367b705df119a9df3c505168f76e7103213c923400ad3a292f languageName: node linkType: hard @@ -19696,6 +19828,16 @@ __metadata: languageName: node linkType: hard +"open@npm:^7.4.2": + version: 7.4.2 + resolution: "open@npm:7.4.2" + dependencies: + is-docker: "npm:^2.0.0" + is-wsl: "npm:^2.1.1" + checksum: 10c0/77573a6a68f7364f3a19a4c80492712720746b63680ee304555112605ead196afe91052bd3c3d165efdf4e9d04d255e87de0d0a77acec11ef47fd5261251813f + languageName: node + linkType: hard + "open@npm:^8.0.4, open@npm:^8.4.0, open@npm:~8.4.0": version: 8.4.2 resolution: "open@npm:8.4.2" @@ -20121,6 +20263,30 @@ __metadata: languageName: node linkType: hard +"patch-package@npm:^8.0.0": + version: 8.0.1 + resolution: "patch-package@npm:8.0.1" + dependencies: + "@yarnpkg/lockfile": "npm:^1.1.0" + chalk: "npm:^4.1.2" + ci-info: "npm:^3.7.0" + cross-spawn: "npm:^7.0.3" + find-yarn-workspace-root: "npm:^2.0.0" + fs-extra: "npm:^10.0.0" + json-stable-stringify: "npm:^1.0.2" + klaw-sync: "npm:^6.0.0" + minimist: "npm:^1.2.6" + open: "npm:^7.4.2" + semver: "npm:^7.5.3" + slash: "npm:^2.0.0" + tmp: "npm:^0.2.4" + yaml: "npm:^2.2.2" + bin: + patch-package: index.js + checksum: 10c0/6dd7cdd8b814902f1a66bc9082bd5a5a484956563538a694ff1de2e7f4cc14a13480739f5f04e0d1747395d6f1b651eb1ddbc39687ce5ff8a3927f212cffd2ac + languageName: node + linkType: hard + "path-browserify@npm:^1.0.1": version: 1.0.1 resolution: "path-browserify@npm:1.0.1" @@ -21533,14 +21699,15 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:^19.0.0": - version: 19.2.4 - resolution: "react-dom@npm:19.2.4" +"react-dom@npm:^18.3.0": + version: 18.3.1 + resolution: "react-dom@npm:18.3.1" dependencies: - scheduler: "npm:^0.27.0" + loose-envify: "npm:^1.1.0" + scheduler: "npm:^0.23.2" peerDependencies: - react: ^19.2.4 - checksum: 10c0/f0c63f1794dedb154136d4d0f59af00b41907f4859571c155940296808f4b94bf9c0c20633db75b5b2112ec13d8d7dd4f9bf57362ed48782f317b11d05a44f35 + react: ^18.3.1 + checksum: 10c0/a752496c1941f958f2e8ac56239172296fcddce1365ce45222d04a1947e0cc5547df3e8447f855a81d6d39f008d7c32eab43db3712077f09e3f67c4874973e85 languageName: node linkType: hard @@ -21820,10 +21987,12 @@ __metadata: languageName: node linkType: hard -"react@npm:^19.0.0": - version: 19.2.4 - resolution: "react@npm:19.2.4" - checksum: 10c0/cd2c9ff67a720799cc3b38a516009986f7fc4cb8d3e15716c6211cf098d1357ee3e348ab05ad0600042bbb0fd888530ba92e329198c92eafa0994f5213396596 +"react@npm:^18.3.0": + version: 18.3.1 + resolution: "react@npm:18.3.1" + dependencies: + loose-envify: "npm:^1.1.0" + checksum: 10c0/283e8c5efcf37802c9d1ce767f302dd569dd97a70d9bb8c7be79a789b9902451e0d16334b05d73299b20f048cbc3c7d288bbbde10b701fa194e2089c237dbea3 languageName: node linkType: hard @@ -22953,10 +23122,12 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:^0.27.0": - version: 0.27.0 - resolution: "scheduler@npm:0.27.0" - checksum: 10c0/4f03048cb05a3c8fddc45813052251eca00688f413a3cee236d984a161da28db28ba71bd11e7a3dd02f7af84ab28d39fb311431d3b3772fed557945beb00c452 +"scheduler@npm:^0.23.2": + version: 0.23.2 + resolution: "scheduler@npm:0.23.2" + dependencies: + loose-envify: "npm:^1.1.0" + checksum: 10c0/26383305e249651d4c58e6705d5f8425f153211aef95f15161c151f7b8de885f24751b377e4a0b3dd42cce09aad3f87a61dab7636859c0d89b7daf1a1e2a5c78 languageName: node linkType: hard @@ -23145,7 +23316,7 @@ __metadata: languageName: node linkType: hard -"set-function-length@npm:^1.2.1": +"set-function-length@npm:^1.2.1, set-function-length@npm:^1.2.2": version: 1.2.2 resolution: "set-function-length@npm:1.2.2" dependencies: @@ -24405,6 +24576,13 @@ __metadata: languageName: node linkType: hard +"tmp@npm:^0.2.4": + version: 0.2.5 + resolution: "tmp@npm:0.2.5" + checksum: 10c0/cee5bb7d674bb4ba3ab3f3841c2ca7e46daeb2109eec395c1ec7329a91d52fcb21032b79ac25161a37b2565c4858fefab927af9735926a113ef7bac9091a6e0e + languageName: node + linkType: hard + "tmp@npm:~0.2.1": version: 0.2.3 resolution: "tmp@npm:0.2.3" @@ -26123,6 +26301,15 @@ __metadata: languageName: node linkType: hard +"yaml@npm:^2.2.2": + version: 2.8.2 + resolution: "yaml@npm:2.8.2" + bin: + yaml: bin.mjs + checksum: 10c0/703e4dc1e34b324aa66876d63618dcacb9ed49f7e7fe9b70f1e703645be8d640f68ab84f12b86df8ac960bac37acf5513e115de7c970940617ce0343c8c9cd96 + languageName: node + linkType: hard + "yaml@npm:^2.6.0": version: 2.7.1 resolution: "yaml@npm:2.7.1" From b30b14603314d650d2d93047809672c8ddcf7a05 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Mon, 2 Mar 2026 13:39:11 -0500 Subject: [PATCH 25/35] test --- packages/gamut/src/Card/elements.tsx | 2 +- yarn.lock | 90 +++------------------------- 2 files changed, 9 insertions(+), 83 deletions(-) diff --git a/packages/gamut/src/Card/elements.tsx b/packages/gamut/src/Card/elements.tsx index 3d9ec6e84ba..b1d5274dca5 100644 --- a/packages/gamut/src/Card/elements.tsx +++ b/packages/gamut/src/Card/elements.tsx @@ -1,7 +1,7 @@ import { Background } from '@codecademy/gamut-styles'; import styled from '@emotion/styled'; -import { motion } from 'motion/react'; import type { Variants } from 'motion/react'; +import { motion } from 'motion/react'; import * as React from 'react'; import { Box } from '../Box'; diff --git a/yarn.lock b/yarn.lock index 20ad46db3df..1a27a227ed7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2435,20 +2435,13 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.10.0": +"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.6.1": version: 4.12.2 resolution: "@eslint-community/regexpp@npm:4.12.2" checksum: 10c0/fddcbc66851b308478d04e302a4d771d6917a0b3740dc351513c0da9ca2eab8a1adf99f5e0aa7ab8b13fa0df005c81adeee7e63a92f3effd7d367a163b721c2d languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.6.1": - version: 4.12.1 - resolution: "@eslint-community/regexpp@npm:4.12.1" - checksum: 10c0/a03d98c246bcb9109aec2c08e4d10c8d010256538dcb3f56610191607214523d4fb1b00aa81df830b6dffb74c5fa0be03642513a289c567949d3e550ca11cdf6 - languageName: node - linkType: hard - "@eslint/eslintrc@npm:^2.1.4": version: 2.1.4 resolution: "@eslint/eslintrc@npm:2.1.4" @@ -5401,7 +5394,7 @@ __metadata: languageName: node linkType: hard -"@react-aria/ssr@npm:^3.9.10": +"@react-aria/ssr@npm:^3.9.10, @react-aria/ssr@npm:^3.9.8": version: 3.9.10 resolution: "@react-aria/ssr@npm:3.9.10" dependencies: @@ -5412,17 +5405,6 @@ __metadata: languageName: node linkType: hard -"@react-aria/ssr@npm:^3.9.8": - version: 3.9.8 - resolution: "@react-aria/ssr@npm:3.9.8" - dependencies: - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/848cac34f8584477ab6c91686ab447c7f7eee997e0b1771cc71298d15a4dd0400ce7b899ad8c1603a72d59a72f24a390964133693a3ba602828801d4dacc3f45 - languageName: node - linkType: hard - "@react-aria/switch@npm:^3.7.10": version: 3.7.10 resolution: "@react-aria/switch@npm:3.7.10" @@ -10187,20 +10169,7 @@ __metadata: languageName: node linkType: hard -"call-bind@npm:^1.0.2, call-bind@npm:^1.0.5, call-bind@npm:^1.0.6, call-bind@npm:^1.0.7": - version: 1.0.7 - resolution: "call-bind@npm:1.0.7" - dependencies: - es-define-property: "npm:^1.0.0" - es-errors: "npm:^1.3.0" - function-bind: "npm:^1.1.2" - get-intrinsic: "npm:^1.2.4" - set-function-length: "npm:^1.2.1" - checksum: 10c0/a3ded2e423b8e2a265983dba81c27e125b48eefb2655e7dfab6be597088da3d47c47976c24bc51b8fd9af1061f8f87b4ab78a314f3c77784b2ae2ba535ad8b8d - languageName: node - linkType: hard - -"call-bind@npm:^1.0.8": +"call-bind@npm:^1.0.2, call-bind@npm:^1.0.5, call-bind@npm:^1.0.6, call-bind@npm:^1.0.7, call-bind@npm:^1.0.8": version: 1.0.8 resolution: "call-bind@npm:1.0.8" dependencies: @@ -14379,25 +14348,7 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.6": - version: 1.3.0 - resolution: "get-intrinsic@npm:1.3.0" - dependencies: - call-bind-apply-helpers: "npm:^1.0.2" - es-define-property: "npm:^1.0.1" - es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.1.1" - function-bind: "npm:^1.1.2" - get-proto: "npm:^1.0.1" - gopd: "npm:^1.2.0" - has-symbols: "npm:^1.1.0" - hasown: "npm:^2.0.2" - math-intrinsics: "npm:^1.1.0" - checksum: 10c0/52c81808af9a8130f581e6a6a83e1ba4a9f703359e7a438d1369a5267a25412322f03dcbd7c549edaef0b6214a0630a28511d7df0130c93cfd380f4fa0b5b66a - languageName: node - linkType: hard - -"get-intrinsic@npm:^1.3.0": +"get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.3.0": version: 1.3.1 resolution: "get-intrinsic@npm:1.3.1" dependencies: @@ -23234,16 +23185,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.2, semver@npm:^7.6.3, semver@npm:^7.7.2": - version: 7.7.2 - resolution: "semver@npm:7.7.2" - bin: - semver: bin/semver.js - checksum: 10c0/aca305edfbf2383c22571cb7714f48cadc7ac95371b4b52362fb8eeffdfbc0de0669368b82b2b15978f8848f01d7114da65697e56cd8c37b0dab8c58e543f9ea - languageName: node - linkType: hard - -"semver@npm:^7.6.0": +"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.2, semver@npm:^7.6.3, semver@npm:^7.7.2": version: 7.7.4 resolution: "semver@npm:7.7.4" bin: @@ -23316,7 +23258,7 @@ __metadata: languageName: node linkType: hard -"set-function-length@npm:^1.2.1, set-function-length@npm:^1.2.2": +"set-function-length@npm:^1.2.2": version: 1.2.2 resolution: "set-function-length@npm:1.2.2" dependencies: @@ -24576,20 +24518,13 @@ __metadata: languageName: node linkType: hard -"tmp@npm:^0.2.4": +"tmp@npm:^0.2.4, tmp@npm:~0.2.1": version: 0.2.5 resolution: "tmp@npm:0.2.5" checksum: 10c0/cee5bb7d674bb4ba3ab3f3841c2ca7e46daeb2109eec395c1ec7329a91d52fcb21032b79ac25161a37b2565c4858fefab927af9735926a113ef7bac9091a6e0e languageName: node linkType: hard -"tmp@npm:~0.2.1": - version: 0.2.3 - resolution: "tmp@npm:0.2.3" - checksum: 10c0/3e809d9c2f46817475b452725c2aaa5d11985cf18d32a7a970ff25b568438e2c076c2e8609224feef3b7923fa9749b74428e3e634f6b8e520c534eef2fd24125 - languageName: node - linkType: hard - "tmpl@npm:1.0.5": version: 1.0.5 resolution: "tmpl@npm:1.0.5" @@ -26301,7 +26236,7 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^2.2.2": +"yaml@npm:^2.2.2, yaml@npm:^2.6.0": version: 2.8.2 resolution: "yaml@npm:2.8.2" bin: @@ -26310,15 +26245,6 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^2.6.0": - version: 2.7.1 - resolution: "yaml@npm:2.7.1" - bin: - yaml: bin.mjs - checksum: 10c0/ee2126398ab7d1fdde566b4013b68e36930b9e6d8e68b6db356875c99614c10d678b6f45597a145ff6d63814961221fc305bf9242af8bf7450177f8a68537590 - languageName: node - linkType: hard - "yargs-parser@npm:20.2.4": version: 20.2.4 resolution: "yargs-parser@npm:20.2.4" From ab53da1107bda6b2f2dffcefd0eed1d9388108e1 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Mon, 2 Mar 2026 13:39:17 -0500 Subject: [PATCH 26/35] fix --- packages/gamut/src/Card/elements.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/gamut/src/Card/elements.tsx b/packages/gamut/src/Card/elements.tsx index b1d5274dca5..4274b9abc09 100644 --- a/packages/gamut/src/Card/elements.tsx +++ b/packages/gamut/src/Card/elements.tsx @@ -16,7 +16,9 @@ type MotionBoxProps = React.ComponentProps & { variants?: Variants; }; -export const MotionBox = motion.create(Box) as React.ComponentType; +export const MotionBox = motion.create( + Box +) as React.ComponentType; export const DynamicCardWrapper = styled(MotionBox)( cardVariants, From 2e4957ff429940d2b24ac71f7968cf1fecda4a80 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Mon, 2 Mar 2026 15:24:54 -0500 Subject: [PATCH 27/35] test motion types --- packages/gamut/src/Box/Box.tsx | 7 +++---- packages/gamut/src/Box/FlexBox.tsx | 7 +++---- packages/gamut/src/Box/GridBox.tsx | 7 +++---- packages/gamut/src/Card/elements.tsx | 16 ++-------------- packages/gamut/src/Card/index.tsx | 11 +---------- packages/gamut/src/Card/types.tsx | 7 ++++++- packages/gamut/src/List/elements.tsx | 4 +++- .../src/Pagination/__tests__/Pagination.test.tsx | 4 ++-- packages/gamut/src/utils/types.ts | 4 +++- 9 files changed, 26 insertions(+), 41 deletions(-) diff --git a/packages/gamut/src/Box/Box.tsx b/packages/gamut/src/Box/Box.tsx index 9bae2bf8ee8..b4d8339259b 100644 --- a/packages/gamut/src/Box/Box.tsx +++ b/packages/gamut/src/Box/Box.tsx @@ -13,9 +13,8 @@ const StyledBox = styled('div', styledOptions(['fit']))( ); export const Box = - asCompatibleForwardRefComponent>(StyledBox); + asCompatibleForwardRefComponent< + CompatibleStyledComponentProps + >(StyledBox); export type { BoxProps } from './props'; diff --git a/packages/gamut/src/Box/FlexBox.tsx b/packages/gamut/src/Box/FlexBox.tsx index fe6060bd213..ea7b0302ad1 100644 --- a/packages/gamut/src/Box/FlexBox.tsx +++ b/packages/gamut/src/Box/FlexBox.tsx @@ -13,9 +13,8 @@ const StyledFlexBox = styled( )(css({ display: 'flex' }), sharedStates, flexStates, boxProps); export const FlexBox = - asCompatibleForwardRefComponent>(StyledFlexBox); + asCompatibleForwardRefComponent< + CompatibleStyledComponentProps + >(StyledFlexBox); export type { FlexBoxProps } from './props'; diff --git a/packages/gamut/src/Box/GridBox.tsx b/packages/gamut/src/Box/GridBox.tsx index 96a22302a92..6e483aa05fd 100644 --- a/packages/gamut/src/Box/GridBox.tsx +++ b/packages/gamut/src/Box/GridBox.tsx @@ -18,7 +18,6 @@ const StyledGridBox = styled( ); export const GridBox = - asCompatibleForwardRefComponent>(StyledGridBox); + asCompatibleForwardRefComponent< + CompatibleStyledComponentProps + >(StyledGridBox); diff --git a/packages/gamut/src/Card/elements.tsx b/packages/gamut/src/Card/elements.tsx index 4274b9abc09..b75b77ba402 100644 --- a/packages/gamut/src/Card/elements.tsx +++ b/packages/gamut/src/Card/elements.tsx @@ -1,24 +1,12 @@ import { Background } from '@codecademy/gamut-styles'; import styled from '@emotion/styled'; -import type { Variants } from 'motion/react'; -import { motion } from 'motion/react'; -import * as React from 'react'; +import { motion } from 'framer-motion'; import { Box } from '../Box'; import { cardVariants, shadowVariants } from './styles'; import { CardWrapperProps } from './types'; -/** Minimal motion props used by Card; avoids TS4023 in declaration emit (React 19). */ -type MotionBoxProps = React.ComponentProps & { - initial?: string; - animate?: string; - whileHover?: string; - variants?: Variants; -}; - -export const MotionBox = motion.create( - Box -) as React.ComponentType; +export const MotionBox = motion.create(Box); export const DynamicCardWrapper = styled(MotionBox)( cardVariants, diff --git a/packages/gamut/src/Card/index.tsx b/packages/gamut/src/Card/index.tsx index 03b36d64e59..4098940d18c 100644 --- a/packages/gamut/src/Card/index.tsx +++ b/packages/gamut/src/Card/index.tsx @@ -19,15 +19,6 @@ export const Card: React.FC = ({ height = '100%', ...rest }) => { - // Omit event handlers that conflict between React types and Motion types - const { - onAnimationStart: _a, - onAnimationEnd: _b, - onDragStart: _c, - onDrag: _d, - onDragEnd: _e, - ...restProps - } = rest; const defaultBorderRadius: BorderRadiusToken = isInteractive ? 'md' : 'none'; const trueBorderRadius = borderRadius ?? defaultBorderRadius; const resolvedBorderRadius = @@ -85,7 +76,7 @@ export const Card: React.FC = ({ shadow={shadow} variant={variant} variants={setHoverShadow} - {...restProps} + {...rest} > {children} diff --git a/packages/gamut/src/Card/types.tsx b/packages/gamut/src/Card/types.tsx index e261db33733..03f519d8199 100644 --- a/packages/gamut/src/Card/types.tsx +++ b/packages/gamut/src/Card/types.tsx @@ -25,5 +25,10 @@ export interface CardWrapperProps export type CardProps = Omit< React.ComponentProps, - 'bg' + | 'bg' + | 'onAnimationStart' + | 'onAnimationEnd' + | 'onDragStart' + | 'onDrag' + | 'onDragEnd' >; diff --git a/packages/gamut/src/List/elements.tsx b/packages/gamut/src/List/elements.tsx index 5c6eecd78d2..bef140ace2f 100644 --- a/packages/gamut/src/List/elements.tsx +++ b/packages/gamut/src/List/elements.tsx @@ -523,7 +523,9 @@ export const StaticListWrapper = styled(Box)(listStyles, listStates); export const AnimatedListWrapper = styled(motion.create(Box))( listStyles, listStates -) as React.ComponentType & Record>; +) as React.ComponentType< + React.ComponentProps & Record +>; export const hiddenVariant = { background: `linear-gradient(90deg, transparent 0%, transparent 40%, ${theme.colors['background-selected']} 50%, ${theme.colors['border-tertiary']} 100%)`, diff --git a/packages/gamut/src/Pagination/__tests__/Pagination.test.tsx b/packages/gamut/src/Pagination/__tests__/Pagination.test.tsx index 9896fce28cc..db3f4b502da 100644 --- a/packages/gamut/src/Pagination/__tests__/Pagination.test.tsx +++ b/packages/gamut/src/Pagination/__tests__/Pagination.test.tsx @@ -130,7 +130,7 @@ describe('Pagination', () => { expect(getPage({ view, pageNumber: 7 })); }); - it('calls onChange with page number whenever page changes', () => { + it('calls onChange with page number whenever page changes', async () => { const { view } = renderView({}); const page2 = getPage({ view, pageNumber: 2 }); @@ -138,7 +138,7 @@ describe('Pagination', () => { fireEvent.click(page2); expect(onChange).toHaveBeenCalledWith(2); - const backButton = view.getByRole('button', { + const backButton = await view.findByRole('button', { name: /(Navigate back to page )\d+/, }); const forwardButton = getForwardButton({ view }); diff --git a/packages/gamut/src/utils/types.ts b/packages/gamut/src/utils/types.ts index 9b8a0132700..dfef736ead4 100644 --- a/packages/gamut/src/utils/types.ts +++ b/packages/gamut/src/utils/types.ts @@ -67,7 +67,9 @@ export type CompatibleStyledComponentProps< * so this centralizes the type assertion instead of repeating it in each file. * Parameter accepts ComponentType so Emotion's StyledComponent (ref: LegacyRef) is accepted. */ -export function asCompatibleForwardRefComponent

>( +export function asCompatibleForwardRefComponent< + P extends CompatibleRefAttributes +>( component: React.ComponentType

| React.ComponentType ): React.ForwardRefExoticComponent

{ return component as unknown as React.ForwardRefExoticComponent

; From d0f4e7f21f8547ae5372e1530616e628bc74537b Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Tue, 3 Mar 2026 09:46:48 -0500 Subject: [PATCH 28/35] withComponent patch --- packages/gamut/src/Box/Box.tsx | 14 ++++++-------- packages/gamut/src/Box/FlexBox.tsx | 14 ++++++-------- packages/gamut/src/Box/GridBox.tsx | 14 ++++++-------- packages/gamut/src/utils/types.ts | 15 +++++++++++++++ 4 files changed, 33 insertions(+), 24 deletions(-) diff --git a/packages/gamut/src/Box/Box.tsx b/packages/gamut/src/Box/Box.tsx index b4d8339259b..e7ddaf5d999 100644 --- a/packages/gamut/src/Box/Box.tsx +++ b/packages/gamut/src/Box/Box.tsx @@ -1,10 +1,8 @@ import { styledOptions } from '@codecademy/gamut-styles'; import styled from '@emotion/styled'; -import { - asCompatibleForwardRefComponent, - CompatibleStyledComponentProps, -} from '../utils/types'; +import type { CompatibleStyledComponentProps } from '../utils/types'; +import { asCompatibleForwardRefComponentWithStyled } from '../utils/types'; import { BoxProps, boxProps, sharedStates } from './props'; const StyledBox = styled('div', styledOptions(['fit']))( @@ -12,9 +10,9 @@ const StyledBox = styled('div', styledOptions(['fit']))( boxProps ); -export const Box = - asCompatibleForwardRefComponent< - CompatibleStyledComponentProps - >(StyledBox); +export const Box = asCompatibleForwardRefComponentWithStyled< + CompatibleStyledComponentProps, + typeof StyledBox +>(StyledBox); export type { BoxProps } from './props'; diff --git a/packages/gamut/src/Box/FlexBox.tsx b/packages/gamut/src/Box/FlexBox.tsx index ea7b0302ad1..484ea6981a7 100644 --- a/packages/gamut/src/Box/FlexBox.tsx +++ b/packages/gamut/src/Box/FlexBox.tsx @@ -1,10 +1,8 @@ import { css, styledOptions } from '@codecademy/gamut-styles'; import styled from '@emotion/styled'; -import { - asCompatibleForwardRefComponent, - CompatibleStyledComponentProps, -} from '../utils/types'; +import type { CompatibleStyledComponentProps } from '../utils/types'; +import { asCompatibleForwardRefComponentWithStyled } from '../utils/types'; import { boxProps, FlexBoxProps, flexStates, sharedStates } from './props'; const StyledFlexBox = styled( @@ -12,9 +10,9 @@ const StyledFlexBox = styled( styledOptions(['fit', 'wrap', 'center', 'column', 'row', 'inline']) )(css({ display: 'flex' }), sharedStates, flexStates, boxProps); -export const FlexBox = - asCompatibleForwardRefComponent< - CompatibleStyledComponentProps - >(StyledFlexBox); +export const FlexBox = asCompatibleForwardRefComponentWithStyled< + CompatibleStyledComponentProps, + typeof StyledFlexBox +>(StyledFlexBox); export type { FlexBoxProps } from './props'; diff --git a/packages/gamut/src/Box/GridBox.tsx b/packages/gamut/src/Box/GridBox.tsx index 6e483aa05fd..108b9aeb0ae 100644 --- a/packages/gamut/src/Box/GridBox.tsx +++ b/packages/gamut/src/Box/GridBox.tsx @@ -1,10 +1,8 @@ import { styledOptions, system } from '@codecademy/gamut-styles'; import styled from '@emotion/styled'; -import { - asCompatibleForwardRefComponent, - CompatibleStyledComponentProps, -} from '../utils/types'; +import type { CompatibleStyledComponentProps } from '../utils/types'; +import { asCompatibleForwardRefComponentWithStyled } from '../utils/types'; import { boxProps, GridBoxProps, gridStates, sharedStates } from './props'; const StyledGridBox = styled( @@ -17,7 +15,7 @@ const StyledGridBox = styled( boxProps ); -export const GridBox = - asCompatibleForwardRefComponent< - CompatibleStyledComponentProps - >(StyledGridBox); +export const GridBox = asCompatibleForwardRefComponentWithStyled< + CompatibleStyledComponentProps, + typeof StyledGridBox +>(StyledGridBox); diff --git a/packages/gamut/src/utils/types.ts b/packages/gamut/src/utils/types.ts index dfef736ead4..b0ddb991691 100644 --- a/packages/gamut/src/utils/types.ts +++ b/packages/gamut/src/utils/types.ts @@ -74,3 +74,18 @@ export function asCompatibleForwardRefComponent< ): React.ForwardRefExoticComponent

{ return component as unknown as React.ForwardRefExoticComponent

; } + +/** + * Like asCompatibleForwardRefComponent but also preserves the Emotion StyledComponent + * `withComponent` method on the return type so consumers can use Box.withComponent('span'). + * C is inferred from the component argument so only P is passed at the call site. + */ +export function asCompatibleForwardRefComponentWithStyled< + P extends CompatibleRefAttributes, + C extends React.ComponentType & { withComponent?: unknown } +>( + component: C +): React.ForwardRefExoticComponent

& Pick { + return component as unknown as React.ForwardRefExoticComponent

& + Pick; +} From 3a4b059df20103e9d8f2ce540e7ecc78a9438d34 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Tue, 3 Mar 2026 15:35:51 -0500 Subject: [PATCH 29/35] fromat --- packages/gamut/src/utils/types.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/gamut/src/utils/types.ts b/packages/gamut/src/utils/types.ts index b0ddb991691..6125dd1122a 100644 --- a/packages/gamut/src/utils/types.ts +++ b/packages/gamut/src/utils/types.ts @@ -83,9 +83,7 @@ export function asCompatibleForwardRefComponent< export function asCompatibleForwardRefComponentWithStyled< P extends CompatibleRefAttributes, C extends React.ComponentType & { withComponent?: unknown } ->( - component: C -): React.ForwardRefExoticComponent

& Pick { +>(component: C): React.ForwardRefExoticComponent

& Pick { return component as unknown as React.ForwardRefExoticComponent

& Pick; } From 2734dd39c65bb6837c65c76a610f82ce8dc9cd90 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Wed, 4 Mar 2026 09:17:57 -0500 Subject: [PATCH 30/35] test legacy ref breaking --- packages/gamut/src/utils/types.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/gamut/src/utils/types.ts b/packages/gamut/src/utils/types.ts index 6125dd1122a..ac87b9e62ce 100644 --- a/packages/gamut/src/utils/types.ts +++ b/packages/gamut/src/utils/types.ts @@ -33,15 +33,11 @@ export type CompatibleComponentProps = WithOptionalScrollProps>; /** - * Ref type for component ref props so useRef(null) is accepted. - * Our @types/react patch fixed LegacyRef for DOM/forwardRef; Ref is unchanged and still - * does not include RefObject. Use this type when declaring ref props (e.g. on Box). + * Ref type for component ref props. Accepts React's LegacyRef so consumers can pass + * refs without type errors (useRef, callback refs, or legacy string refs). Use when + * declaring ref props (e.g. on Box). */ -export type CompatibleRef = - | React.RefCallback - | React.RefObject - | React.RefObject - | null; +export type CompatibleRef = React.LegacyRef | null; /** * RefAttributes with ref typed as CompatibleRef so React 18 consumers can pass From 25410b62f5abdd70bd766fc4ac1e82871002f397 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Wed, 4 Mar 2026 13:42:24 -0500 Subject: [PATCH 31/35] connectedform --- .../gamut/src/ConnectedForm/ConnectedForm.tsx | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/gamut/src/ConnectedForm/ConnectedForm.tsx b/packages/gamut/src/ConnectedForm/ConnectedForm.tsx index faedf0d290d..a645a6c6b67 100644 --- a/packages/gamut/src/ConnectedForm/ConnectedForm.tsx +++ b/packages/gamut/src/ConnectedForm/ConnectedForm.tsx @@ -82,6 +82,18 @@ export interface ConnectedFormProps }; } +/** + * Explicit type for the ConnectedForm component so that declaration emission + * preserves the generic (Values) for consumers. Without this, forwardRef + * would be inferred as any and the .d.ts would lose onSubmit/onError types. + */ +export interface ConnectedFormComponent { + >( + props: ConnectedFormProps, + ref: React.ForwardedRef + ): React.ReactElement; +} + export type FormProviderCustomProps = FormProviderProps & FormContextProps; export const FormPropsContext = React.createContext>( @@ -181,7 +193,5 @@ export const ConnectedForm = forwardRef( ); } - // CASS COME BACK TO THIS - // React 19 JSX types expect single-arg components; forwardRef uses (props, ref) - // eslint-disable-next-line @typescript-eslint/no-explicit-any -) as any; + // CASS - come back to this +) as ConnectedFormComponent; From 6b9ddd1cff51d7967ba542a4c488c66173cecefb Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Wed, 4 Mar 2026 15:22:18 -0500 Subject: [PATCH 32/35] yarned --- yarn.lock | 673 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 638 insertions(+), 35 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3a3d2e86398..2c517c3125f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2611,6 +2611,15 @@ __metadata: languageName: node linkType: hard +"@internationalized/date@npm:^3.12.0": + version: 3.12.0 + resolution: "@internationalized/date@npm:3.12.0" + dependencies: + "@swc/helpers": "npm:^0.5.0" + checksum: 10c0/6a26495d32f010b227a1f506da02cdf8438506014b41cfb81576c707a3dfe3d0fd207f80bcf28acd9eef8248a2c2da115cf9016515d513653ea1b22a796d0246 + languageName: node + linkType: hard + "@internationalized/message@npm:^3.1.8": version: 3.1.8 resolution: "@internationalized/message@npm:3.1.8" @@ -5069,6 +5078,22 @@ __metadata: languageName: node linkType: hard +"@react-aria/interactions@npm:^3.24.1, @react-aria/interactions@npm:^3.27.0": + version: 3.27.1 + resolution: "@react-aria/interactions@npm:3.27.1" + dependencies: + "@react-aria/ssr": "npm:^3.9.10" + "@react-aria/utils": "npm:^3.33.1" + "@react-stately/flags": "npm:^3.1.2" + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/3fe2bf9b6d58554c21bacbc9d6af4a547040b803a8eaed5b5fa3ea99045fe777a038ef1f4b13919833b60744ba46635aaf0849d04a6de1eb545728c339a8b510 + languageName: node + linkType: hard + "@react-aria/label@npm:^3.7.24": version: 3.7.24 resolution: "@react-aria/label@npm:3.7.24" @@ -5611,6 +5636,23 @@ __metadata: languageName: node linkType: hard +"@react-aria/utils@npm:^3.33.1": + version: 3.33.1 + resolution: "@react-aria/utils@npm:3.33.1" + dependencies: + "@react-aria/ssr": "npm:^3.9.10" + "@react-stately/flags": "npm:^3.1.2" + "@react-stately/utils": "npm:^3.11.0" + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + clsx: "npm:^2.0.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/8b59b6e4f5f2358aecc291c929b621e68d121ebd15a8377da0a8b34ee706c9caea928dc34a0cc70650527dc9538619f4a9dcbcacf92bee31a73e69f59afbc772 + languageName: node + linkType: hard + "@react-aria/virtualizer@npm:^4.1.3": version: 4.1.12 resolution: "@react-aria/virtualizer@npm:4.1.12" @@ -5670,6 +5712,21 @@ __metadata: languageName: node linkType: hard +"@react-stately/calendar@npm:^3.9.3": + version: 3.9.3 + resolution: "@react-stately/calendar@npm:3.9.3" + dependencies: + "@internationalized/date": "npm:^3.12.0" + "@react-stately/utils": "npm:^3.11.0" + "@react-types/calendar": "npm:^3.8.3" + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/24231a0b0c270b9936a043b4e17091005fce0749804f1b0ea7e0f101f945081255d08439186d0229430f2ade745c9d2eaa131e0b154d236e0dc3b0912a93864e + languageName: node + linkType: hard + "@react-stately/checkbox@npm:^3.7.4": version: 3.7.4 resolution: "@react-stately/checkbox@npm:3.7.4" @@ -5685,6 +5742,33 @@ __metadata: languageName: node linkType: hard +"@react-stately/checkbox@npm:^3.7.5": + version: 3.7.5 + resolution: "@react-stately/checkbox@npm:3.7.5" + dependencies: + "@react-stately/form": "npm:^3.2.4" + "@react-stately/utils": "npm:^3.11.0" + "@react-types/checkbox": "npm:^3.10.4" + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/c60a931853af7882e7fa498f3e02c0ef13fbf824696f504869e22f1f1fc65967d3f05f9dd66a4b466bb8a8533113bddf713c712abcbcae07f50fb11c952db4c5 + languageName: node + linkType: hard + +"@react-stately/collections@npm:^3.12.10": + version: 3.12.10 + resolution: "@react-stately/collections@npm:3.12.10" + dependencies: + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/6c033e1e4f345bcad9cc725f63a63c2908d45ee96c44a27bf67d41f1c6065f9bce3177de2168cff53ca33ebe93028a8806e3f45659f600efcac739fae02876c1 + languageName: node + linkType: hard + "@react-stately/collections@npm:^3.12.9": version: 3.12.9 resolution: "@react-stately/collections@npm:3.12.9" @@ -5716,6 +5800,25 @@ __metadata: languageName: node linkType: hard +"@react-stately/color@npm:^3.9.5": + version: 3.9.5 + resolution: "@react-stately/color@npm:3.9.5" + dependencies: + "@internationalized/number": "npm:^3.6.5" + "@internationalized/string": "npm:^3.2.7" + "@react-stately/form": "npm:^3.2.4" + "@react-stately/numberfield": "npm:^3.11.0" + "@react-stately/slider": "npm:^3.7.5" + "@react-stately/utils": "npm:^3.11.0" + "@react-types/color": "npm:^3.1.4" + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/7fa5b21ef06ee3aab466e9caf1a4c6c9c4591828d433d0600777b1f00324abe4918572dd6ec6640d9a7ed41e631ef7ae19f7fa277c3232ae7fb20b1057b0938b + languageName: node + linkType: hard + "@react-stately/combobox@npm:^3.10.3, @react-stately/combobox@npm:^3.12.2": version: 3.12.2 resolution: "@react-stately/combobox@npm:3.12.2" @@ -5734,15 +5837,33 @@ __metadata: languageName: node linkType: hard -"@react-stately/data@npm:^3.15.1": - version: 3.15.1 - resolution: "@react-stately/data@npm:3.15.1" +"@react-stately/combobox@npm:^3.13.0": + version: 3.13.0 + resolution: "@react-stately/combobox@npm:3.13.0" dependencies: - "@react-types/shared": "npm:^3.33.0" + "@react-stately/collections": "npm:^3.12.10" + "@react-stately/form": "npm:^3.2.4" + "@react-stately/list": "npm:^3.13.4" + "@react-stately/overlays": "npm:^3.6.23" + "@react-stately/utils": "npm:^3.11.0" + "@react-types/combobox": "npm:^3.14.0" + "@react-types/shared": "npm:^3.33.1" "@swc/helpers": "npm:^0.5.0" peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/c9e131546bd2ddac696a7bba3c269108688db5af763cd17dd0a624215e23f7ea6d6b434a794416a6c572968cae4026d42f766be222c07ce5fc5aaea481d1d0e2 + checksum: 10c0/b538778862fa5107e8c8b54f630a5d0a6ec2c1d35ae9111b813baf0bdfd55f79cedd8b3dcf0a8ad118edfb9f300506a382b09c8a13b706f183d6d61156e4533d + languageName: node + linkType: hard + +"@react-stately/data@npm:^3.15.2": + version: 3.15.2 + resolution: "@react-stately/data@npm:3.15.2" + dependencies: + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/b8765059eac1e19dac9e0e4407f1a36e4204b62dd7efc87a1fe157574869df17f9852a7f6c94a8813b3844c38023f25317fe83eff1cd752552da59235b9c5f14 languageName: node linkType: hard @@ -5765,6 +5886,25 @@ __metadata: languageName: node linkType: hard +"@react-stately/datepicker@npm:^3.16.1": + version: 3.16.1 + resolution: "@react-stately/datepicker@npm:3.16.1" + dependencies: + "@internationalized/date": "npm:^3.12.0" + "@internationalized/number": "npm:^3.6.5" + "@internationalized/string": "npm:^3.2.7" + "@react-stately/form": "npm:^3.2.4" + "@react-stately/overlays": "npm:^3.6.23" + "@react-stately/utils": "npm:^3.11.0" + "@react-types/datepicker": "npm:^3.13.5" + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/7b4d044e9f5feb30ee5d4ac66fce9294a97464471d659d6fc35d6d0d4f8280283b1cfcbf5f232ac38ed16f4b765b15ac6d67399efb3f78488cf4e46d015e4c56 + languageName: node + linkType: hard + "@react-stately/disclosure@npm:^3.0.10": version: 3.0.10 resolution: "@react-stately/disclosure@npm:3.0.10" @@ -5778,6 +5918,19 @@ __metadata: languageName: node linkType: hard +"@react-stately/disclosure@npm:^3.0.11": + version: 3.0.11 + resolution: "@react-stately/disclosure@npm:3.0.11" + dependencies: + "@react-stately/utils": "npm:^3.11.0" + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/1b588e777fe01a527897cfce0fbc07525df02ee602e2a3a2415e5ef28596af965cbefc0a7f603aaea413f3ca1cb46ee236d0544550cf4906cb1a2d2ea6eb20fc + languageName: node + linkType: hard + "@react-stately/dnd@npm:^3.7.3": version: 3.7.3 resolution: "@react-stately/dnd@npm:3.7.3" @@ -5791,6 +5944,19 @@ __metadata: languageName: node linkType: hard +"@react-stately/dnd@npm:^3.7.4": + version: 3.7.4 + resolution: "@react-stately/dnd@npm:3.7.4" + dependencies: + "@react-stately/selection": "npm:^3.20.9" + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/9cb1292c04364e631ace5d5e86f0b89423c958a7b80dcd22ef2f36edca20a3cd9315af327a79d337e60d349ffcc770c9b59e0ab9dc206af5e42e6aad34229467 + languageName: node + linkType: hard + "@react-stately/flags@npm:^3.1.1, @react-stately/flags@npm:^3.1.2": version: 3.1.2 resolution: "@react-stately/flags@npm:3.1.2" @@ -5812,6 +5978,18 @@ __metadata: languageName: node linkType: hard +"@react-stately/form@npm:^3.2.4": + version: 3.2.4 + resolution: "@react-stately/form@npm:3.2.4" + dependencies: + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/e940fd5a8fa0fcd3f09acdc3eb97b12fa84690d6a4fc01a52da22673e4a2580b76626901296cad7ee7ed9ea43deb9a48e6af248bf4d59a4fe4c599f30941ecb3 + languageName: node + linkType: hard + "@react-stately/grid@npm:^3.11.8": version: 3.11.8 resolution: "@react-stately/grid@npm:3.11.8" @@ -5827,6 +6005,21 @@ __metadata: languageName: node linkType: hard +"@react-stately/grid@npm:^3.11.9": + version: 3.11.9 + resolution: "@react-stately/grid@npm:3.11.9" + dependencies: + "@react-stately/collections": "npm:^3.12.10" + "@react-stately/selection": "npm:^3.20.9" + "@react-types/grid": "npm:^3.3.8" + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/6fbd5be08268a893254f19a26495f7b578e78fd51373f92711603295c0335cfaf36a4478db77cc48fa585e22963370b232b3d394037c74125b90349e14bb0631 + languageName: node + linkType: hard + "@react-stately/layout@npm:^4.2.1": version: 4.5.3 resolution: "@react-stately/layout@npm:4.5.3" @@ -5860,6 +6053,21 @@ __metadata: languageName: node linkType: hard +"@react-stately/list@npm:^3.13.4": + version: 3.13.4 + resolution: "@react-stately/list@npm:3.13.4" + dependencies: + "@react-stately/collections": "npm:^3.12.10" + "@react-stately/selection": "npm:^3.20.9" + "@react-stately/utils": "npm:^3.11.0" + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/df5c4b07bd81fc2a3db13fa618aec99f91b94467d107f3ab123de6c336f757faf120c4fb3e04aa68a635026240668f78902ea9c4d3f3da6b4238506ecbbd5721 + languageName: node + linkType: hard + "@react-stately/menu@npm:^3.9.10": version: 3.9.10 resolution: "@react-stately/menu@npm:3.9.10" @@ -5874,6 +6082,20 @@ __metadata: languageName: node linkType: hard +"@react-stately/menu@npm:^3.9.11": + version: 3.9.11 + resolution: "@react-stately/menu@npm:3.9.11" + dependencies: + "@react-stately/overlays": "npm:^3.6.23" + "@react-types/menu": "npm:^3.10.7" + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/6006e7fd865eee1b4accdb22a13fbbd5c11de5f5b613a562b280eefbd2b1c3adb273348047d6214a5f53f6b4486202f46114969235110e02c1e208bf9e6eb635 + languageName: node + linkType: hard + "@react-stately/numberfield@npm:^3.10.4": version: 3.10.4 resolution: "@react-stately/numberfield@npm:3.10.4" @@ -5889,6 +6111,21 @@ __metadata: languageName: node linkType: hard +"@react-stately/numberfield@npm:^3.11.0": + version: 3.11.0 + resolution: "@react-stately/numberfield@npm:3.11.0" + dependencies: + "@internationalized/number": "npm:^3.6.5" + "@react-stately/form": "npm:^3.2.4" + "@react-stately/utils": "npm:^3.11.0" + "@react-types/numberfield": "npm:^3.8.18" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/5e82aed4dadb5a0ef38385ef07c961c88d27f96e4d1a7fa8ebb79ebb825d235f919e31cf97cb09e369d412682742acbef631c7b876cbedd040d65e1df0d8af72 + languageName: node + linkType: hard + "@react-stately/overlays@npm:^3.6.22": version: 3.6.22 resolution: "@react-stately/overlays@npm:3.6.22" @@ -5902,6 +6139,19 @@ __metadata: languageName: node linkType: hard +"@react-stately/overlays@npm:^3.6.23": + version: 3.6.23 + resolution: "@react-stately/overlays@npm:3.6.23" + dependencies: + "@react-stately/utils": "npm:^3.11.0" + "@react-types/overlays": "npm:^3.9.4" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/7c62160e11bbeb58780a629e09f0c8b16716a06b5c6114909fc45bb0118d55913b50aab3bbee2d6f60bbdd1075fed234dd361b3595b6cc49115a370c66b01ff3 + languageName: node + linkType: hard + "@react-stately/radio@npm:^3.11.4": version: 3.11.4 resolution: "@react-stately/radio@npm:3.11.4" @@ -5917,6 +6167,21 @@ __metadata: languageName: node linkType: hard +"@react-stately/radio@npm:^3.11.5": + version: 3.11.5 + resolution: "@react-stately/radio@npm:3.11.5" + dependencies: + "@react-stately/form": "npm:^3.2.4" + "@react-stately/utils": "npm:^3.11.0" + "@react-types/radio": "npm:^3.9.4" + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/85a3cdd263e91445b4c739a8cf817a44032aab4c0863b385ebda49009d5c737fa653d087fc992771304037972d4d31fd065c00a46a36f11f688cb2e9e5da215e + languageName: node + linkType: hard + "@react-stately/searchfield@npm:^3.5.18": version: 3.5.18 resolution: "@react-stately/searchfield@npm:3.5.18" @@ -5930,6 +6195,19 @@ __metadata: languageName: node linkType: hard +"@react-stately/searchfield@npm:^3.5.19": + version: 3.5.19 + resolution: "@react-stately/searchfield@npm:3.5.19" + dependencies: + "@react-stately/utils": "npm:^3.11.0" + "@react-types/searchfield": "npm:^3.6.8" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/f0b0cb7bbfdc7415049739984b6670baff4e45e62d26026050bd916a0c45e1f740fa53f4bc5d08326ae6b1b41ea8db219e34b3e6c053d8d8398536eeeee396ed + languageName: node + linkType: hard + "@react-stately/select@npm:^3.9.1": version: 3.9.1 resolution: "@react-stately/select@npm:3.9.1" @@ -5947,6 +6225,23 @@ __metadata: languageName: node linkType: hard +"@react-stately/select@npm:^3.9.2": + version: 3.9.2 + resolution: "@react-stately/select@npm:3.9.2" + dependencies: + "@react-stately/form": "npm:^3.2.4" + "@react-stately/list": "npm:^3.13.4" + "@react-stately/overlays": "npm:^3.6.23" + "@react-stately/utils": "npm:^3.11.0" + "@react-types/select": "npm:^3.12.2" + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/613ec7668802085f5b281d651ec0e2229b45dc17b2b750342bfbba928965af1da1e64f0214f89eafc836710ee440406863b8ac26b80e8d63c2fe9945a587f3f5 + languageName: node + linkType: hard + "@react-stately/selection@npm:^3.20.0, @react-stately/selection@npm:^3.20.8": version: 3.20.8 resolution: "@react-stately/selection@npm:3.20.8" @@ -5961,6 +6256,20 @@ __metadata: languageName: node linkType: hard +"@react-stately/selection@npm:^3.20.9": + version: 3.20.9 + resolution: "@react-stately/selection@npm:3.20.9" + dependencies: + "@react-stately/collections": "npm:^3.12.10" + "@react-stately/utils": "npm:^3.11.0" + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/c006938877d900a885e39d066f5f5bc00fe346c197b4514b7cd93256e402d88f3f133e84f0ca22385d975936d641e6535ba1560cf73333c2314d6621d08b2cd3 + languageName: node + linkType: hard + "@react-stately/slider@npm:^3.7.4": version: 3.7.4 resolution: "@react-stately/slider@npm:3.7.4" @@ -5975,6 +6284,20 @@ __metadata: languageName: node linkType: hard +"@react-stately/slider@npm:^3.7.5": + version: 3.7.5 + resolution: "@react-stately/slider@npm:3.7.5" + dependencies: + "@react-stately/utils": "npm:^3.11.0" + "@react-types/shared": "npm:^3.33.1" + "@react-types/slider": "npm:^3.8.4" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/e1c14a4354f910bf967b4e450e02bb447baa3a268460a00b19944ce457785ec19a3fb386a82c7d1d7ff6a110a368193a008418ecfbaab9844681d7391d4568a0 + languageName: node + linkType: hard + "@react-stately/table@npm:^3.14.0, @react-stately/table@npm:^3.15.3": version: 3.15.3 resolution: "@react-stately/table@npm:3.15.3" @@ -5994,6 +6317,25 @@ __metadata: languageName: node linkType: hard +"@react-stately/table@npm:^3.15.4": + version: 3.15.4 + resolution: "@react-stately/table@npm:3.15.4" + dependencies: + "@react-stately/collections": "npm:^3.12.10" + "@react-stately/flags": "npm:^3.1.2" + "@react-stately/grid": "npm:^3.11.9" + "@react-stately/selection": "npm:^3.20.9" + "@react-stately/utils": "npm:^3.11.0" + "@react-types/grid": "npm:^3.3.8" + "@react-types/shared": "npm:^3.33.1" + "@react-types/table": "npm:^3.13.6" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/47fef5047d1e0aeb7e34db1f575d9f92b4b6bb5264dcf59862fed32d227863b6fc0b0b4357cb542fa25cc2f4d271e719e3a04bf1875960d01b6fa9860956ff07 + languageName: node + linkType: hard + "@react-stately/tabs@npm:^3.8.8": version: 3.8.8 resolution: "@react-stately/tabs@npm:3.8.8" @@ -6008,6 +6350,20 @@ __metadata: languageName: node linkType: hard +"@react-stately/tabs@npm:^3.8.9": + version: 3.8.9 + resolution: "@react-stately/tabs@npm:3.8.9" + dependencies: + "@react-stately/list": "npm:^3.13.4" + "@react-types/shared": "npm:^3.33.1" + "@react-types/tabs": "npm:^3.3.22" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/9c61603a3c928b5caa40b02fe0fb82e0c9085d3f3dc624bc0e911981097fe3db4a03c13e794178f3fc47365a4a71b46b1098346da00b5464ad19277b936b4236 + languageName: node + linkType: hard + "@react-stately/toast@npm:^3.1.3": version: 3.1.3 resolution: "@react-stately/toast@npm:3.1.3" @@ -6034,6 +6390,20 @@ __metadata: languageName: node linkType: hard +"@react-stately/toggle@npm:^3.9.5": + version: 3.9.5 + resolution: "@react-stately/toggle@npm:3.9.5" + dependencies: + "@react-stately/utils": "npm:^3.11.0" + "@react-types/checkbox": "npm:^3.10.4" + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/eebc198e2d8a9f90d94d42e90657147ac380cc7db053549d203a97780963d007f92545e5dab03a8126530c6444254d1b802a2a7918dfc537e16d172e17172d20 + languageName: node + linkType: hard + "@react-stately/tooltip@npm:^3.5.10": version: 3.5.10 resolution: "@react-stately/tooltip@npm:3.5.10" @@ -6047,6 +6417,19 @@ __metadata: languageName: node linkType: hard +"@react-stately/tooltip@npm:^3.5.11": + version: 3.5.11 + resolution: "@react-stately/tooltip@npm:3.5.11" + dependencies: + "@react-stately/overlays": "npm:^3.6.23" + "@react-types/tooltip": "npm:^3.5.2" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/d21970faad11e33d3255ef7957ca299951f4b4e677b3a49418f534b1bc3ce5a627fd3531b23e7e9d77e4de6e5d2d1300c713de271e9614b0e5b12ced29d93103 + languageName: node + linkType: hard + "@react-stately/tree@npm:^3.9.5": version: 3.9.5 resolution: "@react-stately/tree@npm:3.9.5" @@ -6062,6 +6445,21 @@ __metadata: languageName: node linkType: hard +"@react-stately/tree@npm:^3.9.6": + version: 3.9.6 + resolution: "@react-stately/tree@npm:3.9.6" + dependencies: + "@react-stately/collections": "npm:^3.12.10" + "@react-stately/selection": "npm:^3.20.9" + "@react-stately/utils": "npm:^3.11.0" + "@react-types/shared": "npm:^3.33.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/96b82237a95d3d6957989f36fd7595263f5c28b786e65efe3c51e18b379e1385cddcfd0b806380ed046798df76020a12eb12d4f4a810d15cfaed579e95e63e26 + languageName: node + linkType: hard + "@react-stately/utils@npm:^3.10.4, @react-stately/utils@npm:^3.10.5, @react-stately/utils@npm:^3.11.0": version: 3.11.0 resolution: "@react-stately/utils@npm:3.11.0" @@ -6134,6 +6532,18 @@ __metadata: languageName: node linkType: hard +"@react-types/calendar@npm:^3.8.3": + version: 3.8.3 + resolution: "@react-types/calendar@npm:3.8.3" + dependencies: + "@internationalized/date": "npm:^3.12.0" + "@react-types/shared": "npm:^3.33.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/c1f129b2f431227d7150639f95201c50f32299813e3e8714f2457335023675ff61b08508b67a687ceef18c0449e1b07c7863688e2710615be746cde6ffb60c0b + languageName: node + linkType: hard + "@react-types/checkbox@npm:^3.10.3": version: 3.10.3 resolution: "@react-types/checkbox@npm:3.10.3" @@ -6145,6 +6555,17 @@ __metadata: languageName: node linkType: hard +"@react-types/checkbox@npm:^3.10.4": + version: 3.10.4 + resolution: "@react-types/checkbox@npm:3.10.4" + dependencies: + "@react-types/shared": "npm:^3.33.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/010479017ce2b42a1f4f10cf539f5fe48c85c555224bac1368c9e0433a7803d58bf2ba84a78597eae34387aac65caa7b64b9e6da8fbb391c91076f590957f25b + languageName: node + linkType: hard + "@react-types/color@npm:^3.1.3": version: 3.1.3 resolution: "@react-types/color@npm:3.1.3" @@ -6157,6 +6578,18 @@ __metadata: languageName: node linkType: hard +"@react-types/color@npm:^3.1.4": + version: 3.1.4 + resolution: "@react-types/color@npm:3.1.4" + dependencies: + "@react-types/shared": "npm:^3.33.1" + "@react-types/slider": "npm:^3.8.4" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/ab0505bad9bca20049539dff6949ba6be84e43e5dda375844d5f4957127ea0af8b565e11c3fb3cb1bff2885d75a9d31cc7c7e210b6a5434f9cd57dc04ef434d9 + languageName: node + linkType: hard + "@react-types/combobox@npm:^3.13.11, @react-types/combobox@npm:^3.13.3": version: 3.13.11 resolution: "@react-types/combobox@npm:3.13.11" @@ -6168,6 +6601,17 @@ __metadata: languageName: node linkType: hard +"@react-types/combobox@npm:^3.14.0": + version: 3.14.0 + resolution: "@react-types/combobox@npm:3.14.0" + dependencies: + "@react-types/shared": "npm:^3.33.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/6a36a6e2068cb03455e4ce254006ec9377a14ab958bcab0d3f0a8840e467a7efeda25a0817c46a4137ba861115f38dea0bf56d945a89c85356abfcaa45a2df34 + languageName: node + linkType: hard + "@react-types/datepicker@npm:^3.13.4": version: 3.13.4 resolution: "@react-types/datepicker@npm:3.13.4" @@ -6182,6 +6626,20 @@ __metadata: languageName: node linkType: hard +"@react-types/datepicker@npm:^3.13.5": + version: 3.13.5 + resolution: "@react-types/datepicker@npm:3.13.5" + dependencies: + "@internationalized/date": "npm:^3.12.0" + "@react-types/calendar": "npm:^3.8.3" + "@react-types/overlays": "npm:^3.9.4" + "@react-types/shared": "npm:^3.33.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/e011c1d0844ddd36ed50448fb83aec602fc3c6db4f32a5c6d76d3bb168debafb170aa880102de4abb664ff2f77d140037b63ca4a375f4b1574989ce5b471c3c3 + languageName: node + linkType: hard + "@react-types/dialog@npm:^3.5.23": version: 3.5.23 resolution: "@react-types/dialog@npm:3.5.23" @@ -6216,6 +6674,17 @@ __metadata: languageName: node linkType: hard +"@react-types/grid@npm:^3.3.8": + version: 3.3.8 + resolution: "@react-types/grid@npm:3.3.8" + dependencies: + "@react-types/shared": "npm:^3.33.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/2a47eb97919869d5d68ebe3d34e2f48fb36bd5d9b8e8cea973661c4658399484c801b0d1ddbedfea5358e05924e5460306b6f8745a5428c1a163b3d23360053c + languageName: node + linkType: hard + "@react-types/link@npm:^3.6.6": version: 3.6.6 resolution: "@react-types/link@npm:3.6.6" @@ -6250,6 +6719,18 @@ __metadata: languageName: node linkType: hard +"@react-types/menu@npm:^3.10.7": + version: 3.10.7 + resolution: "@react-types/menu@npm:3.10.7" + dependencies: + "@react-types/overlays": "npm:^3.9.4" + "@react-types/shared": "npm:^3.33.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/4537966ccd72cd1e181082068e383a65eaaad294a1e11b81eda6d7f7d6a507729040be496df403d85d24a0cf28fd2efb5a33aa21a8e6532ff0f0ecf1230a71b5 + languageName: node + linkType: hard + "@react-types/meter@npm:^3.4.14": version: 3.4.14 resolution: "@react-types/meter@npm:3.4.14" @@ -6272,6 +6753,17 @@ __metadata: languageName: node linkType: hard +"@react-types/numberfield@npm:^3.8.18": + version: 3.8.18 + resolution: "@react-types/numberfield@npm:3.8.18" + dependencies: + "@react-types/shared": "npm:^3.33.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/720e531c7e2aba91fe25193a0adb5acd2a46a04d813d5fef904db409dccaa5c761316f2d0c0e9329e4d305535c8d7569214aac08296df1f0085b0095b649dba7 + languageName: node + linkType: hard + "@react-types/overlays@npm:^3.9.3": version: 3.9.3 resolution: "@react-types/overlays@npm:3.9.3" @@ -6283,6 +6775,17 @@ __metadata: languageName: node linkType: hard +"@react-types/overlays@npm:^3.9.4": + version: 3.9.4 + resolution: "@react-types/overlays@npm:3.9.4" + dependencies: + "@react-types/shared": "npm:^3.33.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/ecf332ad553029db14cf4a001893ade13f56bb6fc003357d2854166067c2b5dd2229e976cca79bf707c3f7c47d5dedb675d9b2ce45000114e4531dc5aaf00e04 + languageName: node + linkType: hard + "@react-types/progress@npm:^3.5.17": version: 3.5.17 resolution: "@react-types/progress@npm:3.5.17" @@ -6305,6 +6808,17 @@ __metadata: languageName: node linkType: hard +"@react-types/radio@npm:^3.9.4": + version: 3.9.4 + resolution: "@react-types/radio@npm:3.9.4" + dependencies: + "@react-types/shared": "npm:^3.33.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/a9634cf79e0ab6d6aa399b64d2684c28f8e54aaf85bb78a4e9a6457f0a87d199b27afb51f474dba19c7f55cd74ad0570962659c1031a70a8f04e8918f716b393 + languageName: node + linkType: hard + "@react-types/searchfield@npm:^3.6.0, @react-types/searchfield@npm:^3.6.7": version: 3.6.7 resolution: "@react-types/searchfield@npm:3.6.7" @@ -6317,6 +6831,18 @@ __metadata: languageName: node linkType: hard +"@react-types/searchfield@npm:^3.6.8": + version: 3.6.8 + resolution: "@react-types/searchfield@npm:3.6.8" + dependencies: + "@react-types/shared": "npm:^3.33.1" + "@react-types/textfield": "npm:^3.12.8" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/de035fd6bf9f84758a1bb9d3c19585200959fcf4d58539a0516e2726c15399273093fba6c38bd2b8ad428318ecd21048e3f434571c8fc2437e90cd22fdaabc11 + languageName: node + linkType: hard + "@react-types/select@npm:^3.12.1": version: 3.12.1 resolution: "@react-types/select@npm:3.12.1" @@ -6328,6 +6854,17 @@ __metadata: languageName: node linkType: hard +"@react-types/select@npm:^3.12.2": + version: 3.12.2 + resolution: "@react-types/select@npm:3.12.2" + dependencies: + "@react-types/shared": "npm:^3.33.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/5e4f191174fbe2662d03c0d9a8b8fafa7617cf7a68765649bd739aedd25d30cf1f8466f0ec43d3659c789a43692690940db693d7ee65f07549b62c47caa257ff + languageName: node + linkType: hard + "@react-types/shared@npm:^3.28.0, @react-types/shared@npm:^3.29.0, @react-types/shared@npm:^3.33.0": version: 3.33.0 resolution: "@react-types/shared@npm:3.33.0" @@ -6337,6 +6874,15 @@ __metadata: languageName: node linkType: hard +"@react-types/shared@npm:^3.33.1": + version: 3.33.1 + resolution: "@react-types/shared@npm:3.33.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/072dbf92de80e3535441fbf4a9075009636221974d0b70bd1078ec1e343ae1373d69d2c02c2fba0963e50f4b134872144ffaf1573daec8477233e408f96e008c + languageName: node + linkType: hard + "@react-types/slider@npm:^3.8.3": version: 3.8.3 resolution: "@react-types/slider@npm:3.8.3" @@ -6348,6 +6894,17 @@ __metadata: languageName: node linkType: hard +"@react-types/slider@npm:^3.8.4": + version: 3.8.4 + resolution: "@react-types/slider@npm:3.8.4" + dependencies: + "@react-types/shared": "npm:^3.33.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/e1bbc112d88aa73d1a808cac6df2b3cde14d144af8d82f2dd47a7a7b752cdfecd5b9238b16fe47aeb23af1b0767707d99bb48138bedc97df43cd61e9d023ceed + languageName: node + linkType: hard + "@react-types/switch@npm:^3.5.16": version: 3.5.16 resolution: "@react-types/switch@npm:3.5.16" @@ -6371,6 +6928,18 @@ __metadata: languageName: node linkType: hard +"@react-types/table@npm:^3.13.6": + version: 3.13.6 + resolution: "@react-types/table@npm:3.13.6" + dependencies: + "@react-types/grid": "npm:^3.3.8" + "@react-types/shared": "npm:^3.33.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/32a8e88376050e7c8396f39cda8b81c02a27b7ffa0d4c47cadd52c00e24ea74c681002f63a811904a48414d6ffd199c074b2cf738eeef5c6b61170d3e158b0b5 + languageName: node + linkType: hard + "@react-types/tabs@npm:^3.3.21": version: 3.3.21 resolution: "@react-types/tabs@npm:3.3.21" @@ -6382,6 +6951,17 @@ __metadata: languageName: node linkType: hard +"@react-types/tabs@npm:^3.3.22": + version: 3.3.22 + resolution: "@react-types/tabs@npm:3.3.22" + dependencies: + "@react-types/shared": "npm:^3.33.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/b2318b580e3cf4a13918129424fd6f72ad7836e4244d9bb0f437462045a1b3b602b8eb341b1e1b5f20fb63ac5f9a59f6960167706157fbc950371fc260b4ded6 + languageName: node + linkType: hard + "@react-types/textfield@npm:^3.12.7": version: 3.12.7 resolution: "@react-types/textfield@npm:3.12.7" @@ -6393,6 +6973,17 @@ __metadata: languageName: node linkType: hard +"@react-types/textfield@npm:^3.12.8": + version: 3.12.8 + resolution: "@react-types/textfield@npm:3.12.8" + dependencies: + "@react-types/shared": "npm:^3.33.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/9cebea13054ad7f191770b66a5aed35f627c4e5a4d1ac8163304a452f16254357cbf5fb51f0beafce4d770ea45526cc4311371a428ad709c9e50f8795ee18e6d + languageName: node + linkType: hard + "@react-types/tooltip@npm:^3.5.1": version: 3.5.1 resolution: "@react-types/tooltip@npm:3.5.1" @@ -6405,6 +6996,18 @@ __metadata: languageName: node linkType: hard +"@react-types/tooltip@npm:^3.5.2": + version: 3.5.2 + resolution: "@react-types/tooltip@npm:3.5.2" + dependencies: + "@react-types/overlays": "npm:^3.9.4" + "@react-types/shared": "npm:^3.33.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/d94fd3102e69f459b4d67c561ee9306e9f2cec4456b868a668bf6448a22ac8df8b97d8e349903d9d664d6dfebc4acc29c824f8026e65a15a9abf851d54e7f810 + languageName: node + linkType: hard + "@rollup/plugin-babel@npm:^6.0.4": version: 6.0.4 resolution: "@rollup/plugin-babel@npm:6.0.4" @@ -21787,39 +22390,39 @@ __metadata: languageName: node linkType: hard -"react-stately@npm:^3.44.0": - version: 3.44.0 - resolution: "react-stately@npm:3.44.0" - dependencies: - "@react-stately/calendar": "npm:^3.9.2" - "@react-stately/checkbox": "npm:^3.7.4" - "@react-stately/collections": "npm:^3.12.9" - "@react-stately/color": "npm:^3.9.4" - "@react-stately/combobox": "npm:^3.12.2" - "@react-stately/data": "npm:^3.15.1" - "@react-stately/datepicker": "npm:^3.16.0" - "@react-stately/disclosure": "npm:^3.0.10" - "@react-stately/dnd": "npm:^3.7.3" - "@react-stately/form": "npm:^3.2.3" - "@react-stately/list": "npm:^3.13.3" - "@react-stately/menu": "npm:^3.9.10" - "@react-stately/numberfield": "npm:^3.10.4" - "@react-stately/overlays": "npm:^3.6.22" - "@react-stately/radio": "npm:^3.11.4" - "@react-stately/searchfield": "npm:^3.5.18" - "@react-stately/select": "npm:^3.9.1" - "@react-stately/selection": "npm:^3.20.8" - "@react-stately/slider": "npm:^3.7.4" - "@react-stately/table": "npm:^3.15.3" - "@react-stately/tabs": "npm:^3.8.8" +"react-stately@npm:^3.36.1": + version: 3.45.0 + resolution: "react-stately@npm:3.45.0" + dependencies: + "@react-stately/calendar": "npm:^3.9.3" + "@react-stately/checkbox": "npm:^3.7.5" + "@react-stately/collections": "npm:^3.12.10" + "@react-stately/color": "npm:^3.9.5" + "@react-stately/combobox": "npm:^3.13.0" + "@react-stately/data": "npm:^3.15.2" + "@react-stately/datepicker": "npm:^3.16.1" + "@react-stately/disclosure": "npm:^3.0.11" + "@react-stately/dnd": "npm:^3.7.4" + "@react-stately/form": "npm:^3.2.4" + "@react-stately/list": "npm:^3.13.4" + "@react-stately/menu": "npm:^3.9.11" + "@react-stately/numberfield": "npm:^3.11.0" + "@react-stately/overlays": "npm:^3.6.23" + "@react-stately/radio": "npm:^3.11.5" + "@react-stately/searchfield": "npm:^3.5.19" + "@react-stately/select": "npm:^3.9.2" + "@react-stately/selection": "npm:^3.20.9" + "@react-stately/slider": "npm:^3.7.5" + "@react-stately/table": "npm:^3.15.4" + "@react-stately/tabs": "npm:^3.8.9" "@react-stately/toast": "npm:^3.1.3" - "@react-stately/toggle": "npm:^3.9.4" - "@react-stately/tooltip": "npm:^3.5.10" - "@react-stately/tree": "npm:^3.9.5" - "@react-types/shared": "npm:^3.33.0" + "@react-stately/toggle": "npm:^3.9.5" + "@react-stately/tooltip": "npm:^3.5.11" + "@react-stately/tree": "npm:^3.9.6" + "@react-types/shared": "npm:^3.33.1" peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/0476362742d729033fc3fe5f601c587605d2374cd44adadeee77b9d476791c20f5879473f3bcbeccc5c1fcae6c7d424d7bebbdc1828a1792e0a42e667b4ded46 + checksum: 10c0/847d614e15d9928160664680707e885398f7b0d7d73e966edab821dec1a4abe55fe909c51a02b674aa4d75397028cb3c024bfc5d5201f01f346686b0503ba233 languageName: node linkType: hard From 5d81f2e59e53a8032f9cde6a8e99cdc8127782ed Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Wed, 4 Mar 2026 15:39:54 -0500 Subject: [PATCH 33/35] fix --- yarn.lock | 675 ++++-------------------------------------------------- 1 file changed, 44 insertions(+), 631 deletions(-) diff --git a/yarn.lock b/yarn.lock index 2c517c3125f..a93e7bde513 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2602,16 +2602,7 @@ __metadata: languageName: node linkType: hard -"@internationalized/date@npm:^3.11.0, @internationalized/date@npm:^3.7.0": - version: 3.11.0 - resolution: "@internationalized/date@npm:3.11.0" - dependencies: - "@swc/helpers": "npm:^0.5.0" - checksum: 10c0/05dfa06806cb0c58c51a99ae3ccae2eebeafb645f8d55f2956b448db21996b9eef61c3da0f8b2256e76cd457bfd0efd1ef62f987e547d75611c2fb6ae3dd2bef - languageName: node - linkType: hard - -"@internationalized/date@npm:^3.12.0": +"@internationalized/date@npm:^3.11.0, @internationalized/date@npm:^3.12.0, @internationalized/date@npm:^3.7.0": version: 3.12.0 resolution: "@internationalized/date@npm:3.12.0" dependencies: @@ -5619,24 +5610,7 @@ __metadata: languageName: node linkType: hard -"@react-aria/utils@npm:^3.28.1, @react-aria/utils@npm:^3.28.2, @react-aria/utils@npm:^3.33.0": - version: 3.33.0 - resolution: "@react-aria/utils@npm:3.33.0" - dependencies: - "@react-aria/ssr": "npm:^3.9.10" - "@react-stately/flags": "npm:^3.1.2" - "@react-stately/utils": "npm:^3.11.0" - "@react-types/shared": "npm:^3.33.0" - "@swc/helpers": "npm:^0.5.0" - clsx: "npm:^2.0.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/15e9c79102632f96c611ca10ce5a3436617f1b3979ca7b4be192cf4c65c74871edb66c72bdbcedaeeaa6498d04947184d5bccf29a2a36a28eff89c3d55d9d1ca - languageName: node - linkType: hard - -"@react-aria/utils@npm:^3.33.1": +"@react-aria/utils@npm:^3.28.1, @react-aria/utils@npm:^3.28.2, @react-aria/utils@npm:^3.33.0, @react-aria/utils@npm:^3.33.1": version: 3.33.1 resolution: "@react-aria/utils@npm:3.33.1" dependencies: @@ -5697,22 +5671,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/calendar@npm:^3.9.2": - version: 3.9.2 - resolution: "@react-stately/calendar@npm:3.9.2" - dependencies: - "@internationalized/date": "npm:^3.11.0" - "@react-stately/utils": "npm:^3.11.0" - "@react-types/calendar": "npm:^3.8.2" - "@react-types/shared": "npm:^3.33.0" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/d910836573b6088a25bef3f503b9977980c0a11feccacff08a41f8402b510255b0d26d524db63733875f25ef5e192aa6a5fbebc6e34129dbe0e4b0714ff96162 - languageName: node - linkType: hard - -"@react-stately/calendar@npm:^3.9.3": +"@react-stately/calendar@npm:^3.9.2, @react-stately/calendar@npm:^3.9.3": version: 3.9.3 resolution: "@react-stately/calendar@npm:3.9.3" dependencies: @@ -5727,22 +5686,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/checkbox@npm:^3.7.4": - version: 3.7.4 - resolution: "@react-stately/checkbox@npm:3.7.4" - dependencies: - "@react-stately/form": "npm:^3.2.3" - "@react-stately/utils": "npm:^3.11.0" - "@react-types/checkbox": "npm:^3.10.3" - "@react-types/shared": "npm:^3.33.0" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/2a87a0160ed50954886dce3635be62b085edd86eac3c508f34ad019411e2848fe103ae1c44a3b2e8c22eb38df80ceabc8583b7496fe4f842df681df14ef0c44a - languageName: node - linkType: hard - -"@react-stately/checkbox@npm:^3.7.5": +"@react-stately/checkbox@npm:^3.7.4, @react-stately/checkbox@npm:^3.7.5": version: 3.7.5 resolution: "@react-stately/checkbox@npm:3.7.5" dependencies: @@ -5757,7 +5701,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/collections@npm:^3.12.10": +"@react-stately/collections@npm:^3.12.10, @react-stately/collections@npm:^3.12.9": version: 3.12.10 resolution: "@react-stately/collections@npm:3.12.10" dependencies: @@ -5769,38 +5713,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/collections@npm:^3.12.9": - version: 3.12.9 - resolution: "@react-stately/collections@npm:3.12.9" - dependencies: - "@react-types/shared": "npm:^3.33.0" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/d7e68eaf89a2b79c73fbf7437d32f65a2d65bf59123bcb896176132652c020490d7187e52aff22169b033fefde4c728b4bb89a224e0061618c00d84ae0f373b6 - languageName: node - linkType: hard - -"@react-stately/color@npm:^3.9.4": - version: 3.9.4 - resolution: "@react-stately/color@npm:3.9.4" - dependencies: - "@internationalized/number": "npm:^3.6.5" - "@internationalized/string": "npm:^3.2.7" - "@react-stately/form": "npm:^3.2.3" - "@react-stately/numberfield": "npm:^3.10.4" - "@react-stately/slider": "npm:^3.7.4" - "@react-stately/utils": "npm:^3.11.0" - "@react-types/color": "npm:^3.1.3" - "@react-types/shared": "npm:^3.33.0" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/30ee71641bcc9e8c2a03ce443b7ca694659626292110a4146f52fa8619f10e74ba0dc59ed3c35d0e33bb47c649915ca9d79280989c2e2ff3fe196ea27736cf44 - languageName: node - linkType: hard - -"@react-stately/color@npm:^3.9.5": +"@react-stately/color@npm:^3.9.4, @react-stately/color@npm:^3.9.5": version: 3.9.5 resolution: "@react-stately/color@npm:3.9.5" dependencies: @@ -5819,25 +5732,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/combobox@npm:^3.10.3, @react-stately/combobox@npm:^3.12.2": - version: 3.12.2 - resolution: "@react-stately/combobox@npm:3.12.2" - dependencies: - "@react-stately/collections": "npm:^3.12.9" - "@react-stately/form": "npm:^3.2.3" - "@react-stately/list": "npm:^3.13.3" - "@react-stately/overlays": "npm:^3.6.22" - "@react-stately/utils": "npm:^3.11.0" - "@react-types/combobox": "npm:^3.13.11" - "@react-types/shared": "npm:^3.33.0" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/e5fef62e7dd4502a695ae6158d3afe2047036da2b8974e34d0021e4220b6028571f6c0dbf49616f5258147cf250bd231a1be622f04c5be19004fdc0898125474 - languageName: node - linkType: hard - -"@react-stately/combobox@npm:^3.13.0": +"@react-stately/combobox@npm:^3.10.3, @react-stately/combobox@npm:^3.12.2, @react-stately/combobox@npm:^3.13.0": version: 3.13.0 resolution: "@react-stately/combobox@npm:3.13.0" dependencies: @@ -5867,26 +5762,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/datepicker@npm:^3.16.0": - version: 3.16.0 - resolution: "@react-stately/datepicker@npm:3.16.0" - dependencies: - "@internationalized/date": "npm:^3.11.0" - "@internationalized/number": "npm:^3.6.5" - "@internationalized/string": "npm:^3.2.7" - "@react-stately/form": "npm:^3.2.3" - "@react-stately/overlays": "npm:^3.6.22" - "@react-stately/utils": "npm:^3.11.0" - "@react-types/datepicker": "npm:^3.13.4" - "@react-types/shared": "npm:^3.33.0" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/37da44a664284b06730e141b033d9d2128803c97191e7f72a1e50b7f204d52f6e4ee4d310a4d2a59f0d3e838b334adb1d4b57e9008e5670d5ed4222ba4d44a00 - languageName: node - linkType: hard - -"@react-stately/datepicker@npm:^3.16.1": +"@react-stately/datepicker@npm:^3.16.0, @react-stately/datepicker@npm:^3.16.1": version: 3.16.1 resolution: "@react-stately/datepicker@npm:3.16.1" dependencies: @@ -5905,20 +5781,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/disclosure@npm:^3.0.10": - version: 3.0.10 - resolution: "@react-stately/disclosure@npm:3.0.10" - dependencies: - "@react-stately/utils": "npm:^3.11.0" - "@react-types/shared": "npm:^3.33.0" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/acfc0346f5503b8693dabd145fc2eff36f59eb140f7a0cadd956ab102453bdf1dd63503fe9611106b6b4348d85be3b29c5ab1f743945148dcd23d518035f7dbb - languageName: node - linkType: hard - -"@react-stately/disclosure@npm:^3.0.11": +"@react-stately/disclosure@npm:^3.0.10, @react-stately/disclosure@npm:^3.0.11": version: 3.0.11 resolution: "@react-stately/disclosure@npm:3.0.11" dependencies: @@ -5931,20 +5794,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/dnd@npm:^3.7.3": - version: 3.7.3 - resolution: "@react-stately/dnd@npm:3.7.3" - dependencies: - "@react-stately/selection": "npm:^3.20.8" - "@react-types/shared": "npm:^3.33.0" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/a6ef1cfe1ba0335837462f57fbe5dac637a861945b9f958e875dd8ad440312e10dd93df3c2740cff93106bc20d1e1145c881e4fc8ec947b135d0133b23af5b94 - languageName: node - linkType: hard - -"@react-stately/dnd@npm:^3.7.4": +"@react-stately/dnd@npm:^3.7.3, @react-stately/dnd@npm:^3.7.4": version: 3.7.4 resolution: "@react-stately/dnd@npm:3.7.4" dependencies: @@ -5966,19 +5816,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/form@npm:^3.2.3": - version: 3.2.3 - resolution: "@react-stately/form@npm:3.2.3" - dependencies: - "@react-types/shared": "npm:^3.33.0" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/bfab5e15a9b3080a0bcf0a65d3e37aba561ec78a9aebb3ce7eeed52bec72def2b3db82ec51bf60f1f453b7a116b240350c37ae7fa9c9042cac3b5a73296daf59 - languageName: node - linkType: hard - -"@react-stately/form@npm:^3.2.4": +"@react-stately/form@npm:^3.2.3, @react-stately/form@npm:^3.2.4": version: 3.2.4 resolution: "@react-stately/form@npm:3.2.4" dependencies: @@ -5990,22 +5828,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/grid@npm:^3.11.8": - version: 3.11.8 - resolution: "@react-stately/grid@npm:3.11.8" - dependencies: - "@react-stately/collections": "npm:^3.12.9" - "@react-stately/selection": "npm:^3.20.8" - "@react-types/grid": "npm:^3.3.7" - "@react-types/shared": "npm:^3.33.0" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/1f7ebe345c3621abc81374cf0429f070a02d49d461a702ef2419f7f827f3de4827d742a441efe7de3f617bbcbac664bfb7bdf2e2c015275a986537f8f928f3d4 - languageName: node - linkType: hard - -"@react-stately/grid@npm:^3.11.9": +"@react-stately/grid@npm:^3.11.8, @react-stately/grid@npm:^3.11.9": version: 3.11.9 resolution: "@react-stately/grid@npm:3.11.9" dependencies: @@ -6038,22 +5861,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/list@npm:^3.13.3": - version: 3.13.3 - resolution: "@react-stately/list@npm:3.13.3" - dependencies: - "@react-stately/collections": "npm:^3.12.9" - "@react-stately/selection": "npm:^3.20.8" - "@react-stately/utils": "npm:^3.11.0" - "@react-types/shared": "npm:^3.33.0" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/790bc56513dcef53678509f134e9aecc04051ffdc37961b8d51f5ca7628f05d854438716d54a8ebcd26b93488628a8b0f6b7b952bf147cadacbfe2b1ac210662 - languageName: node - linkType: hard - -"@react-stately/list@npm:^3.13.4": +"@react-stately/list@npm:^3.13.3, @react-stately/list@npm:^3.13.4": version: 3.13.4 resolution: "@react-stately/list@npm:3.13.4" dependencies: @@ -6068,21 +5876,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/menu@npm:^3.9.10": - version: 3.9.10 - resolution: "@react-stately/menu@npm:3.9.10" - dependencies: - "@react-stately/overlays": "npm:^3.6.22" - "@react-types/menu": "npm:^3.10.6" - "@react-types/shared": "npm:^3.33.0" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/937d16c769f8fcea94060d530e1238f96a50262621ee05afdfeeb1a18771b0ae04ae5d1fadaa1dd7718f4ae9006f286eb6ebe329bf5068bad8f196af813e5ad9 - languageName: node - linkType: hard - -"@react-stately/menu@npm:^3.9.11": +"@react-stately/menu@npm:^3.9.10, @react-stately/menu@npm:^3.9.11": version: 3.9.11 resolution: "@react-stately/menu@npm:3.9.11" dependencies: @@ -6096,22 +5890,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/numberfield@npm:^3.10.4": - version: 3.10.4 - resolution: "@react-stately/numberfield@npm:3.10.4" - dependencies: - "@internationalized/number": "npm:^3.6.5" - "@react-stately/form": "npm:^3.2.3" - "@react-stately/utils": "npm:^3.11.0" - "@react-types/numberfield": "npm:^3.8.17" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/7a6635a823ca7c03064c3b65e99d1122e1851f0e88795542da6a7b27198269d6aec764daffa0b97da57af1fc6bd202bf5f9cfd6ac26e8a209b7a717e1e707c0f - languageName: node - linkType: hard - -"@react-stately/numberfield@npm:^3.11.0": +"@react-stately/numberfield@npm:^3.10.4, @react-stately/numberfield@npm:^3.11.0": version: 3.11.0 resolution: "@react-stately/numberfield@npm:3.11.0" dependencies: @@ -6126,20 +5905,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/overlays@npm:^3.6.22": - version: 3.6.22 - resolution: "@react-stately/overlays@npm:3.6.22" - dependencies: - "@react-stately/utils": "npm:^3.11.0" - "@react-types/overlays": "npm:^3.9.3" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/c5da7009c5cba86c852e438a334d3e8fcc17021ec8d4fd5d82135ffb83e19929f97bf12f0b038911af648e3207307e461b332952fa38abd9c82d4adee833f2c8 - languageName: node - linkType: hard - -"@react-stately/overlays@npm:^3.6.23": +"@react-stately/overlays@npm:^3.6.22, @react-stately/overlays@npm:^3.6.23": version: 3.6.23 resolution: "@react-stately/overlays@npm:3.6.23" dependencies: @@ -6152,22 +5918,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/radio@npm:^3.11.4": - version: 3.11.4 - resolution: "@react-stately/radio@npm:3.11.4" - dependencies: - "@react-stately/form": "npm:^3.2.3" - "@react-stately/utils": "npm:^3.11.0" - "@react-types/radio": "npm:^3.9.3" - "@react-types/shared": "npm:^3.33.0" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/ee31fd738d0c0913a4393479e8064af14439aac7e8f05f7b3042cf9ddf30e5ca138258209b3b33909b21574a6a9b051871bfcfd4b1a8311841e3f2ce26a03660 - languageName: node - linkType: hard - -"@react-stately/radio@npm:^3.11.5": +"@react-stately/radio@npm:^3.11.4, @react-stately/radio@npm:^3.11.5": version: 3.11.5 resolution: "@react-stately/radio@npm:3.11.5" dependencies: @@ -6182,20 +5933,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/searchfield@npm:^3.5.18": - version: 3.5.18 - resolution: "@react-stately/searchfield@npm:3.5.18" - dependencies: - "@react-stately/utils": "npm:^3.11.0" - "@react-types/searchfield": "npm:^3.6.7" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/3fab036b4461bd6748e8e9bd17456e7908b76e1df4349f2ee34d426cf3f4ce7b6ff8266078eec3d29485beeb8d89d4426bfbc4e3613442eb489fb0f2867f70cd - languageName: node - linkType: hard - -"@react-stately/searchfield@npm:^3.5.19": +"@react-stately/searchfield@npm:^3.5.18, @react-stately/searchfield@npm:^3.5.19": version: 3.5.19 resolution: "@react-stately/searchfield@npm:3.5.19" dependencies: @@ -6208,24 +5946,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/select@npm:^3.9.1": - version: 3.9.1 - resolution: "@react-stately/select@npm:3.9.1" - dependencies: - "@react-stately/form": "npm:^3.2.3" - "@react-stately/list": "npm:^3.13.3" - "@react-stately/overlays": "npm:^3.6.22" - "@react-stately/utils": "npm:^3.11.0" - "@react-types/select": "npm:^3.12.1" - "@react-types/shared": "npm:^3.33.0" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/4104bb87a0a1efc377c67c675b85aa3b568b43025d0f36aed3494d7ecacc07b35574b5df2f5d2e2b39d23de3eb9391eb0d674ed520658bee96d1780df2168148 - languageName: node - linkType: hard - -"@react-stately/select@npm:^3.9.2": +"@react-stately/select@npm:^3.9.1, @react-stately/select@npm:^3.9.2": version: 3.9.2 resolution: "@react-stately/select@npm:3.9.2" dependencies: @@ -6242,21 +5963,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/selection@npm:^3.20.0, @react-stately/selection@npm:^3.20.8": - version: 3.20.8 - resolution: "@react-stately/selection@npm:3.20.8" - dependencies: - "@react-stately/collections": "npm:^3.12.9" - "@react-stately/utils": "npm:^3.11.0" - "@react-types/shared": "npm:^3.33.0" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/8127e2adf3b96591e5ec31abcf3ca998da3f111306beec809d08675d5c563cfc6fc012b8b7570d8c5794d656e7049a8613663b0596430ddaf37dba2048ad71ac - languageName: node - linkType: hard - -"@react-stately/selection@npm:^3.20.9": +"@react-stately/selection@npm:^3.20.0, @react-stately/selection@npm:^3.20.8, @react-stately/selection@npm:^3.20.9": version: 3.20.9 resolution: "@react-stately/selection@npm:3.20.9" dependencies: @@ -6270,21 +5977,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/slider@npm:^3.7.4": - version: 3.7.4 - resolution: "@react-stately/slider@npm:3.7.4" - dependencies: - "@react-stately/utils": "npm:^3.11.0" - "@react-types/shared": "npm:^3.33.0" - "@react-types/slider": "npm:^3.8.3" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/a8fe1ed9f5144e2b66a9ce58d38d624511e5db6bbd9dec2cb9051b08caac8f17b60f614643ef82f50dd2f4aa1bb13f0e19c7700cce344db5f0d71abb57e76d75 - languageName: node - linkType: hard - -"@react-stately/slider@npm:^3.7.5": +"@react-stately/slider@npm:^3.7.4, @react-stately/slider@npm:^3.7.5": version: 3.7.5 resolution: "@react-stately/slider@npm:3.7.5" dependencies: @@ -6298,26 +5991,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/table@npm:^3.14.0, @react-stately/table@npm:^3.15.3": - version: 3.15.3 - resolution: "@react-stately/table@npm:3.15.3" - dependencies: - "@react-stately/collections": "npm:^3.12.9" - "@react-stately/flags": "npm:^3.1.2" - "@react-stately/grid": "npm:^3.11.8" - "@react-stately/selection": "npm:^3.20.8" - "@react-stately/utils": "npm:^3.11.0" - "@react-types/grid": "npm:^3.3.7" - "@react-types/shared": "npm:^3.33.0" - "@react-types/table": "npm:^3.13.5" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/691625eea3b3fc4014a4e1f18149d717ee9907473bca80e742944740fb5ca2317b6be6a58eaabca670765cdb7be2a543a9a3b094fc1fa3c0f66f9d57b16bf80f - languageName: node - linkType: hard - -"@react-stately/table@npm:^3.15.4": +"@react-stately/table@npm:^3.14.0, @react-stately/table@npm:^3.15.3, @react-stately/table@npm:^3.15.4": version: 3.15.4 resolution: "@react-stately/table@npm:3.15.4" dependencies: @@ -6336,21 +6010,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/tabs@npm:^3.8.8": - version: 3.8.8 - resolution: "@react-stately/tabs@npm:3.8.8" - dependencies: - "@react-stately/list": "npm:^3.13.3" - "@react-types/shared": "npm:^3.33.0" - "@react-types/tabs": "npm:^3.3.21" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/8e43e4fdbe57ac7ba4bc7be4b6757207f87301f253b5335c4736be230a1206975213c5aa3141903c9e2739e5638c76f33e22d7842e2a2e3998f65566b39341eb - languageName: node - linkType: hard - -"@react-stately/tabs@npm:^3.8.9": +"@react-stately/tabs@npm:^3.8.8, @react-stately/tabs@npm:^3.8.9": version: 3.8.9 resolution: "@react-stately/tabs@npm:3.8.9" dependencies: @@ -6376,21 +6036,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/toggle@npm:^3.9.4": - version: 3.9.4 - resolution: "@react-stately/toggle@npm:3.9.4" - dependencies: - "@react-stately/utils": "npm:^3.11.0" - "@react-types/checkbox": "npm:^3.10.3" - "@react-types/shared": "npm:^3.33.0" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/b4fc62204f1399a3a4da1918909a2632aad19f0ccf7e4169c47245878150ae1fe3e8a0cf1c690e29e82a1d9c54d0998b7070c2b57cd4eb41e6205973727aa85d - languageName: node - linkType: hard - -"@react-stately/toggle@npm:^3.9.5": +"@react-stately/toggle@npm:^3.9.4, @react-stately/toggle@npm:^3.9.5": version: 3.9.5 resolution: "@react-stately/toggle@npm:3.9.5" dependencies: @@ -6404,20 +6050,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/tooltip@npm:^3.5.10": - version: 3.5.10 - resolution: "@react-stately/tooltip@npm:3.5.10" - dependencies: - "@react-stately/overlays": "npm:^3.6.22" - "@react-types/tooltip": "npm:^3.5.1" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/3d73aa49044f0e48ff0d0f30157638dac8df18347dcc7effcb6ecfa50885bdadad37550bfc4facc37211b9b06e05518cc1f451b4fb09c1c70b09549cbb85dcc3 - languageName: node - linkType: hard - -"@react-stately/tooltip@npm:^3.5.11": +"@react-stately/tooltip@npm:^3.5.10, @react-stately/tooltip@npm:^3.5.11": version: 3.5.11 resolution: "@react-stately/tooltip@npm:3.5.11" dependencies: @@ -6430,22 +6063,7 @@ __metadata: languageName: node linkType: hard -"@react-stately/tree@npm:^3.9.5": - version: 3.9.5 - resolution: "@react-stately/tree@npm:3.9.5" - dependencies: - "@react-stately/collections": "npm:^3.12.9" - "@react-stately/selection": "npm:^3.20.8" - "@react-stately/utils": "npm:^3.11.0" - "@react-types/shared": "npm:^3.33.0" - "@swc/helpers": "npm:^0.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/2d9acb2d7172bacac9aefabeb01cbf47c8539bea7e57c81ff6d09a4bc501f9f297e2e63bb35d4a9abe2cfccd536400555d23f13dd4aa476af19be1d60bc50870 - languageName: node - linkType: hard - -"@react-stately/tree@npm:^3.9.6": +"@react-stately/tree@npm:^3.9.5, @react-stately/tree@npm:^3.9.6": version: 3.9.6 resolution: "@react-stately/tree@npm:3.9.6" dependencies: @@ -6520,19 +6138,7 @@ __metadata: languageName: node linkType: hard -"@react-types/calendar@npm:^3.8.2": - version: 3.8.2 - resolution: "@react-types/calendar@npm:3.8.2" - dependencies: - "@internationalized/date": "npm:^3.11.0" - "@react-types/shared": "npm:^3.33.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/e7944b60c798563666cf6b35fdf347e6048ef238fe3016095f2e7283791599cc471dbbc6cb20bb83e46fc230f8ea064340ec33727569e2dcae7d8e9fc3f6c729 - languageName: node - linkType: hard - -"@react-types/calendar@npm:^3.8.3": +"@react-types/calendar@npm:^3.8.2, @react-types/calendar@npm:^3.8.3": version: 3.8.3 resolution: "@react-types/calendar@npm:3.8.3" dependencies: @@ -6544,18 +6150,7 @@ __metadata: languageName: node linkType: hard -"@react-types/checkbox@npm:^3.10.3": - version: 3.10.3 - resolution: "@react-types/checkbox@npm:3.10.3" - dependencies: - "@react-types/shared": "npm:^3.33.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/eb1015176671fadf451cfb2b91df0f8d6391f0d08b0257d90100f5a7262426734335607615f04db3ee07f6d83df9067559969e821e43f9e7184e65a543db7d0a - languageName: node - linkType: hard - -"@react-types/checkbox@npm:^3.10.4": +"@react-types/checkbox@npm:^3.10.3, @react-types/checkbox@npm:^3.10.4": version: 3.10.4 resolution: "@react-types/checkbox@npm:3.10.4" dependencies: @@ -6566,19 +6161,7 @@ __metadata: languageName: node linkType: hard -"@react-types/color@npm:^3.1.3": - version: 3.1.3 - resolution: "@react-types/color@npm:3.1.3" - dependencies: - "@react-types/shared": "npm:^3.33.0" - "@react-types/slider": "npm:^3.8.3" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/8bc783d3adbcd18426926156248bb9decf916abd5fef9b97ad8c5ef8efbf4371c3c3277315aba2b3daab17598fd627dce5eefa87b86a668a5f91ec68596369cf - languageName: node - linkType: hard - -"@react-types/color@npm:^3.1.4": +"@react-types/color@npm:^3.1.3, @react-types/color@npm:^3.1.4": version: 3.1.4 resolution: "@react-types/color@npm:3.1.4" dependencies: @@ -6590,18 +6173,7 @@ __metadata: languageName: node linkType: hard -"@react-types/combobox@npm:^3.13.11, @react-types/combobox@npm:^3.13.3": - version: 3.13.11 - resolution: "@react-types/combobox@npm:3.13.11" - dependencies: - "@react-types/shared": "npm:^3.33.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/8b704943d603fb8fcc9055cb10559677c578e9872f9e9084e3bc7f2dc9ede24ac09582b3ff8da645b77d0cabd302c994e85ce1d1e15d0b3f7d09f070c8eb00b0 - languageName: node - linkType: hard - -"@react-types/combobox@npm:^3.14.0": +"@react-types/combobox@npm:^3.13.11, @react-types/combobox@npm:^3.13.3, @react-types/combobox@npm:^3.14.0": version: 3.14.0 resolution: "@react-types/combobox@npm:3.14.0" dependencies: @@ -6612,21 +6184,7 @@ __metadata: languageName: node linkType: hard -"@react-types/datepicker@npm:^3.13.4": - version: 3.13.4 - resolution: "@react-types/datepicker@npm:3.13.4" - dependencies: - "@internationalized/date": "npm:^3.11.0" - "@react-types/calendar": "npm:^3.8.2" - "@react-types/overlays": "npm:^3.9.3" - "@react-types/shared": "npm:^3.33.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/2f716c97a8a8662f311e951f94bbcee69ac902341b24a2a682535c40cbce105e93819f1995a9eefeb25a7d1610ab112cd7ac85658bb73c9f608240c18f675bbc - languageName: node - linkType: hard - -"@react-types/datepicker@npm:^3.13.5": +"@react-types/datepicker@npm:^3.13.4, @react-types/datepicker@npm:^3.13.5": version: 3.13.5 resolution: "@react-types/datepicker@npm:3.13.5" dependencies: @@ -6663,18 +6221,7 @@ __metadata: languageName: node linkType: hard -"@react-types/grid@npm:^3.3.0, @react-types/grid@npm:^3.3.7": - version: 3.3.7 - resolution: "@react-types/grid@npm:3.3.7" - dependencies: - "@react-types/shared": "npm:^3.33.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/cc153cc08bf564e12f04c51b3456bfcd3393f2ea361b6f35cf70a41100f3261dc86825842e50b3c6d84fe01944285717eeff002ed67a4dffd429c1e74ab0f41c - languageName: node - linkType: hard - -"@react-types/grid@npm:^3.3.8": +"@react-types/grid@npm:^3.3.0, @react-types/grid@npm:^3.3.7, @react-types/grid@npm:^3.3.8": version: 3.3.8 resolution: "@react-types/grid@npm:3.3.8" dependencies: @@ -6707,19 +6254,7 @@ __metadata: languageName: node linkType: hard -"@react-types/menu@npm:^3.10.6": - version: 3.10.6 - resolution: "@react-types/menu@npm:3.10.6" - dependencies: - "@react-types/overlays": "npm:^3.9.3" - "@react-types/shared": "npm:^3.33.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/15960881debe12f37918a9aa04f26f44b2c31df3c6aa81e3208fd97b3a67050de4c4af42a18cdf69e8e281744d58a1739d5d38c105d93db5a5bf476202163911 - languageName: node - linkType: hard - -"@react-types/menu@npm:^3.10.7": +"@react-types/menu@npm:^3.10.6, @react-types/menu@npm:^3.10.7": version: 3.10.7 resolution: "@react-types/menu@npm:3.10.7" dependencies: @@ -6742,18 +6277,7 @@ __metadata: languageName: node linkType: hard -"@react-types/numberfield@npm:^3.8.17": - version: 3.8.17 - resolution: "@react-types/numberfield@npm:3.8.17" - dependencies: - "@react-types/shared": "npm:^3.33.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/cf6227d3a67ec7f927c70db9f4c188612e263f28190b718a9f8b68cff60937c39dfcf8422ad23555659ef25508bd7a52989c87d012c54afacf39318ead324ba1 - languageName: node - linkType: hard - -"@react-types/numberfield@npm:^3.8.18": +"@react-types/numberfield@npm:^3.8.17, @react-types/numberfield@npm:^3.8.18": version: 3.8.18 resolution: "@react-types/numberfield@npm:3.8.18" dependencies: @@ -6764,18 +6288,7 @@ __metadata: languageName: node linkType: hard -"@react-types/overlays@npm:^3.9.3": - version: 3.9.3 - resolution: "@react-types/overlays@npm:3.9.3" - dependencies: - "@react-types/shared": "npm:^3.33.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/e7dde940ba785d3995f87641f2b67e502f2090fa8fdef508db1f81c052f4822df608b8bc6ae91dd270ba6055cdf7d8f0e6585c8deb2d34537fb7c8eae7d3099a - languageName: node - linkType: hard - -"@react-types/overlays@npm:^3.9.4": +"@react-types/overlays@npm:^3.9.3, @react-types/overlays@npm:^3.9.4": version: 3.9.4 resolution: "@react-types/overlays@npm:3.9.4" dependencies: @@ -6797,18 +6310,7 @@ __metadata: languageName: node linkType: hard -"@react-types/radio@npm:^3.9.3": - version: 3.9.3 - resolution: "@react-types/radio@npm:3.9.3" - dependencies: - "@react-types/shared": "npm:^3.33.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/9074145535712bddeadd7e8ffa3ef51bb6606e0aa752fafd401257c7f0f8b0314bf61b30cb776b3eabda70a8a6d1d479f8a346eb529c022dda147b27a73dbe02 - languageName: node - linkType: hard - -"@react-types/radio@npm:^3.9.4": +"@react-types/radio@npm:^3.9.3, @react-types/radio@npm:^3.9.4": version: 3.9.4 resolution: "@react-types/radio@npm:3.9.4" dependencies: @@ -6819,19 +6321,7 @@ __metadata: languageName: node linkType: hard -"@react-types/searchfield@npm:^3.6.0, @react-types/searchfield@npm:^3.6.7": - version: 3.6.7 - resolution: "@react-types/searchfield@npm:3.6.7" - dependencies: - "@react-types/shared": "npm:^3.33.0" - "@react-types/textfield": "npm:^3.12.7" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/8ef81774d98054fc7efdf68f225692d453da5b21e97d6dd088c007edb0be0167ab3010b9c2c17796dde848ce51fd5c492c5989c770d46d26fe904cbefc3aaf92 - languageName: node - linkType: hard - -"@react-types/searchfield@npm:^3.6.8": +"@react-types/searchfield@npm:^3.6.0, @react-types/searchfield@npm:^3.6.7, @react-types/searchfield@npm:^3.6.8": version: 3.6.8 resolution: "@react-types/searchfield@npm:3.6.8" dependencies: @@ -6843,18 +6333,7 @@ __metadata: languageName: node linkType: hard -"@react-types/select@npm:^3.12.1": - version: 3.12.1 - resolution: "@react-types/select@npm:3.12.1" - dependencies: - "@react-types/shared": "npm:^3.33.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/9706fd1bbd68a113995c35339ae8d7dfaf47a370dae7ddc8244422dc72c345c9c2adbbc2b08e7755747579bc438d68a096a74afc2fb8975e1ca84947f10d9aa4 - languageName: node - linkType: hard - -"@react-types/select@npm:^3.12.2": +"@react-types/select@npm:^3.12.1, @react-types/select@npm:^3.12.2": version: 3.12.2 resolution: "@react-types/select@npm:3.12.2" dependencies: @@ -6865,16 +6344,7 @@ __metadata: languageName: node linkType: hard -"@react-types/shared@npm:^3.28.0, @react-types/shared@npm:^3.29.0, @react-types/shared@npm:^3.33.0": - version: 3.33.0 - resolution: "@react-types/shared@npm:3.33.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/159758a91b5ecbf028651b07c54972f557716f52f6d31e03a581c5a6b694453a7ceb1272f4b82e03b99cb00780e6f0829624d57ac9b83189f296436dc768b956 - languageName: node - linkType: hard - -"@react-types/shared@npm:^3.33.1": +"@react-types/shared@npm:^3.28.0, @react-types/shared@npm:^3.29.0, @react-types/shared@npm:^3.33.0, @react-types/shared@npm:^3.33.1": version: 3.33.1 resolution: "@react-types/shared@npm:3.33.1" peerDependencies: @@ -6883,18 +6353,7 @@ __metadata: languageName: node linkType: hard -"@react-types/slider@npm:^3.8.3": - version: 3.8.3 - resolution: "@react-types/slider@npm:3.8.3" - dependencies: - "@react-types/shared": "npm:^3.33.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/93656c42a9c56779363c050f13bd88abe59958c93dc43caef6ebc5193a9a6320c56108ede022e869741b430716ef632ffc2498fa25a4854124a39aa8c8cd65b3 - languageName: node - linkType: hard - -"@react-types/slider@npm:^3.8.4": +"@react-types/slider@npm:^3.8.3, @react-types/slider@npm:^3.8.4": version: 3.8.4 resolution: "@react-types/slider@npm:3.8.4" dependencies: @@ -6916,19 +6375,7 @@ __metadata: languageName: node linkType: hard -"@react-types/table@npm:^3.11.0, @react-types/table@npm:^3.13.5": - version: 3.13.5 - resolution: "@react-types/table@npm:3.13.5" - dependencies: - "@react-types/grid": "npm:^3.3.7" - "@react-types/shared": "npm:^3.33.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/a19e1cf38903baa9549f37f6f2331b035ef5606ec7767313949b555ee9e21466ee8aec1384c70d92484a2aefbad6b91029f72699430d0be1ee2b3ae43abd9e87 - languageName: node - linkType: hard - -"@react-types/table@npm:^3.13.6": +"@react-types/table@npm:^3.11.0, @react-types/table@npm:^3.13.5, @react-types/table@npm:^3.13.6": version: 3.13.6 resolution: "@react-types/table@npm:3.13.6" dependencies: @@ -6940,18 +6387,7 @@ __metadata: languageName: node linkType: hard -"@react-types/tabs@npm:^3.3.21": - version: 3.3.21 - resolution: "@react-types/tabs@npm:3.3.21" - dependencies: - "@react-types/shared": "npm:^3.33.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/e4b02a4c77d4e57d67541cfc38ed55b3ce683d84074237c720879bed5d12f7e8631d606aa552237feab622cc7edc0a4b176983bf8053547215231323b32886c0 - languageName: node - linkType: hard - -"@react-types/tabs@npm:^3.3.22": +"@react-types/tabs@npm:^3.3.21, @react-types/tabs@npm:^3.3.22": version: 3.3.22 resolution: "@react-types/tabs@npm:3.3.22" dependencies: @@ -6962,18 +6398,7 @@ __metadata: languageName: node linkType: hard -"@react-types/textfield@npm:^3.12.7": - version: 3.12.7 - resolution: "@react-types/textfield@npm:3.12.7" - dependencies: - "@react-types/shared": "npm:^3.33.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/6e644519a6a6eb1d00fe83a92508596079131042c48406439cd32c359c0d3a70cc309e6530a7c1b51c8f4b477cb6e4d5aa13810c242597fd470f73031c7c80de - languageName: node - linkType: hard - -"@react-types/textfield@npm:^3.12.8": +"@react-types/textfield@npm:^3.12.7, @react-types/textfield@npm:^3.12.8": version: 3.12.8 resolution: "@react-types/textfield@npm:3.12.8" dependencies: @@ -6984,19 +6409,7 @@ __metadata: languageName: node linkType: hard -"@react-types/tooltip@npm:^3.5.1": - version: 3.5.1 - resolution: "@react-types/tooltip@npm:3.5.1" - dependencies: - "@react-types/overlays": "npm:^3.9.3" - "@react-types/shared": "npm:^3.33.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/cf563a16bfece724ec32d5d344f1221a16256ef07c6b83d0b673ec443e6ac22218b05cb11ad351b6082286feb139a72e38ef34625941992c6b0c993966aeb31e - languageName: node - linkType: hard - -"@react-types/tooltip@npm:^3.5.2": +"@react-types/tooltip@npm:^3.5.1, @react-types/tooltip@npm:^3.5.2": version: 3.5.2 resolution: "@react-types/tooltip@npm:3.5.2" dependencies: From da007c0f93071a748b70b947d348bd73c3de1017 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Fri, 13 Mar 2026 15:41:56 -0400 Subject: [PATCH 34/35] target ref --- .eslintrc.js | 14 ++++++++++++++ packages/gamut/package.json | 3 ++- .../src/Form/SelectDropdown/types/internal.ts | 3 +-- packages/gamut/src/PopoverContainer/types.ts | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 57cafb693f5..d4a59c9d81f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -94,5 +94,19 @@ module.exports = { 'no-plusplus': 'off', }, }, + { + files: ['*.ts', '*.tsx', '*.js', '*.jsx'], + rules: { + 'no-restricted-syntax': [ + 'error', + { + selector: + "MemberExpression[object.type='Identifier'][object.name='JSX']", + message: + 'Use React.JSX.* instead of global JSX namespace for React 19 compatibility.', + }, + ], + }, + }, ], }; diff --git a/packages/gamut/package.json b/packages/gamut/package.json index 556bf2d7f81..2f503db24cd 100644 --- a/packages/gamut/package.json +++ b/packages/gamut/package.json @@ -51,7 +51,8 @@ "build": "nx build @codecademy/gamut", "build:watch": "yarn build && onchange ./src -- yarn build", "compile": "babel ./src --out-dir ./dist --extensions \".ts,.tsx\"", - "verify": "tsc --noEmit" + "verify": "tsc --noEmit", + "verify:react19": "tsc --noEmit" }, "sideEffects": [ "**/*.css", diff --git a/packages/gamut/src/Form/SelectDropdown/types/internal.ts b/packages/gamut/src/Form/SelectDropdown/types/internal.ts index 8a151e2102c..1a23971023c 100644 --- a/packages/gamut/src/Form/SelectDropdown/types/internal.ts +++ b/packages/gamut/src/Form/SelectDropdown/types/internal.ts @@ -18,8 +18,7 @@ export type InternalSelectProps = { * Used for managing focus on select input and remove all button. */ export type ProgramaticFocusRef = - | React.MutableRefObject - | React.MutableRefObject; + React.MutableRefObject; /** * Context value for SelectDropdown internal state management. diff --git a/packages/gamut/src/PopoverContainer/types.ts b/packages/gamut/src/PopoverContainer/types.ts index 2c14f860579..e573ddf2313 100644 --- a/packages/gamut/src/PopoverContainer/types.ts +++ b/packages/gamut/src/PopoverContainer/types.ts @@ -82,7 +82,7 @@ export interface PopoverContainerProps /** * The target element around which the popover will be positioned. */ - targetRef: RefObject; + targetRef: RefObject; /** * If true, it will allow outside page interaction. Popover container will still close when clicking outside of the popover or hitting the escape key. */ From b8f7d4e583ea9ab320b42d1145b22f6342a761dc Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Fri, 13 Mar 2026 17:46:03 -0400 Subject: [PATCH 35/35] test connectedform type fix --- packages/gamut/src/ConnectedForm/ConnectedForm.tsx | 7 +++---- packages/gamut/src/Form/SelectDropdown/types/internal.ts | 3 +-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/gamut/src/ConnectedForm/ConnectedForm.tsx b/packages/gamut/src/ConnectedForm/ConnectedForm.tsx index a645a6c6b67..df9e77fcd6d 100644 --- a/packages/gamut/src/ConnectedForm/ConnectedForm.tsx +++ b/packages/gamut/src/ConnectedForm/ConnectedForm.tsx @@ -84,13 +84,12 @@ export interface ConnectedFormProps /** * Explicit type for the ConnectedForm component so that declaration emission - * preserves the generic (Values) for consumers. Without this, forwardRef - * would be inferred as any and the .d.ts would lose onSubmit/onError types. + * preserves the generic (Values) for consumers. Single-argument signature + * matches React 18/19 createElement(type, props); ref is passed via props.ref. */ export interface ConnectedFormComponent { >( - props: ConnectedFormProps, - ref: React.ForwardedRef + props: ConnectedFormProps & React.RefAttributes ): React.ReactElement; } diff --git a/packages/gamut/src/Form/SelectDropdown/types/internal.ts b/packages/gamut/src/Form/SelectDropdown/types/internal.ts index 1a23971023c..43ec3a2ab19 100644 --- a/packages/gamut/src/Form/SelectDropdown/types/internal.ts +++ b/packages/gamut/src/Form/SelectDropdown/types/internal.ts @@ -17,8 +17,7 @@ export type InternalSelectProps = { * Ref type for programmatic focus management. * Used for managing focus on select input and remove all button. */ -export type ProgramaticFocusRef = - React.MutableRefObject; +export type ProgramaticFocusRef = React.MutableRefObject; /** * Context value for SelectDropdown internal state management.