Compare commits

...

15 Commits

Author SHA1 Message Date
Mehmet Salih Yavuz
d7f4a6b0e2 style: prettier formatting for the React 19 changes 2026-07-16 18:35:16 +03:00
Mehmet Salih Yavuz
cc450b91bb fix: keep user-event 12 call sites and move the ReactText alias
The local ReactText alias (React 19 removed the type) sat between imports,
tripping oxlint's import/first — move it below them.

Restore userEvent.paste(element, text) in two tests: they had been migrated
to user-event 14's one-argument signature, and the v14 bump is not part of
this branch.
2026-07-16 18:35:07 +03:00
Mehmet Salih Yavuz
ec5bd3eba1 test: adapt AG Grid tests to React 19; keep user-event at 12
React 19 commits AG Grid's rows/header after the initial render rather than
during it, so assertions that read the DOM synchronously after render() now
wait for the grid. The grid itself renders fine — only the timing moved.

React 19 also passes ref as a regular prop instead of a second argument, so
ThemedAgGridReact asserts on the props object rather than the call arity.

Drop the @testing-library/user-event 14 bump: it is not required (12.8.3
already peers @testing-library/dom >=7.21.4, which dom 10 satisfies) and v14's
async API would silently break ~1000 sync call sites across the suite. RTL 16
+ dom 10 are kept, which is what React 19 actually needs.
2026-07-16 14:47:52 +03:00
Mehmet Salih Yavuz
c786adbc01 fix(types): React 19 type errors against current master
Re-derived on top of master's refactors (the original per-file fixes were
written before those files were rewritten):

- JSX.Element -> ReactElement (React 19 drops the global JSX namespace)
- useRef() -> useRef(null) where React 19 now requires an initial value
- RefObject<T> -> RefObject<T | null> on props fed by useRef(null)
- ReactElement<P> where element.props is now unknown
- ConnectDragSource cast to Ref, matching the existing Column.tsx convention
- dropzoneReducer: drop the default param so useReducer infers non-optional state
- SaveModal/ScheduleQueryButton: use master's ModalTriggerRef API
- SliceHeaderControls: metaKey click via fireEvent (user-event 14 drops the
  event-init argument)
2026-07-16 14:28:24 +03:00
Mehmet Salih Yavuz
e012349eaf fix(superset-ui-core): restore reactify defaultProps + WeakValidationMap under React 19
React 19 ignores defaultProps on function/forwardRef components, so
reactify silently dropped the defaults declared on renderFn. Merge them
explicitly using React's own rule (default applies only where the prop is
undefined).

React 19 also removed WeakValidationMap from its type exports; redefine it
locally from prop-types' Validator.
2026-07-16 14:11:01 +03:00
Mehmet Salih Yavuz
51a03144ec chore: transform ESM-only deps for jest
react-resize-detector (bumped to 12 for React 19), react-markdown, vfile and
friends ship ESM only, so babel-jest has to transform them.
2026-07-16 14:03:37 +03:00
Mehmet Salih Yavuz
1da86f26f7 fix(types): final round of React 19 type errors
- Type cloneElement targets with explicit ReactElement<Props> for
  CopyToClipboard, DrillDetailPane, TabsRenderer, ControlRow
- Update ResizePayload mock in MetadataBar test for v12 onResize API
- userEvent v14: paste(text) replaces paste(el, text) — focus first
- ListView filtersRef now accepts nullable inner type
- ExploreContainer useReducer cast to declared dispatch tuple
- Replace Tabs defaultProps test with a behavioural rendering check
- Cast Storybook story functions to FC in tests (storybook 8 sig change)
2026-07-16 14:02:46 +03:00
Mehmet Salih Yavuz
c4aa582ad1 fix(types): React 19 RefObject<T> -> RefObject<T | null>
React 19 made RefObject<T> require a non-null T. useRef returns
RefObject<T | null>. Widen prop type annotations across the codebase so
consumers accept the new shape. Also remove leftover unused ReactElement
imports from the JSX namespace migration.
2026-07-16 14:02:34 +03:00
Mehmet Salih Yavuz
b727ee180f fix(types): more React 19 type fixes
- AutoSizer: revert to v1 (v2 changes children API significantly,
  defer to a follow-up)
- ModalTrigger: split ModalTriggerImperativeApi (handle shape) from
  ModalTriggerRef (RefObject); update consumers
- Replace ReactChild (removed in React 19) with ReactNode
- d3-scale typing: cast createLinearScale results to include never extras
- Various cloneElement consumers typed with proper ReactElement<Props>
2026-07-16 14:01:45 +03:00
Mehmet Salih Yavuz
83051f8aee fix(types): React 19 element.props is unknown — type ReactElement<P>
Update consumers that read element.props in:
- ag-grid-table CustomPopover/CustomHeader (typed cloneElement targets)
- deckgl DeckGLContainer / common (isCustomTooltip)
- echart Refs/getEchartInstance return shape
- Drop ReactText (removed in React 19); declare local alias
- Type DatePicker.RangePicker explicitly to avoid portability issue
2026-07-16 14:00:27 +03:00
Mehmet Salih Yavuz
a35952269c fix(superset-ui-core): React 19 type errors in components/hooks
- Type cloneElement/Children consumers with explicit ReactElement<Props>
  (React 19 narrowed element.props from any to unknown)
