Draft
Conversation
e9e30f2 to
8633f4d
Compare
Phase 1 — Tooling upgrades: - TypeScript 4 → 5.8.3, typescript-plugin-styled-components 1 → 3 - ts-jest 26 → 29, Jest 26 → 29, @types/jest 25 → 29 - Add jest-environment-jsdom (Jest 29 no longer defaults to jsdom) - eslint 7 → 8, @typescript-eslint v4 → v7, eslint-plugin-unicorn/jest/airbnb-typescript - jest.config.js: add testEnvironment jsdom, ts-jest tuple transform format - .eslintrc.js: rename recommended-requiring-type-checking → recommended-type-checked - src/utils/testing.ts: update jest-dom import path (extend-expect removed in v6) - Build scripts: ttsc → tsc (ttypescript incompatible with TS5) Phase 2 — React 19.2.4: - react/react-dom 18.2.0 → 19.2.4, @types/react v18 → v19 - @testing-library/react v14 → v16, jest-dom v5 → v6 - peerDependencies broadened to ^18.2.0 || ^19.0.0 for library consumers - overrides: react-refresh 0.14.2, react-is 19.2.4, windowed-select types Phase 3 — Remove defaultProps (removed in React 19 for FC/forwardRef): - Styled-components (Button, TextButton, HelperText, Label, experimental/Text): defaultProps → .attrs<Props>({...}) - Function components (Checkbox, Modal, SelectList): defaultProps → destructuring defaults - forwardRef components (Input, InnerInput): defaultProps → destructuring defaults Phase 4 — TypeScript type fixes for @types/react@19: - JSX global namespace removed: JSX.Element → React.JSX.Element (Breadcrumbs, TabBar/Link, Tooltip, DateField, DatePicker, Calendar, InfoBannerCard, experimental/Tooltip, withDeprecatedMessage, LabelWrapper) - ReactDOM.findDOMNode removed: add nodeRef to all CSSTransition usages (Banner, Modal×2, Offcanvas×3) using react-transition-group v4 nodeRef API - useRef<T>() requires arg: → useRef<T | null>(null) (Password, PhoneInput, DatepickerRangeInput, InnerInput) - Render-prop functions no longer assignable to ReactNode: Chip: remove unnecessary Fragment wrapper RadioButton: narrow children type to ReactNode via Omit - React.cloneElement stricter typing: cast to HTMLAttributes & RefAttributes (Tooltip) Storybook fix: - @storybook/react-dom-shim preset only enables createRoot shim for React 18 (version.startsWith("18")). React 19 falls through to legacy react-16.js shim which calls ReactDOM.render() — removed in React 19. - Fix: webpackFinal alias in .storybook/main.ts forces react-18 shim (createRoot) which is fully compatible with React 19. Result: 58/58 test suites pass, build succeeds, tsc --noEmit clean, Storybook renders correctly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Use useDarkMode() from storybook-dark-mode in withColorScheme decorator (works in Storybook preview hook context, same as main branch) - Fix docs.container dark mode using React hooks + addons.getChannel() to subscribe to DARK_MODE_EVENT_NAME, avoiding storybook preview-api hooks which throw outside decorator/story context - Add missing ESLint plugins (import, react, react-hooks, jsx-a11y) to plugins array so ESLint 8 correctly resolves rules from extended configs - Disable newly-triggered strict rules that fire on pre-existing code - Fix no-floating-promises in useLocaleObject.ts - Upgrade pretty-quick v3 to v4 for Prettier v3 compatibility - Fix commit-msg hook for Husky v9 (use --edit $1 instead of HUSKY_GIT_PARAMS) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix type-only exports across all components (export type {}) for
Vite/esbuild compatibility
- Add import type for all type-only imports (ESLint consistent-type-imports)
- Add @vite-ignore to dynamic imports in Flag.tsx and useLocaleObject.ts
- Fix CSSTransition nodeRef for React 19 (Modal, Offcanvas, Banner)
- Fix React 19 breaking changes: defaultProps, JSX namespace, useRef types,
ReactNode functions, cloneElement typing
- Migrate react-popper to @floating-ui/react for Popover and Tooltip
- Update date-fns v3 locale dynamic imports
- Add Husky v9 pre-commit hook
- Update jscodeshift v17 codemod type casts
- Add UPGRADE_PLAN.md documenting all migration phases
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
8633f4d to
99646eb
Compare
… warnings - Replace legacy .eslintrc.js with ESLint 10 flat config (eslint.config.mjs) - Remove unmaintained eslint-config-airbnb-typescript; replace with typescript-eslint unified package + @eslint-react/eslint-plugin - Add eslint-plugin-import-x (maintained fork), globals, eslint-import-resolver-typescript - Fix all 14 ESLint errors: conditional hooks, missing keys, leaked conditional rendering, stale disable comments, array sort, autofocus, prefer-ternary - Fix 56 of 103 warnings: lazy useState init, ref naming convention, import naming, forwardRef (turned off for React 18+19 compat), complex dep-array expressions extracted to variables - Bump tsconfig.json lib to es2023 (required for Array#toSorted) - Add UPGRADE_PLAN_2026.md with 10-phase upgrade plan Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Upgrade styled-components ^5.3.8 → ^6.3.12; remove @types/styled-components (v6 ships own types) - Add shouldForwardProp: isPropValid to all styled HTML element components to restore v5 prop-filtering behavior (Box, Text, Headline, Button, Card, Link, Table, TabBar, Skeleton, Input, Select, Banner, Tag, Breadcrumbs, Datepicker, Popover, and more) - Fix removed v6 types: StyledComponent→IStyledComponent, drop GlobalStyleComponent and ThemeProps, ReadonlyArray<string>→string[], use RuleSet for css return type - Fix react-select components: replace styled(components.X) wrappers with inner styled divs to prevent theme-prop stripping (SingleValue, Option, DynamicWidthMenu) - Update snapshots for stylis v4 CSS output (fewer vendor prefixes, gradient formatting) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Bump typescript devDep to ^6.0.2 - Add ignoreDeprecations: "6.0" to tsconfig for node10 moduleResolution deprecation - Exclude src/codemods entirely from tsconfig type-checking (uses Node.js globals) - Add src/global.d.ts for CSS module, warning, @styled-system/theme-get, and process declarations TS6 breaking changes fixed across ~55 files: - Implicit-any now enforced (TS7053/TS7006): typed object index expressions, callback params - Optional callbacks require optional-chaining invocation (TS2722) - React.createContext default value must match generic type - useRef<T>(null) → RefObject<T | null>, requiring casts for useDay library compatibility - FocusedInput null vs undefined strictness in @datepicker-react/hooks - String indexing on typed objects requires keyof typeof cast - Boolean coercion required for mixed-type setHasValue calls - isValidDateText updated to accept Date | undefined - SelectList triggerReference typed as HTMLDivElement | null with explicit callback ref - Tooltip: fix potential leaked conditional rendering Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove ignoreDeprecations workaround by fixing all deprecated features: - tsconfig.json: moduleResolution "node" → "bundler" (correct for a bundler-consumed library; avoids node16/nodenext requirement for explicit .js import extensions) - package.json build:cjs: --target es5 → --target es2015 (ES5 target deprecated in TS6; consumers use bundlers that handle transpilation anyway) - SelectList.tsx/styles.ts: fix size > 0 comparisons (size is 'medium'|'small', not a number; previously type errors were masked, now correctly use truthiness checks) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
moduleResolution "bundler" requires module to be "esnext" or "preserve". Without an explicit module setting, TypeScript defaults to CommonJS which is incompatible. The build scripts override --module on the CLI anyway, so this only affects IDE type-checking. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
No config changes required — Storybook manages Vite internally. Storybook 8 starts cleanly with Vite 8, library build unaffected. Node ≥20.19 required by Vite 7+; running Node 24.13.1. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s in SelectList Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nd @types/node v22 Root causes: - moduleResolution: "bundler" couldn't resolve jscodeshift/dist/testUtils (no exports field) - @types/node v22 removed CJS globals (__dirname, module) from global scope Fix: - Add tsconfig.jest.json with moduleResolution: "node" + module: "commonjs" for codemods - Add src/codemods/global.d.ts declaring __dirname, __filename, jscodeshift/dist/testUtils - Split jest.config.js into two projects: components (jsdom) and codemods (node, diagnostics off) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…se 10) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
36c4f59 to
6d99c6e
Compare
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…e dead babel/stylelint configs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Re-add storybook-dark-mode@5.0.0 (compatible with storybook@^10.0.0) - Restore useDarkMode() hook in withColorScheme decorator - Restore channel-based dark mode tracking in docs container - Restore darkMode parameters with lightClass/darkClass/stylePreview - Fix preview background by using CSS variable directly on wrapper div instead of relying on background:inherit through EnforcedColorScheme - Remove custom manager.ts (was for native colorScheme global approach) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…o Node 24
- ESLint config: add parserOptions blocks for .storybook/, docs/, scripts/;
disableTypeChecked for root JS/MJS config files; ignore .github/, storybook-static/
- tsconfig.eslint.json: add rootDir='.', noEmit=true, fix .storybook glob pattern
- Convert import styled from 'styled-components' to named import { styled }
across 120+ files (v6 exports styled as named export)
- Breadcrumbs: replace deprecated Children.toArray/map/cloneElement with plain array map
- useOnChange: replace useState+useEffect anti-pattern with useRef for prev value
- Modal, Offcanvas: wrap handleClose in useCallback, add to effect deps
- Fix missing exhaustive-deps across Search, MonthRangePicker, useMutationObserver,
DatepickerRangeInput, DatepickerSingleInput, DatePicker (experimental)
- Add eslint-disable comments with explanations for intentional set-state-in-effect
patterns (datepicker sync, input label float, color scheme sync, popover gate)
- Delete stale generated JS files: .storybook/main.js, preview.js,
docs/components/*.js, docs/components/migration/*.js
- package.json: add npm overrides for @csstools/css-tokenizer and
@csstools/css-parser-algorithms to fix Jest jsdom module resolution (hoisting bug)
- package.json: update lint:eslint script to eslint . (full project)
- CI: upgrade docs.yml from Node 18 to 24, gh-pages v3 to v4
- CI: add node-version 24 + cache npm to preview.yml (was missing entirely)
- CI: add --legacy-peer-deps to all npm ci install steps
- CI: add timeout-minutes and explicit permissions to all jobs
- CI: enable preview template in preview.yml (package is React 19 compatible)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
commit: |
commit: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Media
Why
How