- Update useResizeDetector onResize callbacks for v12 ResizePayload shape
- useRef nullable types in useElementOnScreen and useCSSTextTruncation
2026-07-16 14:00:27 +03:00
Mehmet Salih Yavuz
644ae87081 fix(types): React 19 JSX namespace, useRef, and createLoadableRenderer
- Replace JSX.Element with ReactElement (JSX namespace no longer global)
- useRef<T>() -> useRef<T | null>(null) (React 19 requires initial value)
- Drop WeakValidationMap import (removed in React 19); declare local version
- Update createLoadableRenderer typings to be JSX-component compatible
- Loosen LoadingProps error type to unknown
2026-07-16 13:59:22 +03:00
Mehmet Salih Yavuz
be9dc1fb27 refactor: migrate defaultProps to default destructuring on function components
React 19 ignores defaultProps on function components silently. Move
defaults into function parameter destructuring (MetricsControl,
EditableTabs/EditableTabPane in superset-ui-core/Tabs). Drop the
redundant TableRenderer.defaultProps in pivot-table — PivotData already
applies its own defaults internally. Class component defaultProps are
left intact (still supported).
2026-07-16 13:58:01 +03:00
Mehmet Salih Yavuz
3221b6f893 fix: small React 19 API compatibility fixes
- Switch `act` imports from react-dom/test-utils to react
- Replace `useRef() as ModalTriggerRef` with proper typed initial value
- Update useReducer generic signature from legacy Reducer<S, A> to <S, [A]>
2026-07-16 13:57:16 +03:00
Mehmet Salih Yavuz
2b67d225dc chore(deps): bump react ecosystem to 19
- Update react, react-dom, @types/react, @types/react-dom to ^19.2.0
- Update package/plugin peer deps to "^18.2.0 || ^19.0.0"
- Add overrides for react-router-dom, react-table, react-ultimate-pagination,
  @visx/*, @great-expectations/jsonforms-antd-renderers to allow React 19
- Bump @testing-library/react ^14 -> ^16, @testing-library/dom ^9 -> ^10,
  @testing-library/user-event ^12 -> ^14
- Bump react-redux 7 -> 9 (drop @types/react-redux; types bundled)
- Bump redux 4 -> 5, redux-thunk 2 -> 3, @reduxjs/toolkit 1 -> 2
- Bump react-resize-detector 9 -> 12, react-virtualized-auto-sizer 1 -> 2,
  react-checkbox-tree 1 -> 2, react-arborist 3.5 -> 3.6
- Bump react-error-boundary, react-markdown, react-ace to React 19-compatible versions
- Move react out of dependencies in legacy-plugin-chart-chord to peerDependencies
2026-07-16 13:56:32 +03:00
177 changed files with 1081 additions and 831 deletions

View File

@@ -17,7 +17,14 @@
* under the License.
*/
import { useState, useEffect, useCallback, useRef, ReactNode } from 'react';
import {
useState,
useEffect,
useCallback,
useRef,
ReactNode,
type ReactElement,
} from 'react';
import { t } from '@apache-superset/core/translation';
import {
SupersetClient,
@@ -54,7 +61,7 @@ export default function VerifyCORS({
host,
method,
postPayload,
}: Props): JSX.Element {
}: Props): ReactElement {
const [didVerify, setDidVerify] = useState(false);
const [error, setError] = useState<Error | SupersetApiError | undefined>(
undefined,

View File

@@ -75,7 +75,7 @@ module.exports = {
// @ant-design/colors and @ant-design/fast-color are allowed through because
// @ant-design/icons >= 6.3 deep-imports the ESM build of @ant-design/colors
// from its CJS output, so babel-jest must transform those files.
'node_modules/(?!@ant-design/(colors|fast-color)|@formatjs/.*|d3-(array|interpolate|color|time|scale|time-format|format)|internmap|@mapbox/tiny-sdf|remark-gfm|(?!@ngrx|(?!deck.gl)|d3-scale)|markdown-table|micromark-*.|decode-named-character-reference|character-entities|mdast-util-*.|unist-util-*.|ccount|escape-string-regexp|nanoid|uuid|@rjsf/*.|@x0k/.*|echarts|zrender|fetch-mock|pretty-ms|parse-ms|ol|@babel/runtime|@emotion|cheerio|cheerio/lib|parse5|dom-serializer|entities|htmlparser2|rehype-sanitize|hast-util-sanitize|unified|unist-.*|hast-.*|rehype-.*|remark-.*|mdast-.*|micromark-.*|parse-entities|property-information|space-separated-tokens|comma-separated-tokens|bail|devlop|zwitch|longest-streak|geostyler|geostyler-.*|(?!geostyler)lodash|react-error-boundary|react-json-tree|react-base16-styling|lodash-es|rbush|quickselect|react-diff-viewer-continued|storybook/*.|json-stringify-pretty-compact)',
'node_modules/(?!@ant-design/(colors|fast-color)|@formatjs/.*|d3-(array|interpolate|color|time|scale|time-format|format)|internmap|@mapbox/tiny-sdf|remark-gfm|(?!@ngrx|(?!deck.gl)|d3-scale)|markdown-table|micromark-*.|decode-named-character-reference|character-entities|mdast-util-*.|unist-util-*.|ccount|escape-string-regexp|nanoid|uuid|@rjsf/*.|@x0k/.*|echarts|zrender|fetch-mock|pretty-ms|parse-ms|ol|@babel/runtime|@emotion|cheerio|cheerio/lib|parse5|dom-serializer|entities|htmlparser2|rehype-sanitize|hast-util-sanitize|unified|unist-.*|hast-.*|rehype-.*|remark-.*|mdast-.*|micromark-.*|parse-entities|property-information|space-separated-tokens|comma-separated-tokens|bail|devlop|zwitch|longest-streak|geostyler|geostyler-.*|(?!geostyler)lodash|react-error-boundary|react-json-tree|react-base16-styling|lodash-es|rbush|quickselect|react-diff-viewer-continued|storybook/*.|json-stringify-pretty-compact|react-resize-detector|react-markdown|vfile|vfile-message|trim-lines|trough|is-plain-obj)',
],
preset: 'ts-jest',
transform: {

View File

@@ -120,20 +120,19 @@
"ol": "^10.9.0",
"query-string": "9.4.1",
"re-resizable": "^6.11.2",
"react": "^18.3.0",
"react": "^19.2.0",
"react-arborist": "^3.13.2",
"react-checkbox-tree": "^1.8.0",
"react-checkbox-tree": "^2.0.1",
"react-diff-viewer-continued": "^4.2.2",
"react-dnd": "^11.1.3",
"react-dnd-html5-backend": "^11.1.3",
"react-dom": "^18.3.0",
"react-dom": "^19.2.0",
"react-google-recaptcha": "^3.1.0",
"react-intersection-observer": "^10.0.3",
"react-json-tree": "^0.20.0",
"react-lines-ellipsis": "^0.16.1",
"react-loadable": "^5.5.0",
"react-redux": "^7.2.9",
"react-resize-detector": "^9.1.1",
"react-resize-detector": "^12.3.0",
"react-reverse-portal": "^2.3.0",
"react-router-dom": "^5.3.4",
"react-search-input": "^0.11.3",
@@ -190,9 +189,9 @@
"@swc/core": "^1.15.43",
"@swc/plugin-emotion": "^14.15.0",
"@swc/plugin-transform-imports": "^12.5.0",
"@testing-library/dom": "^9.3.4",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^14.0.0",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^12.8.3",
"@types/content-disposition": "^0.5.9",
"@types/dom-to-image": "^2.6.7",
@@ -203,10 +202,9 @@
"@types/lodash-es": "^4.17.12",
"@types/mousetrap": "^1.6.15",
"@types/node": "^26.1.1",
"@types/react": "^18.3.0",
"@types/react-dom": "^18.3.0",
"@types/react-loadable": "^5.5.11",
"@types/react-redux": "^7.1.10",
"@types/react": "^19.2.0",
"@types/react-dom": "^19.2.0",
"@types/react-redux": "^7.1.34",
"@types/react-router-dom": "^5.3.3",
"@types/react-transition-group": "^4.4.12",
"@types/react-window": "^1.8.8",
@@ -300,7 +298,7 @@
"ace-builds": "^1.41.0",
"core-js": "^3.38.1",
"handlebars": "^4.7.8",
"react-ace": "^10.1.0",
"react-ace": "^14.0.1",
"regenerator-runtime": "^0.14.1"
}
},
@@ -6728,13 +6726,15 @@
}
},
"node_modules/@noble/hashes": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz",
"integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.2.0.tgz",
"integrity": "sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">= 16"
"node": ">= 20.19.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
@@ -8569,9 +8569,6 @@
"arm64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -8589,9 +8586,6 @@
"arm64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -8609,9 +8603,6 @@
"ppc64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -8629,9 +8620,6 @@
"riscv64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -8649,9 +8637,6 @@
"riscv64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -8669,9 +8654,6 @@
"s390x"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -8689,9 +8671,6 @@
"x64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -8709,9 +8688,6 @@
"x64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -11380,22 +11356,31 @@
}
},
"node_modules/@testing-library/dom": {
"version": "9.3.4",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz",
"integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==",
"version": "10.4.1",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz",
"integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.10.4",
"@babel/runtime": "^7.12.5",
"@types/aria-query": "^5.0.1",
"aria-query": "5.1.3",
"chalk": "^4.1.0",
"aria-query": "5.3.0",
"dom-accessibility-api": "^0.5.9",
"lz-string": "^1.5.0",
"picocolors": "1.1.1",
"pretty-format": "^27.0.2"
},
"engines": {
"node": ">=14"
"node": ">=18"
}
},
"node_modules/@testing-library/dom/node_modules/aria-query": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
"integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
"license": "Apache-2.0",
"dependencies": {
"dequal": "^2.0.3"
}
},
"node_modules/@testing-library/jest-dom": {
@@ -11424,21 +11409,30 @@
"license": "MIT"
},
"node_modules/@testing-library/react": {
"version": "14.3.1",
"resolved": "https://registry.npmjs.org/@testing-library/react/-/react-14.3.1.tgz",
"integrity": "sha512-H99XjUhWQw0lTgyMN05W3xQG1Nh4lq574D8keFf1dDoNTJgp66VbJozRaczoF+wsiaPJNt/TcnfpLGufGxSrZQ==",
"version": "16.3.2",
"resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.2.tgz",
"integrity": "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@testing-library/dom": "^9.0.0",
"@types/react-dom": "^18.0.0"
"@babel/runtime": "^7.12.5"
},
"engines": {
"node": ">=14"
"node": ">=18"
},
"peerDependencies": {
"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
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@testing-library/user-event": {
@@ -12314,6 +12308,7 @@
"version": "15.7.15",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
"integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/qs": {
@@ -12344,22 +12339,21 @@
"license": "MIT"
},
"node_modules/@types/react": {
"version": "18.3.28",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.28.tgz",
"integrity": "sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==",
"version": "19.2.17",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz",
"integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==",
"license": "MIT",
"dependencies": {
"@types/prop-types": "*",
"csstype": "^3.2.2"
}
},
"node_modules/@types/react-dom": {
"version": "18.3.7",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
"integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
"version": "19.2.3",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
"license": "MIT",
"peerDependencies": {
"@types/react": "^18.0.0"
"@types/react": "^19.2.0"
}
},
"node_modules/@types/react-google-recaptcha": {
@@ -12371,20 +12365,11 @@
"@types/react": "*"
}
},
"node_modules/@types/react-loadable": {
"version": "5.5.11",
"resolved": "https://registry.npmjs.org/@types/react-loadable/-/react-loadable-5.5.11.tgz",
"integrity": "sha512-/tq2IJ853MoIFRBmqVOxnGsRRjER5TmEKzsZtaAkiXAWoDeKgR/QNOT1vd9k0p9h/F616X21cpNh3hu4RutzRQ==",
"license": "MIT",
"dependencies": {
"@types/react": "*",
"@types/webpack": "^4"
}
},
"node_modules/@types/react-loadable/node_modules/@types/webpack": {
"version": "4.41.40",
"resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.40.tgz",
"integrity": "sha512-u6kMFSBM9HcoTpUXnL6mt2HSzftqb3JgYV6oxIgL2dl6sX6aCa5k6SOkzv5DuZjBTPUE/dJltKtwwuqrkZHpfw==",
"extraneous": true,
"license": "MIT",
"dependencies": {
"@types/node": "*",
@@ -12399,6 +12384,7 @@
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"extraneous": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
@@ -12580,12 +12566,6 @@
"@types/node": "*"
}
},
"node_modules/@types/source-list-map": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.6.tgz",
"integrity": "sha512-5JcVt1u5HDmlXkwOD2nslZVllBBc7HDuOICfiZah2Z0is8M8g+ddAEawbmd3VjedfDHBzxCaXLs07QEmb7y54g==",
"license": "MIT"
},
"node_modules/@types/stack-utils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
@@ -12602,12 +12582,6 @@
"@types/geojson": "*"
}
},
"node_modules/@types/tapable": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.12.tgz",
"integrity": "sha512-bTHG8fcxEqv1M9+TD14P8ok8hjxoOCkfKc8XXLaaD05kI7ohpeI956jtDOD3XHKBQrlyPughUtzm1jtVhHpA5Q==",
"license": "MIT"
},
"node_modules/@types/tinycolor2": {
"version": "1.4.6",
"resolved": "https://registry.npmjs.org/@types/tinycolor2/-/tinycolor2-1.4.6.tgz",
@@ -12628,24 +12602,6 @@
"license": "MIT",
"optional": true
},
"node_modules/@types/uglify-js": {
"version": "3.17.5",
"resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.17.5.tgz",
"integrity": "sha512-TU+fZFBTBcXj/GpDpDaBmgWk/gn96kMZ+uocaFUlV2f8a6WdMzzI44QBCmGcCiYR0Y6ZlNRiyUyKKt5nl/lbzQ==",
"license": "MIT",
"dependencies": {
"source-map": "^0.6.1"
}
},
"node_modules/@types/uglify-js/node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/@types/underscore": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.13.0.tgz",
@@ -12697,17 +12653,6 @@
"@types/node": "*"
}
},
"node_modules/@types/webpack-sources": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-3.2.3.tgz",
"integrity": "sha512-4nZOdMwSPHZ4pTEZzSp0AsTM4K7Qmu40UKW4tJDiOVs20UzYF9l+qUe4s0ftfN0pin06n+5cWWDJXH+sbhAiDw==",
"license": "MIT",
"dependencies": {
"@types/node": "*",
"@types/source-list-map": "*",
"source-map": "^0.7.3"
}
},
"node_modules/@types/yargs": {
"version": "17.0.33",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
@@ -14552,6 +14497,7 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"dev": true,
"license": "ISC",
"dependencies": {
"normalize-path": "^3.0.0",
@@ -16181,6 +16127,7 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
@@ -19310,6 +19257,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/es-toolkit": {
"version": "1.49.0",
"resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.49.0.tgz",
"integrity": "sha512-G5iZ6Pc/FNRY/soKZHC+TxGDD83rHUDXxzaWhGCX44vAv/tMs56WMusnm/KMNK+luUPsgA9U28cGr4RDlSzL2g==",
"license": "MIT",
"workspaces": [
"docs",
"benchmarks"
]
},
"node_modules/es6-error": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
@@ -22838,6 +22795,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -28407,7 +28365,6 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
"integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
"dev": true,
"license": "MIT"
},
"node_modules/lodash.merge": {
@@ -33009,6 +32966,19 @@
"node": ">=16.0.0"
}
},
"node_modules/pkijs/node_modules/@noble/hashes": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz",
"integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 16"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/playwright": {
"version": "1.61.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.61.1.tgz",
@@ -34847,33 +34817,29 @@
}
},
"node_modules/react": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"version": "19.2.7",
"resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz",
"integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-ace": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/react-ace/-/react-ace-10.1.0.tgz",
"integrity": "sha512-VkvUjZNhdYTuKOKQpMIZi7uzZZVgzCjM7cLYu6F64V0mejY8a2XTyPUIMszC6A4trbeMIHbK5fYFcT/wkP/8VA==",
"version": "14.0.1",
"resolved": "https://registry.npmjs.org/react-ace/-/react-ace-14.0.1.tgz",
"integrity": "sha512-z6YAZ20PNf/FqmYEic//G/UK6uw0rn21g58ASgHJHl9rfE4nITQLqthr9rHMVQK4ezwohJbp2dGrZpkq979PYQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"ace-builds": "^1.4.14",
"ace-builds": "^1.36.3",
"diff-match-patch": "^1.0.5",
"lodash.get": "^4.4.2",
"lodash.isequal": "^4.5.0",
"prop-types": "^15.7.2"
"prop-types": "^15.8.1"
},
"peerDependencies": {
"react": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0"
"react": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/react-arborist": {
@@ -34984,36 +34950,18 @@
}
},
"node_modules/react-checkbox-tree": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/react-checkbox-tree/-/react-checkbox-tree-1.8.0.tgz",
"integrity": "sha512-ufC4aorihOvjLpvY1beab2hjVLGZbDTFRzw62foG0+th+KX7e/sdmWu/nD1ZS/U5Yr0rWGwedGH5GOtR0IkUXw==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/react-checkbox-tree/-/react-checkbox-tree-2.0.2.tgz",
"integrity": "sha512-6cywFB8PgvQD4V9hXMbOKV5F2MPzepix73aevgRZMqkwcqKHD/ulkueCP2ptQYBa43iU7X7YmYxRABKRg77R6Q==",
"license": "MIT",
"dependencies": {
"classnames": "^2.2.5",
"lodash": "^4.17.10",
"nanoid": "^3.0.0",
"fast-equals": "^6.0.0",
"lodash.memoize": "^4.1.2",
"prop-types": "^15.5.8"
},
"peerDependencies": {
"react": "^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-checkbox-tree/node_modules/nanoid": {
"version": "3.3.12",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
"integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/react-diff-viewer-continued": {
@@ -35168,16 +35116,15 @@
}
},
"node_modules/react-dom": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
"version": "19.2.7",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz",
"integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
"scheduler": "^0.27.0"
},
"peerDependencies": {
"react": "^18.3.1"
"react": "^19.2.7"
}
},
"node_modules/react-draggable": {
@@ -35292,18 +35239,6 @@
"react-dom": "*"
}
},
"node_modules/react-loadable": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/react-loadable/-/react-loadable-5.5.0.tgz",
"integrity": "sha512-C8Aui0ZpMd4KokxRdVAm2bQtI03k2RMRNzOB+IipV3yxFTSVICv7WoUr5L9ALB5BmKO1iHgZtWM8EvYG83otdg==",
"license": "MIT",
"dependencies": {
"prop-types": "^15.5.0"
},
"peerDependencies": {
"react": "*"
}
},
"node_modules/react-map-gl": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/react-map-gl/-/react-map-gl-8.1.1.tgz",
@@ -35478,16 +35413,15 @@
}
},
"node_modules/react-resize-detector": {
"version": "9.1.1",
"resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-9.1.1.tgz",
"integrity": "sha512-siLzop7i4xIvZIACE/PHTvRegA8QRCEt0TfmvJ/qCIFQJ4U+3NuYcF8tNDmDWxfIn+X1eNCyY2rauH4KRxge8w==",
"version": "12.3.0",
"resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-12.3.0.tgz",
"integrity": "sha512-mIDOVrTHKGnKe6qEUWi8dFdfHM5CPyTOpqoHctdMQf89Ljm/0qqDIzkP3vTRZZJi9/raaMiRxDEOqO4you5x+A==",
"license": "MIT",
"dependencies": {
"lodash": "^4.17.21"
"es-toolkit": "^1.39.6"
},
"peerDependencies": {
"react": "^16.0.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0"
"react": "^18.0.0 || ^19.0.0"
}
},
"node_modules/react-reverse-portal": {
@@ -36987,13 +36921,10 @@
}
},
"node_modules/scheduler": {
"version": "0.23.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0"
}
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
"integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
"license": "MIT"
},
"node_modules/schema-utils": {
"version": "4.3.3",
@@ -37789,6 +37720,7 @@
"version": "0.7.6",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz",
"integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">= 12"
@@ -39196,6 +39128,7 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
@@ -42280,6 +42213,43 @@
"mkdirp": "bin/cmd.js"
}
},
"node_modules/webpack-visualizer-plugin2/node_modules/react": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/webpack-visualizer-plugin2/node_modules/react-dom": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
"dev": true,
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
},
"peerDependencies": {
"react": "^18.3.1"
}
},
"node_modules/webpack-visualizer-plugin2/node_modules/scheduler": {
"version": "0.23.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0"
}
},
"node_modules/webpack/node_modules/acorn": {
"version": "8.16.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
@@ -43578,13 +43548,12 @@
"@babel/preset-react": "^7.29.7",
"@babel/preset-typescript": "^7.29.7",
"@emotion/styled": "^11.14.1",
"@testing-library/dom": "^9.3.4",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "*",
"@testing-library/react": "^14.0.0",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "*",
"@types/lodash": "^4.17.24",
"@types/react": "*",
"@types/react-loadable": "*",
"@types/react-window": "^1.8.8",
"@types/tinycolor2": "*",
"typescript": "^5.0.0"
@@ -43599,9 +43568,8 @@
"jed": "^1.1.1",
"lodash": "^4.18.1",
"nanoid": "^5.0.9",
"react": "^18.3.0",
"react-dom": "^18.3.0",
"react-loadable": "^5.5.0",
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0",
"tinycolor2": "*"
}
},
@@ -43620,16 +43588,16 @@
"@ant-design/icons": "^5.6.1 || ^6.0.0",
"@emotion/react": "^11.4.1",
"@superset-ui/core": "*",
"@testing-library/dom": "^9.3.4",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "*",
"@testing-library/react": "^14.0.0",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "*",
"ace-builds": "^1.4.14",
"brace": "^0.11.1",
"memoize-one": "^6.0.0",
"react": "^18.3.0",
"react-ace": "^10.1.0",
"react-dom": "^18.3.0"
"react": "^18.3.0 || ^19.0.0",
"react-ace": "^14.0.1",
"react-dom": "^18.3.0 || ^19.0.0"
}
},
"packages/superset-ui-core": {
@@ -43670,7 +43638,7 @@
"react-error-boundary": "^6.1.2",
"react-js-cron": "^6.0.2",
"react-markdown": "^10.1.0",
"react-resize-detector": "^7.1.2",
"react-resize-detector": "^12.3.0",
"react-syntax-highlighter": "^16.1.1",
"react-ultimate-pagination": "^1.3.2",
"regenerator-runtime": "^0.14.1",
@@ -43705,19 +43673,17 @@
"@emotion/cache": "^11.4.0",
"@emotion/react": "^11.4.1",
"@emotion/styled": "^11.14.1",
"@testing-library/dom": "^9.3.4",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "*",
"@testing-library/react": "^14.0.0",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "*",
"@types/react": "*",
"@types/react-loadable": "*",
"@types/react-window": "^1.8.8",
"@types/tinycolor2": "*",
"antd": "^6.0.0",
"nanoid": "^5.0.9",
"react": "^18.3.0",
"react-dom": "^18.3.0",
"react-loadable": "^5.5.0",
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0",
"tinycolor2": "*"
}
},
@@ -43767,23 +43733,6 @@
"node": ">=12"
}
},
"packages/superset-ui-core/node_modules/react-ace": {
"version": "14.0.1",
"resolved": "https://registry.npmjs.org/react-ace/-/react-ace-14.0.1.tgz",
"integrity": "sha512-z6YAZ20PNf/FqmYEic//G/UK6uw0rn21g58ASgHJHl9rfE4nITQLqthr9rHMVQK4ezwohJbp2dGrZpkq979PYQ==",
"license": "MIT",
"dependencies": {
"ace-builds": "^1.36.3",
"diff-match-patch": "^1.0.5",
"lodash.get": "^4.4.2",
"lodash.isequal": "^4.5.0",
"prop-types": "^15.8.1"
},
"peerDependencies": {
"react": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"packages/superset-ui-core/node_modules/react-draggable": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.7.0.tgz",
@@ -43798,19 +43747,6 @@
"react-dom": ">= 16.3.0"
}
},
"packages/superset-ui-core/node_modules/react-resize-detector": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-7.1.2.tgz",
"integrity": "sha512-zXnPJ2m8+6oq9Nn8zsep/orts9vQv3elrpA+R8XTcW7DVVUJ9vwDwMXaBtykAYjMnkCIaOoK9vObyR7ZgFNlOw==",
"license": "MIT",
"dependencies": {
"lodash": "^4.17.21"
},
"peerDependencies": {
"react": "^16.0.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0"
}
},
"packages/superset-ui-switchboard": {
"name": "@superset-ui/switchboard",
"version": "0.20.3",
@@ -43831,7 +43767,7 @@
"@emotion/react": "^11.4.1",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
}
},
"plugins/legacy-plugin-chart-calendar/node_modules/d3-array": {
@@ -43861,22 +43797,13 @@
"license": "Apache-2.0",
"dependencies": {
"d3": "^3.5.17",
"prop-types": "^15.8.1",
"react": "^19.2.7"
"prop-types": "^15.8.1"
},
"peerDependencies": {
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*"
}
},
"plugins/legacy-plugin-chart-chord/node_modules/react": {
"version": "19.2.7",
"resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz",
"integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
"@superset-ui/core": "*",
"react": "^18.2.0 || ^19.0.0"
}
},
"plugins/legacy-plugin-chart-country-map": {
@@ -43892,7 +43819,7 @@
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
}
},
"plugins/legacy-plugin-chart-country-map/node_modules/d3-array": {
@@ -43920,7 +43847,7 @@
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
}
},
"plugins/legacy-plugin-chart-horizon/node_modules/d3-array": {
@@ -43948,7 +43875,7 @@
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
}
},
"plugins/legacy-plugin-chart-parallel-coordinates": {
@@ -43963,7 +43890,7 @@
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
}
},
"plugins/legacy-plugin-chart-partition": {
@@ -43980,9 +43907,9 @@
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"@testing-library/jest-dom": "*",
"@testing-library/react": "^14.0.0",
"react": "^18.3.0",
"react-dom": "^18.3.0"
"@testing-library/react": "^16.3.2",
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0"
}
},
"plugins/legacy-plugin-chart-rose": {
@@ -43999,7 +43926,7 @@
"@emotion/react": "^11.4.1",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
}
},
"plugins/legacy-plugin-chart-world-map": {
@@ -44017,7 +43944,7 @@
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
}
},
"plugins/legacy-plugin-chart-world-map/node_modules/d3-array": {
@@ -44052,7 +43979,7 @@
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"dayjs": "^1.11.21",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
}
},
"plugins/plugin-chart-ag-grid-table": {
@@ -44076,13 +44003,13 @@
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"@testing-library/dom": "^9.3.4",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "*",
"@testing-library/react": "^14.0.0",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "*",
"@types/react": "*",
"react": "^18.3.0",
"react-dom": "^18.3.0"
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0"
}
},
"plugins/plugin-chart-ag-grid-table/node_modules/d3-array": {
@@ -44121,8 +44048,8 @@
"geostyler-wfs-parser": "^3.0.1",
"ol": "^10.8.0",
"polished": "*",
"react": "^18.3.0",
"react-dom": "^18.3.0"
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0"
}
},
"plugins/plugin-chart-echarts": {
@@ -44145,7 +44072,7 @@
"dayjs": "^1.11.21",
"echarts": "*",
"memoize-one": "*",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
}
},
"plugins/plugin-chart-echarts/node_modules/acorn": {
@@ -44195,9 +44122,9 @@
"dayjs": "^1.11.21",
"handlebars": "^4.7.8",
"lodash": "^4.18.1",
"react": "^18.3.0",
"react-ace": "^10.1.0",
"react-dom": "^18.3.0"
"react": "^18.3.0 || ^19.0.0",
"react-ace": "^14.0.1",
"react-dom": "^18.3.0 || ^19.0.0"
}
},
"plugins/plugin-chart-handlebars/node_modules/just-handlebars-helpers": {
@@ -44228,8 +44155,8 @@
"@superset-ui/core": "*",
"lodash": "^4.18.1",
"prop-types": "*",
"react": "^18.3.0",
"react-dom": "^18.3.0"
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0"
}
},
"plugins/plugin-chart-point-cluster-map": {
@@ -44247,8 +44174,8 @@
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"react": "^18.3.0",
"react-dom": "^18.3.0"
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0"
}
},
"plugins/plugin-chart-table": {
@@ -44272,14 +44199,14 @@
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"@testing-library/dom": "^9.3.4",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "*",
"@testing-library/react": "^14.0.0",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "*",
"@types/react": "*",
"match-sorter": "^8.2.0",
"react": "^18.3.0",
"react-dom": "^18.3.0"
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0"
}
},
"plugins/plugin-chart-table/node_modules/d3-array": {
@@ -44313,7 +44240,7 @@
"@superset-ui/core": "*",
"@types/lodash": "*",
"@types/react": "*",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
}
},
"plugins/preset-chart-deckgl": {
@@ -44365,8 +44292,8 @@
"@superset-ui/core": "*",
"dayjs": "^1.11.21",
"mapbox-gl": ">=1.0.0",
"react": "^18.3.0",
"react-dom": "^18.3.0"
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"mapbox-gl": {

View File

@@ -205,20 +205,19 @@
"ol": "^10.9.0",
"query-string": "9.4.1",
"re-resizable": "^6.11.2",
"react": "^18.3.0",
"react": "^19.2.0",
"react-arborist": "^3.13.2",
"react-checkbox-tree": "^1.8.0",
"react-checkbox-tree": "^2.0.1",
"react-diff-viewer-continued": "^4.2.2",
"react-dnd": "^11.1.3",
"react-dnd-html5-backend": "^11.1.3",
"react-dom": "^18.3.0",
"react-dom": "^19.2.0",
"react-google-recaptcha": "^3.1.0",
"react-intersection-observer": "^10.0.3",
"react-json-tree": "^0.20.0",
"react-lines-ellipsis": "^0.16.1",
"react-loadable": "^5.5.0",
"react-redux": "^7.2.9",
"react-resize-detector": "^9.1.1",
"react-resize-detector": "^12.3.0",
"react-reverse-portal": "^2.3.0",
"react-router-dom": "^5.3.4",
"react-search-input": "^0.11.3",
@@ -275,9 +274,9 @@
"@swc/core": "^1.15.43",
"@swc/plugin-emotion": "^14.15.0",
"@swc/plugin-transform-imports": "^12.5.0",
"@testing-library/dom": "^9.3.4",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^14.0.0",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^12.8.3",
"@types/content-disposition": "^0.5.9",
"@types/dom-to-image": "^2.6.7",
@@ -288,10 +287,9 @@
"@types/lodash-es": "^4.17.12",
"@types/mousetrap": "^1.6.15",
"@types/node": "^26.1.1",
"@types/react": "^18.3.0",
"@types/react-dom": "^18.3.0",
"@types/react-loadable": "^5.5.11",
"@types/react-redux": "^7.1.10",
"@types/react": "^19.2.0",
"@types/react-dom": "^19.2.0",
"@types/react-redux": "^7.1.34",
"@types/react-router-dom": "^5.3.3",
"@types/react-transition-group": "^4.4.12",
"@types/react-window": "^1.8.8",
@@ -381,7 +379,7 @@
"ace-builds": "^1.41.0",
"core-js": "^3.38.1",
"handlebars": "^4.7.8",
"react-ace": "^10.1.0",
"react-ace": "^14.0.1",
"regenerator-runtime": "^0.14.1"
},
"engines": {
@@ -389,9 +387,53 @@
"npm": "^11.13.0"
},
"overrides": {
"react-router-dom": {
"react": "^19.2.0",
"react-dom": "^19.2.0"
},
"react-table": {
"react": "^19.2.0"
},
"react-redux": {
"react": "^19.2.0",
"react-dom": "^19.2.0"
},
"react-virtualized-auto-sizer": {
"react": "^19.2.0",
"react-dom": "^19.2.0"
},
"@reduxjs/toolkit": {
"react": "^19.2.0"
},
"react-ultimate-pagination": {
"react": "^19.2.0",
"react-dom": "^19.2.0"
},
"@visx/axis": {
"react": "^19.2.0"
},
"@visx/grid": {
"react": "^19.2.0"
},
"@visx/responsive": {
"react": "^19.2.0"
},
"@visx/scale": {
"react": "^19.2.0"
},
"@visx/tooltip": {
"react": "^19.2.0",
"react-dom": "^19.2.0"
},
"@visx/xychart": {
"react": "^19.2.0",
"react-dom": "^19.2.0"
},
"uuid": "$uuid",
"@great-expectations/jsonforms-antd-renderers": {
"antd": "$antd"
"antd": "$antd",
"react": "^19.2.0",
"react-dom": "^19.2.0"
},
"core-js": "^3.38.1",
"dompurify": "^3.4.11",

View File

@@ -89,12 +89,11 @@
"typescript": "^5.0.0",
"@emotion/styled": "^11.14.1",
"@types/lodash": "^4.17.24",
"@testing-library/dom": "^9.3.4",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "*",
"@testing-library/react": "^14.0.0",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "*",
"@types/react": "*",
"@types/react-loadable": "*",
"@types/react-window": "^1.8.8",
"@types/tinycolor2": "*"
},
@@ -105,9 +104,8 @@
"@fontsource/ibm-plex-mono": "^5.2.7",
"@fontsource/inter": "^5.2.6",
"nanoid": "^5.0.9",
"react": "^18.3.0",
"react-dom": "^18.3.0",
"react-loadable": "^5.5.0",
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0",
"tinycolor2": "*",
"lodash": "^4.18.1",
"antd": "^6.0.0",

View File

@@ -34,16 +34,16 @@
"@ant-design/icons": "^5.6.1 || ^6.0.0",
"@emotion/react": "^11.4.1",
"@superset-ui/core": "*",
"@testing-library/dom": "^9.3.4",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "*",
"@testing-library/react": "^14.0.0",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "*",
"ace-builds": "^1.4.14",
"brace": "^0.11.1",
"memoize-one": "^6.0.0",
"react": "^18.3.0",
"react-ace": "^10.1.0",
"react-dom": "^18.3.0"
"react": "^18.3.0 || ^19.0.0",
"react-ace": "^14.0.1",
"react-dom": "^18.3.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"

View File

@@ -36,7 +36,7 @@ import { SQLPopover } from './SQLPopover';
export type ColumnOptionProps = {
column: ColumnMeta;
showType?: boolean;
labelRef?: RefObject<any>;
labelRef?: RefObject<any | null>;
};
const StyleOverrides = styled.span`

View File

@@ -47,7 +47,7 @@ export interface MetricOptionProps {
showFormula?: boolean;
showType?: boolean;
url?: string;
labelRef?: RefObject<any>;
labelRef?: RefObject<any | null>;
shouldShowTooltip?: boolean;
}

View File

@@ -58,7 +58,7 @@ const TooltipSection = ({
</TooltipSectionWrapper>
);
export const isLabelTruncated = (labelRef?: RefObject<any>): boolean =>
export const isLabelTruncated = (labelRef?: RefObject<any | null>): boolean =>
!!(labelRef?.current?.scrollWidth > labelRef?.current?.clientWidth);
export const getColumnLabelText = (column: ColumnMeta): string =>
@@ -92,7 +92,7 @@ export const getColumnTypeTooltipNode = (column: ColumnMeta): ReactNode => {
export const getColumnTooltipNode = (
column: ColumnMeta,
labelRef?: RefObject<any>,
labelRef?: RefObject<any | null>,
): ReactNode => {
if (
(!column.column_name || !column.verbose_name) &&
@@ -121,7 +121,7 @@ type MetricType = Omit<Metric, 'id' | 'uuid'> & { label?: string };
export const getMetricTooltipNode = (
metric: MetricType,
labelRef?: RefObject<any>,
labelRef?: RefObject<any | null>,
): ReactNode => {
if (
!metric.verbose_name &&

View File

@@ -17,7 +17,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { ReactElement, ReactNode, ReactText, ComponentType } from 'react';
import { ReactElement, ReactNode, ComponentType } from 'react';
import type {
AdhocColumn,
@@ -39,6 +39,9 @@ import type {
import { GenericDataType } from '@apache-superset/core/common';
import { sharedControls, sharedControlComponents } from './shared-controls';
// React 19 removed the ReactText type.
type ReactText = string | number;
export type { Metric } from '@superset-ui/core';
export type { ControlComponentProps } from './shared-controls/components/types';

View File

@@ -56,7 +56,7 @@
"react-error-boundary": "^6.1.2",
"react-js-cron": "^6.0.2",
"react-markdown": "^10.1.0",
"react-resize-detector": "^7.1.2",
"react-resize-detector": "^12.3.0",
"react-syntax-highlighter": "^16.1.1",
"react-ultimate-pagination": "^1.3.2",
"regenerator-runtime": "^0.14.1",
@@ -92,19 +92,17 @@
"@emotion/cache": "^11.4.0",
"@emotion/react": "^11.4.1",
"@emotion/styled": "^11.14.1",
"@testing-library/dom": "^9.3.4",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "*",
"@testing-library/react": "^14.0.0",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "*",
"@types/react": "*",
"@types/react-loadable": "*",
"@types/react-window": "^1.8.8",
"@types/tinycolor2": "*",
"antd": "^6.0.0",
"nanoid": "^5.0.9",
"react": "^18.3.0",
"react-dom": "^18.3.0",
"react-loadable": "^5.5.0",
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0",
"tinycolor2": "*"
},
"publishConfig": {

View File

@@ -17,7 +17,14 @@
* under the License.
*/
import { ReactNode, useCallback, useEffect, useMemo, useState } from 'react';
import {
ReactNode,
useCallback,
useEffect,
useMemo,
useState,
ReactElement,
} from 'react';
import {
SupersetClientInterface,
RequestConfig,
@@ -77,7 +84,7 @@ function ChartDataProvider({
formDataRequestOptions,
datasourceRequestOptions,
queryRequestOptions,
}: ChartDataProviderProps): JSX.Element | null {
}: ChartDataProviderProps): ReactElement | null {
const [state, setState] = useState<ChartDataProviderState>({
status: 'uninitialized',
});
@@ -159,7 +166,7 @@ function ChartDataProvider({
const { status, payload, error } = state;
// Wrap the children result in a Fragment so the component's return type
// stays `JSX.Element | null` (which TypeScript requires for JSX components)
// stays `ReactElement | null` (which TypeScript requires for JSX components)
// while still letting consumers return any ReactNode (strings, fragments,
// arrays, null, etc.) from the render prop.
switch (status) {

View File

@@ -186,8 +186,8 @@ export default function StatefulChart(props: StatefulChartProps) {
const [error, setError] = useState<Error>();
const [formData, setFormData] = useState<QueryFormData>();
const chartClientRef = useRef<ChartClient>();
const abortControllerRef = useRef<AbortController>();
const chartClientRef = useRef<ChartClient | null>(null);
const abortControllerRef = useRef<AbortController | null>(null);
// Initialize chart client
if (!chartClientRef.current) {
@@ -325,7 +325,7 @@ export default function StatefulChart(props: StatefulChartProps) {
}, []);
// Combined effect for all prop changes and lifecycle
const prevPropsRef = useRef<StatefulChartProps>();
const prevPropsRef = useRef<StatefulChartProps | null>(null);
useEffect(() => {
const currentProps = props;
const prevProps = prevPropsRef.current;

View File

@@ -26,6 +26,7 @@ import {
useCallback,
useMemo,
useRef,
ReactElement,
} from 'react';
import {
@@ -76,9 +77,9 @@ export type Props = Omit<SuperChartCoreProps, 'chartProps'> &
/** Prop for form plugins using superchart */
showOverflow?: boolean;
/** Prop for popovercontainer ref */
parentRef?: RefObject<any>;
parentRef?: RefObject<any | null>;
/** Prop for chart ref */
inputRef?: RefObject<any>;
inputRef?: RefObject<any | null>;
/** Chart width */
height?: number | string;
/** Chart height */
@@ -125,7 +126,7 @@ function SuperChart({
height = 400,
width = '100%',
...rest
}: Props): JSX.Element {
}: Props): ReactElement {
/**
* SuperChart's core ref
*/
@@ -264,7 +265,7 @@ function SuperChart({
({ data }) => !data || (Array.isArray(data) && data.length === 0),
));
let chart: JSX.Element;
let chart: ReactElement;
if (noResultQueries) {
chart = noResults ? (
<>{noResults}</>

View File

@@ -42,10 +42,10 @@ function IDENTITY<T>(x: T) {
return x;
}
const EMPTY = () => null;
const EMPTY = Object.assign(() => null, { preload: () => Promise.resolve() });
interface LoadingProps {
error: { toString(): string };
error?: unknown;
}
interface LoadedModules {
@@ -204,7 +204,7 @@ const SuperChartCore = forwardRef<SuperChartCoreRef, Props>(
<div className="alert alert-warning" role="alert">
<strong>{t('ERROR')}</strong>&nbsp;
<code>chartType=&quot;{loadingChartType}&quot;</code> &mdash;
{error.toString()}
{String(error)}
</div>
);
}

View File

@@ -26,11 +26,21 @@ import {
} from 'react';
import type {
ComponentType,
WeakValidationMap,
ForwardRefExoticComponent,
PropsWithoutRef,
RefAttributes,
} from 'react';
import type { Validator } from 'prop-types';
// React 19 dropped `WeakValidationMap` from its type exports; keep the original
// shape so `renderFn.propTypes` still type-checks.
type WeakValidationMap<T> = {
[K in keyof T]?: null extends T[K]
? Validator<T[K] | null | undefined>
: undefined extends T[K]
? Validator<T[K] | null | undefined>
: Validator<T[K]>;
};
// TODO: Note that id and className can collide between Props and ReactifyProps
// leading to (likely) unexpected behaviors. We should either require Props to not
@@ -69,6 +79,24 @@ export type ReactifiedComponent<Props> = ForwardRefExoticComponent<
PropsWithoutRef<Props & ReactifyProps> & RefAttributes<ReactifiedComponentRef>
>;
// Mirrors React's own `defaultProps` rule: a default fills in only where the
// caller passed `undefined`.
function applyDefaultProps<P extends object>(
props: P,
defaultProps?: object,
): P {
if (!defaultProps) {
return props;
}
const merged = { ...props } as Record<string, unknown>;
Object.entries(defaultProps).forEach(([key, value]) => {
if (merged[key] === undefined) {
merged[key] = value;
}
});
return merged as P;
}
// Return the widest public type that covers "use it as a React component" so
// TypeScript JSX callers and `ComponentType<...>`-typed variables still compile;
// callers with explicit `ComponentClass<...>` annotations must widen to
@@ -77,11 +105,18 @@ export type ReactifiedComponent<Props> = ForwardRefExoticComponent<
export default function reactify<Props extends object>(
renderFn: RenderFuncType<Props>,
callbacks?: LifeCycleCallbacks,
): ComponentType<Props & ReactifyProps> {
): ComponentType<Props & ReactifyProps> & {
// Copied off `renderFn` for introspection. React 19 no longer applies these
// itself — `applyDefaultProps` does.
defaultProps?: Partial<Props & ReactifyProps>;
} {
const ReactifiedComponent = forwardRef<
ReactifiedComponentRef,
Props & ReactifyProps
>(function ReactifiedComponent(props, ref) {
>(function ReactifiedComponent(incomingProps, ref) {
// React 19 no longer applies `defaultProps` to function components, so the
// defaults declared on `renderFn` are merged here instead.
const props = applyDefaultProps(incomingProps, renderFn.defaultProps);
const containerRef = useRef<HTMLDivElement>(null);
// Keep the latest props available to the unmount callback — legacy
// consumers read values off `this.props` (e.g. ReactNVD3 uses id).

View File

@@ -101,7 +101,7 @@ export interface ChartPropsConfig {
/** is the chart refreshing its contents */
isRefreshing?: boolean;
/** chart ref */
inputRef?: RefObject<any>;
inputRef?: RefObject<any | null>;
/** Theme object */
theme: SupersetTheme;
/* legend index */
@@ -152,7 +152,7 @@ export default class ChartProps<FormData extends RawFormData = RawFormData> {
isRefreshing?: boolean;
inputRef?: RefObject<any>;
inputRef?: RefObject<any | null>;
inContextMenu?: boolean;

View File

@@ -238,8 +238,8 @@ export function AsyncAceEditor(
// Move autocomplete popup to the nearest parent container with data-ace-container
useEffect(() => {
const editorInstance = (ref as React.RefObject<AceEditor>)?.current
?.editor;
const editorInstance = (ref as React.RefObject<AceEditor | null>)
?.current?.editor;
if (!editorInstance) return;
const editorContainer = editorInstance.container;

View File

@@ -16,7 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
import { Children, ReactElement, Fragment, forwardRef, Ref } from 'react';
import {
Children,
ReactElement,
ReactNode,
Fragment,
forwardRef,
Ref,
} from 'react';
import cx from 'classnames';
import { Button as AntdButton } from 'antd';
import { useTheme } from '@apache-superset/core/theme';
@@ -164,7 +171,9 @@ function ButtonInner(props: ButtonProps, ref: Ref<HTMLElement>) {
color,
} = resolvedStyleMap[buttonStyle ?? 'primary'] ?? BUTTON_STYLE_MAP.primary;
const element = children as ReactElement;
// React 19 types `ReactElement['props']` as `unknown`, so spell out the
// shape read below.
const element = children as ReactElement<{ children?: ReactNode }>;
let renderedChildren = [];

View File

@@ -16,6 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import type { ComponentType } from 'react';
import { DatePicker as AntdDatePicker } from 'antd';
import { css } from '@apache-superset/core/theme';
import type { DatePickerProps, RangePickerProps } from './types';
@@ -29,6 +30,7 @@ export const DatePicker = (props: DatePickerProps) => (
/>
);
export const { RangePicker } = AntdDatePicker;
export const RangePicker: ComponentType<RangePickerProps> =
AntdDatePicker.RangePicker;
export type { DatePickerProps, RangePickerProps };

View File

@@ -16,7 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
import { ReactElement, cloneElement } from 'react';
import {
cloneElement,
type FocusEventHandler,
type KeyboardEventHandler,
type ReactElement,
} from 'react';
import { Dropdown as AntdDropdown, DropdownProps } from 'antd';
import { styled } from '@apache-superset/core/theme';
@@ -98,10 +103,16 @@ export const MenuDotsDropdown = ({
export const NoAnimationDropdown = (props: NoAnimationDropdownProps) => {
const { children, onBlur, onKeyDown, ...rest } = props;
const childrenWithProps = cloneElement(children as ReactElement, {
onBlur,
onKeyDown,
});
const childrenWithProps = cloneElement(
children as ReactElement<{
onBlur?: FocusEventHandler;
onKeyDown?: KeyboardEventHandler;
}>,
{
onBlur,
onKeyDown,
},
);
return (
<AntdDropdown autoFocus overlayStyle={props.overlayStyle} {...rest}>

View File

@@ -57,7 +57,7 @@ export interface DropdownContainerProps {
/**
* Dropdown ref.
*/
dropdownRef?: RefObject<HTMLDivElement>;
dropdownRef?: RefObject<HTMLDivElement | null>;
/**
* Dropdown additional style properties.
*/

View File

@@ -24,7 +24,9 @@ import { BaseIconComponent } from './BaseIcon';
const AsyncIcon = forwardRef<HTMLSpanElement, IconType>((props, ref) => {
const [, setLoaded] = useState(false);
const ImportedSVG = useRef<FC<SVGProps<SVGSVGElement>>>();
const ImportedSVG = useRef<FC<SVGProps<SVGSVGElement>> | undefined>(
undefined,
);
const { fileName, customIcons, iconSize, iconColor, viewBox, ...restProps } =
props;

View File

@@ -16,6 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import type React from 'react';
import { fireEvent, render } from '@superset-ui/core/spec';
import { Icons } from '../Icons';
@@ -57,7 +58,11 @@ test('preserves a custom icon color (antd v6 Tag icon-style regression)', () =>
// test stories from the storybook!
test('renders all the storybook gallery variants', () => {
const { container } = render(<LabelGallery />);
// Cast the storybook fn — its render signature changed in storybook 8
const GalleryComponent = LabelGallery as unknown as React.FC<
Record<string, never>
>;
const { container } = render(<GalleryComponent />);
const nonInteractiveLabelCount = 4;
const renderedLabelCount = options.length * 2 + nonInteractiveLabelCount;
expect(container.querySelectorAll('.ant-tag')).toHaveLength(

View File

@@ -43,14 +43,14 @@ const TWO_DAYS_AGO = '2 days ago';
const runWithBarCollapsed = async (func: Function) => {
const spy = jest.spyOn(resizeDetector, 'useResizeDetector');
let width: number;
spy.mockImplementation(props => {
let width = 0;
spy.mockImplementation(((props: any) => {
if (props?.onResize && !width) {
width = 80;
props.onResize(width);
props.onResize({ width, height: 0, entry: null as unknown });
}
return { ref: { current: undefined } };
});
return { ref: () => {} };
}) as never);
await func();
spy.mockRestore();
};

View File

@@ -17,7 +17,10 @@
* under the License.
*/
import { useCallback, useEffect, useRef, useState } from 'react';
import { useResizeDetector } from 'react-resize-detector';
import {
useResizeDetector,
type OnResizeCallback,
} from 'react-resize-detector';
import { uniqWith } from 'lodash-es';
import { styled } from '@apache-superset/core/theme';
import { Tooltip } from '../Tooltip';
@@ -181,7 +184,7 @@ export interface MetadataBarProps {
* This process is important to make sure the new type is reviewed by the design team, improving Superset consistency.
*/
const MetadataBar = ({ items, tooltipPlacement = 'top' }: MetadataBarProps) => {
const [width, setWidth] = useState<number>();
const [width, setWidth] = useState<number | undefined>(undefined);
const [collapsed, setCollapsed] = useState(false);
const uniqueItems = uniqWith(items, (a, b) => a.type === b.type);
const sortedItems = uniqueItems.sort((a, b) => ORDER[a.type] - ORDER[b.type]);
@@ -193,8 +196,9 @@ const MetadataBar = ({ items, tooltipPlacement = 'top' }: MetadataBarProps) => {
throw new Error('The maximum number of items for the metadata bar is 6.');
}
const onResize = useCallback(
(width: number | undefined) => {
const onResize = useCallback<OnResizeCallback>(
payload => {
const width = payload.width ?? undefined;
// Calculates the breakpoint width to collapse the bar.
// The last item does not have a space, so we subtract SPACE_BETWEEN_ITEMS from the total.
const breakpoint =

View File

@@ -54,7 +54,7 @@ export interface ModalProps {
/** @deprecated Use styles.body instead */
bodyStyle?: CSSProperties;
styles?: { body?: CSSProperties; [key: string]: CSSProperties | undefined };
openerRef?: React.RefObject<HTMLElement>;
openerRef?: React.RefObject<HTMLElement | null>;
}
export interface StyledModalProps {

View File

@@ -17,13 +17,14 @@
* under the License.
*/
import { ModalTrigger } from '.';
import type { ReactElement } from 'react';
interface IModalTriggerProps {
triggerNode: JSX.Element;
triggerNode: ReactElement;
dialogClassName?: string;
modalTitle?: string;
modalBody?: JSX.Element;
modalFooter?: JSX.Element;
modalBody?: ReactElement;
modalFooter?: ReactElement;
beforeOpen?: () => void;
onExit?: () => void;
isButton?: boolean;

View File

@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { Key } from 'react';
import { Key, ReactElement } from 'react';
import cx from 'classnames';
import { css, useTheme } from '@apache-superset/core/theme';
import { Icons } from '@superset-ui/core/components/Icons';
@@ -29,7 +29,7 @@ export interface OptionProps {
}
export type OnChangeHandler = (key: Key) => void;
export type RenderElementHandler = (option: OptionProps) => JSX.Element;
export type RenderElementHandler = (option: OptionProps) => ReactElement;
export interface PopoverDropdownProps {
id: string;

View File

@@ -542,7 +542,7 @@ const AsyncSelect = forwardRef(
originNode: ReactElement & { ref?: RefObject<HTMLElement> },
) =>
dropDownRenderHelper(
originNode,
originNode as Parameters<typeof dropDownRenderHelper>[0],
isDropdownVisible,
isLoading,
fullSelectOptions.length,

View File

@@ -583,10 +583,10 @@ const Select = forwardRef(
const isLoading = loading ?? false;
const popupRender = (
originNode: ReactElement & { ref?: RefObject<HTMLElement> },
originNode: ReactElement & { ref?: RefObject<HTMLElement | null> },
) =>
dropDownRenderHelper(
originNode,
originNode as Parameters<typeof dropDownRenderHelper>[0],
isDropdownVisible,
isLoading,
fullSelectOptions.length,

View File

@@ -153,14 +153,20 @@ export const getSuffixIcon = (
return <Icons.DownOutlined iconSize="s" aria-label="down" />;
};
type FlattenOptionsProps = {
flattenOptions?: Array<Record<string, any>>;
};
export const dropDownRenderHelper = (
originNode: ReactElement & { ref?: RefObject<HTMLElement> },
originNode: ReactElement<FlattenOptionsProps> & {
ref?: RefObject<HTMLElement | null>;
},
isDropdownVisible: boolean,
isLoading: boolean | undefined,
optionsLength: number,
helperText: string | undefined,
errorComponent?: JSX.Element,
bulkSelectComponents?: JSX.Element,
errorComponent?: ReactElement,
bulkSelectComponents?: ReactElement,
) => {
if (!isDropdownVisible) {
originNode.ref?.current?.scrollTo({ top: 0 });
@@ -172,17 +178,19 @@ export const dropDownRenderHelper = (
return errorComponent;
}
const originProps = originNode.props;
// remap for accessibility for proper item count
const accessibilityNode = {
...originNode,
props: {
...originNode.props,
flattenOptions: ensureIsArray(originNode.props.flattenOptions).map(
...originProps,
flattenOptions: ensureIsArray(originProps.flattenOptions).map(
(opt: Record<string, any>, idx: number) => ({
...opt,
data: {
...opt.data,
'aria-setsize': originNode.props.flattenOptions?.length || 0,
'aria-setsize': originProps.flattenOptions?.length || 0,
'aria-posinset': idx + 1,
},
}),

View File

@@ -23,7 +23,10 @@ import {
TableProps as AntTableProps,
} from 'antd/es/table';
import classNames from 'classnames';
import { useResizeDetector } from 'react-resize-detector';
import {
useResizeDetector,
type OnResizeCallback,
} from 'react-resize-detector';
import { useEffect, useRef, useState, useCallback, CSSProperties } from 'react';
import { VariableSizeGrid as Grid } from 'react-window';
import { safeHtmlSpan } from '@superset-ui/core';
@@ -84,8 +87,8 @@ const VirtualTable = <RecordType extends object>(
allowHTML = false,
} = props;
const [tableWidth, setTableWidth] = useState<number>(0);
const onResize = useCallback((width?: number) => {
setTableWidth(width ?? 0);
const onResize = useCallback<OnResizeCallback>(payload => {
setTableWidth(payload.width ?? 0);
}, []);
const { ref } = useResizeDetector({ onResize });
const theme = useTheme();
@@ -126,8 +129,8 @@ const VirtualTable = <RecordType extends object>(
(lastColumn.width as number) + Math.floor(tableWidth - totalWidth);
}
const gridRef = useRef<any>();
const [connectObject] = useState<any>(() => {
const gridRef = useRef<any | null>(null);
const [connectObject] = useState<Record<string, unknown>>(() => {
const obj = {};
Object.defineProperty(obj, 'scrollLeft', {
get: () => {

View File

@@ -17,7 +17,7 @@
* under the License.
*/
import { fireEvent, render } from '@superset-ui/core/spec';
import { fireEvent, render, screen } from '@superset-ui/core/spec';
import Tabs, { EditableTabs, LineEditableTabs } from './Tabs';
const defaultItems = [
@@ -163,12 +163,14 @@ describe('Tabs', () => {
expect(onEditMock).toHaveBeenCalledWith(expect.any(String), 'remove');
});
test('should have default props set correctly', () => {
expect(EditableTabs.defaultProps?.type).toBe('editable-card');
expect(EditableTabs.defaultProps?.animated).toEqual({
inkBar: true,
tabPane: false,
});
test('renders with editable-card defaults', () => {
render(
<EditableTabs
items={[{ key: '1', label: 'Tab 1', children: 'one' }]}
/>,
);
const container = screen.getByText('Tab 1').closest('.ant-tabs');
expect(container).toHaveClass('ant-tabs-editable-card');
});
});

View File

@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import type { FC } from 'react';
import type { ComponentProps, FC } from 'react';
import { css, styled } from '@apache-superset/core/theme';
import { Tabs as AntdTabs, TabsProps as AntdTabsProps } from 'antd';
import { Icons } from '@superset-ui/core/components/Icons';
@@ -132,19 +132,23 @@ const StyledEditableTabs = styled(StyledTabs)`
const StyledCloseOutlined = styled(Icons.CloseOutlined)`
color: ${({ theme }) => theme.colorIcon};
`;
export const EditableTabs = Object.assign(StyledEditableTabs, {
TabPane: StyledTabPane,
const EditableTabsBase: FC<TabsProps> = ({
type = 'editable-card',
animated = { inkBar: true, tabPane: false },
...rest
}: TabsProps) => (
<StyledEditableTabs type={type} animated={animated} {...rest} />
);
const EditableTabPane: FC<ComponentProps<typeof StyledTabPane>> = ({
closeIcon = <StyledCloseOutlined iconSize="s" role="button" tabIndex={0} />,
...rest
}) => <StyledTabPane closeIcon={closeIcon} {...rest} />;
export const EditableTabs = Object.assign(EditableTabsBase, {
TabPane: EditableTabPane,
});
EditableTabs.defaultProps = {
type: 'editable-card',
animated: { inkBar: true, tabPane: false },
};
EditableTabs.TabPane.defaultProps = {
closeIcon: <StyledCloseOutlined iconSize="s" role="button" tabIndex={0} />,
};
export const StyledLineEditableTabs = styled(EditableTabs)`
&.ant-tabs-card > .ant-tabs-nav .ant-tabs-tab {
margin: 0 ${({ theme }) => theme.sizeUnit * 4}px;

View File

@@ -42,7 +42,7 @@ interface TelemetryPixelProps {
* @param {string} props.sha - The SHA of Superset that's currently in use.
* @param {string} props.build - The build of Superset that's currently in use.
* @param {boolean} props.enabled - Runtime opt-out switch; when false the pixel is not rendered.
* @returns {JSX.Element | null} The rendered TelemetryPixel component.
* @returns {ReactElement | null} The rendered TelemetryPixel component.
*/
const PIXEL_ID = '0d3461e1-abb1-4691-a0aa-5ed50de66af0';

View File

@@ -122,6 +122,10 @@ test('applies dark theme when background is dark', () => {
expect(theme.foregroundColor).toBe('#ffffff');
});
// The props AgGridReact was last rendered with.
const agGridProps = () =>
(AgGridReact as unknown as jest.Mock).mock.calls.at(-1)?.[0];
test('forwards ref to AgGridReact', () => {
const ref = createRef<AgGridReact>();
@@ -133,13 +137,14 @@ test('forwards ref to AgGridReact', () => {
/>,
);
// Check that AgGridReact was called with the ref
expect(AgGridReact).toHaveBeenCalledWith(
// React 19 hands `ref` to the component as a regular prop rather than as a
// second argument, so assert on the props object itself.
expect(agGridProps()).toEqual(
expect.objectContaining({
rowData: mockRowData,
columnDefs: mockColumnDefs,
ref,
}),
expect.any(Object), // ref is passed as second argument
);
});
@@ -160,7 +165,7 @@ test('passes all props through to AgGridReact', () => {
// onGridReady and onFirstDataRendered are intercepted by the component to expose
// the grid API on the container element; the wrapped function is passed instead.
expect(AgGridReact).toHaveBeenCalledWith(
expect(agGridProps()).toEqual(
expect.objectContaining({
rowData: mockRowData,
columnDefs: mockColumnDefs,
@@ -169,7 +174,6 @@ test('passes all props through to AgGridReact', () => {
pagination: true,
paginationPageSize: 10,
}),
expect.any(Object),
);
});

View File

@@ -38,7 +38,7 @@ export function Timer({
const [clockStr, setClockStr] = useState(
startTime && endTime ? fDuration(startTime, endTime) : '00:00:00.00',
);
const timer = useRef<ReturnType<typeof setInterval>>();
const timer = useRef<ReturnType<typeof setInterval> | undefined>(undefined);
useEffect(() => {
const stopTimer = () => {

View File

@@ -20,8 +20,8 @@ import { useEffect, useRef, useState, RefObject } from 'react';
export function useElementOnScreen<T extends Element>(
options: IntersectionObserverInit,
): [RefObject<T>, boolean] {
const containerRef = useRef<T>(null);
): [RefObject<T | null>, boolean] {
const containerRef = useRef<T | null>(null);
const [isSticky, setIsSticky] = useState(false);
const callback = (entries: IntersectionObserverEntry[]) => {

View File

@@ -38,9 +38,9 @@ export const truncationCSS = css`
*/
const useCSSTextTruncation = <T extends HTMLElement>(
{ isVertical, isHorizontal } = { isVertical: false, isHorizontal: true },
): [RefObject<T>, boolean] => {
): [RefObject<T | null>, boolean] => {
const [isTruncated, setIsTruncated] = useState(true);
const ref = useRef<T>(null);
const ref = useRef<T | null>(null);
const [offsetWidth, setOffsetWidth] = useState(0);
const [scrollWidth, setScrollWidth] = useState(0);
const [offsetHeight, setOffsetHeight] = useState(0);

View File

@@ -30,10 +30,10 @@ const genElements = (
offsetWidth: number | undefined,
childNodes: any = [],
) => {
const elementRef: RefObject<Partial<HTMLElement>> = {
const elementRef: RefObject<Partial<HTMLElement> | null> = {
current: { scrollWidth, clientWidth, childNodes },
};
const plusRef: RefObject<Partial<HTMLElement>> = {
const plusRef: RefObject<Partial<HTMLElement> | null> = {
current: { offsetWidth },
};
return [elementRef, plusRef];

View File

@@ -18,7 +18,7 @@
*/
import '@testing-library/jest-dom';
import { ComponentType } from 'react';
import { ComponentType, ReactElement } from 'react';
import { render as renderTestComponent, screen } from '@testing-library/react';
import createLoadableRenderer, {
LoadableRenderer as LoadableRendererType,
@@ -29,8 +29,8 @@ describe('createLoadableRenderer', () => {
return <div className="test-component">test</div>;
}
let loadChartSuccess = jest.fn(() => Promise.resolve(TestComponent));
let render: (loaded: { Chart: ComponentType }) => JSX.Element;
let loading: () => JSX.Element;
let render: (loaded: { Chart: ComponentType }) => ReactElement;
let loading: () => ReactElement;
let LoadableRenderer: LoadableRendererType<{}>;
beforeEach(() => {

View File

@@ -33,7 +33,7 @@
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"@apache-superset/core": "*",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"

View File

@@ -30,12 +30,12 @@
},
"dependencies": {
"d3": "^3.5.17",
"prop-types": "^15.8.1",
"react": "^19.2.7"
"prop-types": "^15.8.1"
},
"peerDependencies": {
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"@apache-superset/core": "*"
"@apache-superset/core": "*",
"react": "^18.2.0 || ^19.0.0"
}
}

View File

@@ -34,6 +34,6 @@
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
}
}

View File

@@ -31,7 +31,7 @@
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"@apache-superset/core": "*",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"

View File

@@ -31,7 +31,7 @@
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"@apache-superset/core": "*",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"

View File

@@ -36,6 +36,6 @@
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"@apache-superset/core": "*",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
}
}

View File

@@ -32,9 +32,9 @@
"@superset-ui/core": "*",
"@apache-superset/core": "*",
"@testing-library/jest-dom": "*",
"@testing-library/react": "^14.0.0",
"react": "^18.3.0",
"react-dom": "^18.3.0"
"@testing-library/react": "^16.3.2",
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"

View File

@@ -32,7 +32,7 @@
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"@apache-superset/core": "*",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"

View File

@@ -39,6 +39,6 @@
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"@apache-superset/core": "*",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
}
}

View File

@@ -44,6 +44,6 @@
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"dayjs": "^1.11.21",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
}
}

View File

@@ -40,13 +40,13 @@
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"@testing-library/dom": "^9.3.4",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "*",
"@testing-library/react": "^14.0.0",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "*",
"@types/react": "*",
"react": "^18.3.0",
"react-dom": "^18.3.0"
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"

View File

@@ -68,7 +68,7 @@ const getSortIcon = (sortState: SortState[], colId: string | null) => {
const autoOpenFilterAndFocus = async (
column: Column,
api: GridApi,
filterRef: React.RefObject<HTMLDivElement>,
filterRef: React.RefObject<HTMLDivElement | null>,
setFilterVisible: (visible: boolean) => void,
lastFilteredInputPosition?: FilterInputPosition,
) => {

View File

@@ -16,12 +16,19 @@
* specific language governing permissions and limitations
* under the License.
*/
import { useEffect, useRef, useState, cloneElement } from 'react';
import {
useEffect,
useRef,
useState,
cloneElement,
type ReactElement,
type Ref,
} from 'react';
import { PopoverContainer, PopoverWrapper } from '../../styles';
interface Props {
content: React.ReactNode;
children: React.ReactElement;
children: ReactElement<{ ref?: Ref<HTMLElement> }>;
isOpen: boolean;
onClose: () => void;
}

View File

@@ -24,9 +24,10 @@ import {
memo,
FunctionComponent,
useState,
ChangeEvent,
FormEvent,
useEffect,
type RefObject,
ReactElement,
} from 'react';
import { Constants, ThemedAgGridReact } from '@superset-ui/core/components';
@@ -102,14 +103,14 @@ export interface AgGridTableProps {
handleCellClicked: (event: CellClickedEvent) => void;
handleSelectionChanged: (event: SelectionChangedEvent) => void;
filters?: Record<string, DataRecordValue[]> | null;
renderTimeComparisonDropdown: () => JSX.Element | null;
renderTimeComparisonDropdown: () => ReactElement | null;
cleanedTotals: DataRecord;
showTotals: boolean;
width: number;
onColumnStateChange?: (state: AgGridChartStateWithMetadata) => void;
onFilterChanged?: (filterModel: Record<string, any>) => void;
metricColumns?: string[];
gridRef?: RefObject<AgGridReact>;
gridRef?: RefObject<AgGridReact | null>;
chartState?: AgGridChartState;
}
@@ -246,7 +247,8 @@ const AgGridDataTable: FunctionComponent<AgGridTableProps> = memo(
}, []);
const onFilterTextBoxChanged = useCallback(
({ target: { value } }: ChangeEvent<HTMLInputElement>) => {
(event: FormEvent<HTMLInputElement>) => {
const value = (event.target as HTMLInputElement).value;
if (serverPagination) {
setSearchValue(value);
debouncedSearch(value);

View File

@@ -23,7 +23,14 @@ import {
getTimeFormatterForGranularity,
} from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/common';
import { useCallback, useEffect, useRef, useState, useMemo } from 'react';
import {
useCallback,
useEffect,
useRef,
useState,
useMemo,
type ReactElement,
} from 'react';
import { isEqual } from 'lodash-es';
import {
@@ -439,7 +446,7 @@ export default function TableChart<D extends DataRecord = DataRecord>(
[setDataMask, serverPagination],
);
const renderTimeComparisonVisibility = (): JSX.Element => (
const renderTimeComparisonVisibility = (): ReactElement => (
<TimeComparisonVisibility
comparisonColumns={comparisonColumns}
selectedComparisonColumns={selectedComparisonColumns}

View File

@@ -120,7 +120,7 @@ async function detectLastFilteredInput(
* Gets complete filter state including SQL conversion and input position detection.
*/
export async function getCompleteFilterState(
gridRef: RefObject<AgGridReact>,
gridRef: RefObject<AgGridReact | null>,
metricColumns: string[],
): Promise<FilterState> {
// Capture activeElement before any async operations to detect which input

View File

@@ -24,7 +24,7 @@ import { FILTER_INPUT_POSITIONS } from '../../src/consts';
describe('filterStateManager', () => {
describe('getCompleteFilterState', () => {
test('should return empty state when gridRef.current is null', async () => {
const gridRef = { current: null } as RefObject<AgGridReact>;
const gridRef = { current: null } as RefObject<AgGridReact | null>;
const result = await getCompleteFilterState(gridRef, []);
@@ -41,7 +41,7 @@ describe('filterStateManager', () => {
test('should return empty state when gridRef.current.api is undefined', async () => {
const gridRef = {
current: { api: undefined } as any,
} as RefObject<AgGridReact>;
} as RefObject<AgGridReact | null>;
const result = await getCompleteFilterState(gridRef, []);
@@ -68,7 +68,7 @@ describe('filterStateManager', () => {
const gridRef = {
current: { api: mockApi } as any,
} as RefObject<AgGridReact>;
} as RefObject<AgGridReact | null>;
const result = await getCompleteFilterState(gridRef, []);
@@ -103,7 +103,7 @@ describe('filterStateManager', () => {
const gridRef = {
current: { api: mockApi } as any,
} as RefObject<AgGridReact>;
} as RefObject<AgGridReact | null>;
const result = await getCompleteFilterState(gridRef, ['SUM(revenue)']);
@@ -138,7 +138,7 @@ describe('filterStateManager', () => {
const gridRef = {
current: { api: mockApi } as any,
} as RefObject<AgGridReact>;
} as RefObject<AgGridReact | null>;
// Mock activeElement
Object.defineProperty(document, 'activeElement', {
@@ -182,7 +182,7 @@ describe('filterStateManager', () => {
const gridRef = {
current: { api: mockApi } as any,
} as RefObject<AgGridReact>;
} as RefObject<AgGridReact | null>;
// Mock activeElement
Object.defineProperty(document, 'activeElement', {
@@ -217,7 +217,7 @@ describe('filterStateManager', () => {
const gridRef = {
current: { api: mockApi } as any,
} as RefObject<AgGridReact>;
} as RefObject<AgGridReact | null>;
// Mock activeElement as something outside the filter
const outsideElement = document.createElement('div');
@@ -272,7 +272,7 @@ describe('filterStateManager', () => {
const gridRef = {
current: { api: mockApi } as any,
} as RefObject<AgGridReact>;
} as RefObject<AgGridReact | null>;
// Mock activeElement in age filter
Object.defineProperty(document, 'activeElement', {
@@ -306,7 +306,7 @@ describe('filterStateManager', () => {
const gridRef = {
current: { api: mockApi } as any,
} as RefObject<AgGridReact>;
} as RefObject<AgGridReact | null>;
const result = await getCompleteFilterState(gridRef, []);
@@ -324,7 +324,7 @@ describe('filterStateManager', () => {
const gridRef = {
current: { api: mockApi } as any,
} as RefObject<AgGridReact>;
} as RefObject<AgGridReact | null>;
const result = await getCompleteFilterState(gridRef, []);
@@ -356,7 +356,7 @@ describe('filterStateManager', () => {
const gridRef = {
current: { api: mockApi } as any,
} as RefObject<AgGridReact>;
} as RefObject<AgGridReact | null>;
const result = await getCompleteFilterState(gridRef, []);
@@ -378,7 +378,7 @@ describe('filterStateManager', () => {
const gridRef = {
current: { api: mockApi } as any,
} as RefObject<AgGridReact>;
} as RefObject<AgGridReact | null>;
const result = await getCompleteFilterState(gridRef, []);
@@ -422,7 +422,7 @@ describe('filterStateManager', () => {
const gridRef = {
current: { api: mockApi } as any,
} as RefObject<AgGridReact>;
} as RefObject<AgGridReact | null>;
Object.defineProperty(document, 'activeElement', {
writable: true,
@@ -449,7 +449,7 @@ describe('filterStateManager', () => {
const gridRef = {
current: { api: mockApi } as any,
} as RefObject<AgGridReact>;
} as RefObject<AgGridReact | null>;
const result = await getCompleteFilterState(gridRef, []);
@@ -469,7 +469,7 @@ describe('filterStateManager', () => {
const gridRef = {
current: { api: mockApi } as any,
} as RefObject<AgGridReact>;
} as RefObject<AgGridReact | null>;
const result = await getCompleteFilterState(gridRef, []);
@@ -509,7 +509,7 @@ describe('filterStateManager', () => {
const gridRef = {
current: { api: mockApi } as any,
} as RefObject<AgGridReact>;
} as RefObject<AgGridReact | null>;
// Mock activeElement in join AND operator
Object.defineProperty(document, 'activeElement', {
@@ -556,7 +556,7 @@ describe('filterStateManager', () => {
const gridRef = {
current: { api: mockApi } as any,
} as RefObject<AgGridReact>;
} as RefObject<AgGridReact | null>;
// Mock activeElement in join OR operator
Object.defineProperty(document, 'activeElement', {
@@ -598,7 +598,7 @@ describe('filterStateManager', () => {
const gridRef = {
current: { api: mockApi } as any,
} as RefObject<AgGridReact>;
} as RefObject<AgGridReact | null>;
Object.defineProperty(document, 'activeElement', {
writable: true,
@@ -641,7 +641,7 @@ describe('filterStateManager', () => {
const gridRef = {
current: { api: mockApi } as any,
} as RefObject<AgGridReact>;
} as RefObject<AgGridReact | null>;
Object.defineProperty(document, 'activeElement', {
writable: true,

View File

@@ -48,7 +48,7 @@
"geostyler-wfs-parser": "^3.0.1",
"ol": "^10.8.0",
"polished": "*",
"react": "^18.3.0",
"react-dom": "^18.3.0"
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0"
}
}

View File

@@ -39,7 +39,7 @@
"dayjs": "^1.11.21",
"echarts": "*",
"memoize-one": "*",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"

View File

@@ -66,7 +66,9 @@ export default function EchartsTimeseries({
const echartRef = useRef<EchartsHandler | null>(null);
// eslint-disable-next-line no-param-reassign
refs.echartRef = echartRef;
const clickTimer = useRef<ReturnType<typeof setTimeout>>();
const clickTimer = useRef<ReturnType<typeof setTimeout> | undefined>(
undefined,
);
const extraControlRef = useRef<HTMLDivElement>(null);
const [extraControlHeight, setExtraControlHeight] = useState(0);
useEffect(() => {

View File

@@ -165,7 +165,7 @@ function Echart(
refs.divRef = divRef;
}
const [didMount, setDidMount] = useState(false);
const chartRef = useRef<EChartsType>();
const chartRef = useRef<EChartsType | null>(null);
const previousQueryEventHandlers = useRef<QueryEventHandlers>([]);
const currentSelection = useMemo(
() => Object.keys(selectedValues) || [],
@@ -174,7 +174,7 @@ function Echart(
const previousSelection = useRef<string[]>([]);
useImperativeHandle(ref, () => ({
getEchartInstance: () => chartRef.current,
getEchartInstance: () => chartRef.current ?? undefined,
}));
const locale = useSelector(

View File

@@ -44,7 +44,7 @@ export type EchartsStylesProps = {
export type Refs = {
echartRef?: Ref<EchartsHandler>;
divRef?: RefObject<HTMLDivElement>;
divRef?: RefObject<HTMLDivElement | null>;
};
export interface EchartsProps {

View File

@@ -40,9 +40,9 @@
"handlebars": "^4.7.8",
"lodash": "^4.18.1",
"dayjs": "^1.11.21",
"react": "^18.3.0",
"react-ace": "^10.1.0",
"react-dom": "^18.3.0"
"react": "^18.3.0 || ^19.0.0",
"react-ace": "^14.0.1",
"react-dom": "^18.3.0 || ^19.0.0"
},
"devDependencies": {
"@types/jest": "^30.0.0",

View File

@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { ReactNode } from 'react';
import { ReactNode, ReactElement } from 'react';
interface ControlHeaderProps {
children: ReactNode;
@@ -24,7 +24,7 @@ interface ControlHeaderProps {
export const ControlHeader = ({
children,
}: ControlHeaderProps): JSX.Element => (
}: ControlHeaderProps): ReactElement => (
<div className="ControlHeader">
<div className="pull-left">{children}</div>
</div>

View File

@@ -33,8 +33,8 @@
"@superset-ui/core": "*",
"lodash": "^4.18.1",
"prop-types": "*",
"react": "^18.3.0",
"react-dom": "^18.3.0"
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0"
},
"devDependencies": {
"@babel/types": "^7.29.7",

View File

@@ -1541,4 +1541,3 @@ TableRenderer.propTypes = {
tableOptions: PropTypes.object,
onContextMenu: PropTypes.func,
};
TableRenderer.defaultProps = { ...PivotData.defaultProps, tableOptions: {} };

View File

@@ -36,8 +36,8 @@
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"react": "^18.3.0",
"react-dom": "^18.3.0"
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"

View File

@@ -40,14 +40,14 @@
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"@testing-library/dom": "^9.3.4",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "*",
"@testing-library/react": "^14.0.0",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "*",
"@types/react": "*",
"match-sorter": "^8.2.0",
"react": "^18.3.0",
"react-dom": "^18.3.0"
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"

View File

@@ -27,6 +27,7 @@ import {
DragEvent,
useEffect,
useMemo,
ReactElement,
} from 'react';
import { typedMemo, usePrevious } from '@superset-ui/core';
import { t } from '@apache-superset/core/translation';
@@ -79,10 +80,10 @@ export interface DataTableProps<D extends object> extends TableOptions<D> {
noResults?: string | ((filterString: string) => ReactNode);
sticky?: boolean;
rowCount: number;
wrapperRef?: MutableRefObject<HTMLDivElement>;
wrapperRef?: MutableRefObject<HTMLDivElement | null>;
onColumnOrderChange?: () => void;
renderGroupingHeaders?: () => JSX.Element;
renderTimeComparisonDropdown?: () => JSX.Element;
renderGroupingHeaders?: () => ReactElement;
renderTimeComparisonDropdown?: () => ReactElement;
handleSortByChange: (sortBy: SortByItem[]) => void;
sortByFromParent: SortByItem[];
manualSearch?: boolean;
@@ -138,7 +139,7 @@ export default typedMemo(function DataTable<D extends object>({
onFilteredDataChange,
onFilteredRowsChange,
...moreUseTableOptions
}: DataTableProps<D>): JSX.Element {
}: DataTableProps<D>): ReactElement {
const tableHooks: PluginHook<D>[] = [
useGlobalFilter,
useSortBy,
@@ -343,7 +344,7 @@ export default typedMemo(function DataTable<D extends object>({
if (!columns || columns.length === 0) {
return (
wrapStickyTable ? wrapStickyTable(getNoResults) : getNoResults()
) as JSX.Element;
) as ReactElement;
}
const shouldRenderFooter = columns.some(x => !!x.Footer);

View File

@@ -28,6 +28,7 @@ import {
ComponentPropsWithRef,
CSSProperties,
UIEventHandler,
type JSX,
} from 'react';
import { TableInstance, Hooks } from 'react-table';
import { useTheme, css } from '@apache-superset/core/theme';

View File

@@ -26,7 +26,7 @@ export default function useMountedMemo<T>(
factory: () => T,
deps?: unknown[],
): T | undefined {
const mounted = useRef<typeof factory>();
const mounted = useRef<typeof factory | null>(null);
useLayoutEffect(() => {
mounted.current = factory;
});

View File

@@ -26,6 +26,7 @@ import {
KeyboardEvent as ReactKeyboardEvent,
useEffect,
useRef,
ReactElement,
} from 'react';
import {
@@ -765,7 +766,7 @@ export default function TableChart<D extends DataRecord = DataRecord>(
[comparisonLabels],
);
const renderTimeComparisonDropdown = (): JSX.Element => {
const renderTimeComparisonDropdown = (): ReactElement => {
const allKey = comparisonColumns[0].key;
const handleOnClick = (data: any) => {
const { key } = data;
@@ -872,7 +873,7 @@ export default function TableChart<D extends DataRecord = DataRecord>(
[visibleColumnsMeta, getHeaderColumns, isUsingTimeComparison],
);
const renderGroupingHeaders = (): JSX.Element => {
const renderGroupingHeaders = (): ReactElement => {
// TODO: Make use of ColumnGroup to render the aditional headers
const headers: any = [];
let currentColumnIndex = 0;

View File

@@ -40,7 +40,7 @@
"@superset-ui/core": "*",
"@types/lodash": "*",
"@types/react": "*",
"react": "^18.3.0"
"react": "^18.3.0 || ^19.0.0"
},
"devDependencies": {
"@types/d3-cloud": "^1.2.9"

View File

@@ -18,7 +18,7 @@
*/
import { isCustomControlItem } from '@superset-ui/chart-controls';
import controlPanel from '../src/plugin/controlPanel';
import React, { ReactElement } from 'react';
import React, { type ReactElement } from 'react';
const isNameControl = (
item: unknown,

View File

@@ -68,8 +68,8 @@
"@superset-ui/core": "*",
"dayjs": "^1.11.21",
"mapbox-gl": ">=1.0.0",
"react": "^18.3.0",
"react-dom": "^18.3.0"
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"mapbox-gl": {

View File

@@ -112,7 +112,7 @@ export const DeckGLContainer = memo(
}, [props.layers]);
const isCustomTooltip = (content: ReactNode): boolean =>
isValidElement(content) &&
isValidElement<{ 'data-tooltip-type'?: string }>(content) &&
content.props?.['data-tooltip-type'] === 'custom';
const renderTooltip = (tooltipState: TooltipProps['tooltip']) => {

View File

@@ -116,7 +116,7 @@ const selectDataMask = createSelector(
);
const DeckMulti = (props: DeckMultiProps) => {
const containerRef = useRef<DeckGLContainerHandle>();
const containerRef = useRef<DeckGLContainerHandle | null>(null);
const dataMask = useSelector(selectDataMask);

View File

@@ -93,7 +93,7 @@ export function createDeckGLComponent(
) {
// Higher order component
return memo((props: DeckGLComponentProps) => {
const containerRef = useRef<DeckGLContainerHandle>();
const containerRef = useRef<DeckGLContainerHandle | null>(null);
const prevFormData = usePrevious(props.formData);
const prevFilterState = usePrevious(props.filterState);
const prevPayload = usePrevious(props.payload);

View File

@@ -179,7 +179,7 @@ export const getLayer: GetLayerType<ContourLayer> = function ({
cellSize: safeCellSize,
aggregation: aggregation.toUpperCase(),
getPosition: (d: { position: number[]; weight: number }) =>
d.position as Position,
d.position as unknown as Position,
getWeight: (d: { weight: number }) => d.weight || 0,
...commonLayerProps({
formData: fd,

View File

@@ -394,7 +394,7 @@ export function getPoints(data?: Point[]) {
}
const DeckGLGeoJson = (props: DeckGLGeoJsonProps) => {
const containerRef = useRef<DeckGLContainerHandle>();
const containerRef = useRef<DeckGLContainerHandle | null>(null);
const setTooltip = useCallback((tooltip: TooltipProps['tooltip']) => {
const { current } = containerRef;
if (current) {

View File

@@ -19,7 +19,9 @@
import { HeatmapLayer } from '@deck.gl/aggregation-layers';
import { Position } from '@deck.gl/core';
import { t } from '@apache-superset/core/translation';
import type { ScaleLinear } from 'd3-scale';
import {
CategoricalColorScale,
getSequentialSchemeRegistry,
JsonObject,
QueryFormData,
@@ -130,7 +132,8 @@ export const getLayer: GetLayerType<HeatmapLayer> = ({
colorBreakpoints: fd.color_breakpoints,
fixedColor: fd.color_picker,
colorSchemeType,
colorScale,
colorScale: colorScale as
CategoricalColorScale | ScaleLinear<string, string, never> | undefined,
})?.reverse();
const tooltipContent = setTooltipContent(fd);

View File

@@ -263,7 +263,7 @@ export function getPoints(data: JsonObject[]) {
}
const DeckGLPolygon = (props: DeckGLPolygonProps) => {
const containerRef = useRef<DeckGLContainerHandle>();
const containerRef = useRef<DeckGLContainerHandle | null>(null);
const getAdjustedViewport = useCallback(() => {
let viewport = { ...props.viewport };

View File

@@ -76,7 +76,7 @@ export function commonLayerProps({
let currentTooltipContent: ReactNode = null;
const isCustomTooltip = (content: ReactNode): boolean =>
isValidElement(content) &&
isValidElement<{ 'data-tooltip-type'?: string }>(content) &&
content.props?.['data-tooltip-type'] === 'custom';
onHover = (o: JsonObject) => {
@@ -245,7 +245,7 @@ export const getColorRange = ({
defaultBreakpointsColor: { r: number; g: number; b: number; a: number };
fixedColor?: { r: number; g: number; b: number; a: number };
colorBreakpoints?: ColorBreakpointType[];
colorScale?: CategoricalColorScale | ScaleLinear<string, string>;
colorScale?: CategoricalColorScale | ScaleLinear<string, string, never>;
}) => {
let colorRange: Color[] | undefined;
switch (colorSchemeType) {

View File

@@ -19,7 +19,7 @@
import { t } from '@apache-superset/core/translation';
import { JsonObject, QueryFormData } from '@superset-ui/core';
import { useMemo, memo } from 'react';
import { useMemo, memo, ReactElement } from 'react';
import { HandlebarsRenderer } from './HandlebarsRenderer';
import TooltipRow from '../TooltipRow';
import { createDefaultTemplateWithLimits } from './multiValueUtils';
@@ -126,8 +126,8 @@ function formatValue(value: any): string {
function buildFieldBasedTooltipItems(
o: JsonObject,
formData: QueryFormData,
): JSX.Element[] {
const tooltipItems: JSX.Element[] = [];
): ReactElement[] {
const tooltipItems: ReactElement[] = [];
formData.tooltip_contents.forEach((item: any, index: number) => {
let label = '';
@@ -360,7 +360,7 @@ export function generateEnhancedDefaultTemplate(
export function useTooltipContent(
formData: QueryFormData,
defaultTooltipGenerator: (o: JsonObject) => JSX.Element,
defaultTooltipGenerator: (o: JsonObject) => ReactElement,
) {
const tooltipContentGenerator = useMemo(
() => (o: JsonObject) => {
@@ -401,7 +401,7 @@ export function useTooltipContent(
export function createTooltipContent(
formData: QueryFormData,
defaultTooltipGenerator: (o: JsonObject) => JSX.Element,
defaultTooltipGenerator: (o: JsonObject) => ReactElement,
) {
return (o: JsonObject) => {
if (

View File

@@ -136,7 +136,8 @@ export function getBreakPointColorScaler(
if (!colorScheme) {
return () => TRANSPARENT_COLOR_ARRAY;
}
let scaler: ScaleLinear<string, string> | ScaleThreshold<number, string>;
let scaler:
ScaleLinear<string, string, never> | ScaleThreshold<number, string>;
let maskPoint: (v: number | undefined) => boolean;
if (breakPoints !== null) {
// bucket colors into discrete colors
@@ -164,11 +165,15 @@ export function getBreakPointColorScaler(
// interpolate colors linearly
const linearScaleDomain = extent(features, accessor);
if (!linearScaleDomain.some(i => typeof i === 'number')) {
scaler = colorScheme.createLinearScale();
scaler = colorScheme.createLinearScale() as ScaleLinear<
string,
string,
never
>;
} else {
scaler = colorScheme.createLinearScale(
extent(features, accessor) as number[],
);
) as ScaleLinear<string, string, never>;
}
maskPoint = () => false;
}

View File

@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { type ReactChild } from 'react';
import { type ReactNode } from 'react';
import {
render,
screen,
@@ -96,7 +96,7 @@ jest.mock('src/components/StreamingExportModal/useStreamingExport', () => ({
jest.mock(
'react-virtualized-auto-sizer',
() =>
({ children }: { children: (params: { height: number }) => ReactChild }) =>
({ children }: { children: (params: { height: number }) => ReactNode }) =>
children({ height: 500 }),
);
const applicationRootMock = jest.spyOn(getBootstrapData, 'applicationRoot');
@@ -233,14 +233,15 @@ describe('ResultSet', () => {
const table = getByTestId('table-container');
expect(table).toBeInTheDocument();
const firstColumn = queryAllByText(
query.results?.columns[0].column_name ?? '',
)[0];
const secondColumn = queryAllByText(
query.results?.columns[1].column_name ?? '',
)[0];
expect(firstColumn).toBeInTheDocument();
expect(secondColumn).toBeInTheDocument();
// AG Grid commits its header row after the initial render under React 19.
await waitFor(() => {
expect(
queryAllByText(query.results?.columns[0].column_name ?? '')[0],
).toBeInTheDocument();
expect(
queryAllByText(query.results?.columns[1].column_name ?? '')[0],
).toBeInTheDocument();
});
const exploreButton = getByTestId('explore-results-button');
expect(exploreButton).toBeInTheDocument();

View File

@@ -26,7 +26,7 @@ import { styled } from '@apache-superset/core/theme';
import { parseDate } from 'chrono-node';
import {
ModalTrigger,
ModalTriggerRef,
type ModalTriggerRef,
} from '@superset-ui/core/components/ModalTrigger';
import {
Input,
@@ -155,7 +155,7 @@ const ScheduleQueryButton: FunctionComponent<ScheduleQueryButtonProps> = ({
const [description, setDescription] = useState('');
const [label, setLabel] = useState(defaultLabel);
const [showSchedule, setShowSchedule] = useState(false);
const saveModal: ModalTriggerRef | null = useRef() as ModalTriggerRef;
const saveModal = useRef<ModalTriggerRef['current']>(null);
const onScheduleSubmit = ({
formData,
@@ -171,7 +171,7 @@ const ScheduleQueryButton: FunctionComponent<ScheduleQueryButtonProps> = ({
extra_json: JSON.stringify({ schedule_info: formData }),
};
onSchedule(query);
saveModal?.current?.close();
saveModal?.current?.close?.();
};
const renderModalBody = () => (

View File

@@ -50,7 +50,7 @@ jest.mock(
({
children,
}: {
children: (params: { height: number }) => React.ReactChild;
children: (params: { height: number }) => React.ReactNode;
}) =>
children({ height: 500 }),
);

View File

@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import type { ReactChild } from 'react';
import type { ReactNode } from 'react';
import fetchMock from 'fetch-mock';
import { render, screen, waitFor } from 'spec/helpers/testing-library';
import userEvent from '@testing-library/user-event';
@@ -32,7 +32,7 @@ import TableExploreTree from '.';
jest.mock(
'react-virtualized-auto-sizer',
() =>
({ children }: { children: (params: { height: number }) => ReactChild }) =>
({ children }: { children: (params: { height: number }) => ReactNode }) =>
children({ height: 500 }),
);

View File

@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { type ReactChild } from 'react';
import { type ReactNode } from 'react';
import fetchMock from 'fetch-mock';
import { table, initialState } from 'src/SqlLab/fixtures';
import {
@@ -42,7 +42,7 @@ jest.mock('src/components/FilterableTable', () => ({
jest.mock(
'react-virtualized-auto-sizer',
() =>
({ children }: { children: (params: { height: number }) => ReactChild }) =>
({ children }: { children: (params: { height: number }) => ReactNode }) =>
children({ height: 500 }),
);
jest.mock('@superset-ui/core/components/IconTooltip', () => ({

View File

@@ -36,5 +36,5 @@ export type PluginDeckglLayerVisibilityProps = PluginFilterStylesProps & {
data: (ColumnOption | ColumnData)[];
filterState: FilterState;
formData: DeckglLayerVisibilityFormData;
inputRef: RefObject<RefSelectProps>;
inputRef: RefObject<RefSelectProps | null>;
} & PluginFilterHooks;

View File

@@ -52,7 +52,7 @@ interface PluginFilterGroupByCustomizeProps {
canSelectMultiple?: boolean;
aggregation?: string;
enableEmptyFilter?: boolean;
inputRef?: RefObject<HTMLInputElement>;
inputRef?: RefObject<HTMLInputElement | null>;
}
export type PluginFilterGroupByQueryFormData = QueryFormData &
@@ -69,7 +69,7 @@ export type PluginFilterGroupByProps = PluginFilterStylesProps & {
data: (ColumnOption | ColumnData)[];
filterState: FilterState;
formData: PluginFilterGroupByQueryFormData;
inputRef: RefObject<RefSelectProps>;
inputRef: RefObject<RefSelectProps | null>;
} & PluginFilterHooks;
export const DEFAULT_FORM_DATA: PluginFilterGroupByCustomizeProps = {

View File

@@ -28,7 +28,7 @@ import { PluginFilterHooks, PluginFilterStylesProps } from '../types';
interface PluginFilterTimeColumnCustomizeProps {
defaultValue?: string[] | null;
inputRef?: RefObject<HTMLInputElement>;
inputRef?: RefObject<HTMLInputElement | null>;
}
export type PluginFilterTimeColumnQueryFormData = QueryFormData &
@@ -40,7 +40,7 @@ export type PluginFilterTimeColumnProps = PluginFilterStylesProps & {
data: DataRecord[];
filterState: FilterState;
formData: PluginFilterTimeColumnQueryFormData;
inputRef: RefObject<RefSelectProps>;
inputRef: RefObject<RefSelectProps | null>;
} & PluginFilterHooks;
export const DEFAULT_FORM_DATA: PluginFilterTimeColumnCustomizeProps = {

View File

@@ -23,7 +23,7 @@ import { PluginFilterHooks, PluginFilterStylesProps } from '../types';
interface PluginFilterTimeGrainCustomizeProps {
defaultValue?: string[] | null;
inputRef?: RefObject<HTMLInputElement>;
inputRef?: RefObject<HTMLInputElement | null>;
timeGrains?: string[];
}
@@ -35,7 +35,7 @@ export type PluginFilterTimeGrainProps = PluginFilterStylesProps & {
data: DataRecord[];
filterState: FilterState;
formData: PluginFilterTimeGrainQueryFormData;
inputRef: RefObject<RefSelectProps>;
inputRef: RefObject<RefSelectProps | null>;
} & PluginFilterHooks;
export const DEFAULT_FORM_DATA: PluginFilterTimeGrainCustomizeProps = {

View File

@@ -16,7 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
import { ErrorInfo, useCallback, useEffect, useRef } from 'react';
import {
ErrorInfo,
useCallback,
useEffect,
useRef,
type ReactElement,
} from 'react';
import { t } from '@apache-superset/core/translation';
import { logging } from '@apache-superset/core/utils';
import {
@@ -186,7 +192,7 @@ function Chart({
force = false,
isInView = true,
...restProps
}: ChartProps): JSX.Element {
}: ChartProps): ReactElement {
const {
actions,
chartId,

View File

@@ -92,7 +92,7 @@ const ChartContextMenu = (
displayedItems = ContextMenuItem.All,
additionalConfig,
}: ChartContextMenuProps,
ref: RefObject<ChartContextMenuRef>,
ref: RefObject<ChartContextMenuRef | null>,
) => {
const dispatch = useDispatch();
const theme = useTheme();

View File

@@ -26,6 +26,7 @@ import {
MouseEvent,
ReactNode,
memo,
type ReactElement,
} from 'react';
import {
SuperChart,
@@ -184,7 +185,7 @@ function ChartRendererComponent({
initialValues = BLANK,
setControlValue = () => {},
...restProps
}: ChartRendererProps): JSX.Element | null {
}: ChartRendererProps): ReactElement | null {
const {
annotationData,
actions,

View File

@@ -68,7 +68,11 @@ interface DataType {
// Must be outside of the main component due to problems in
// react-resize-detector with conditional rendering
// https://github.com/maslianok/react-resize-detector/issues/178
function Resizable({ children }: { children: ReactElement }) {
function Resizable({
children,
}: {
children: ReactElement<{ height?: number }>;
}) {
const { ref, height } = useResizeDetector();
return (
<div ref={ref} css={{ flex: 1 }}>

Some files were not shown because too many files have changed in this diff Show More