diff --git a/packages/dev/eslint-plugin-rsp-rules/index.js b/packages/dev/eslint-plugin-rsp-rules/index.js
index 6b664237fe6..d8fdae524f4 100644
--- a/packages/dev/eslint-plugin-rsp-rules/index.js
+++ b/packages/dev/eslint-plugin-rsp-rules/index.js
@@ -1,9 +1,13 @@
let noGetByRoleToThrow = require('./rules/no-getByRole-toThrow');
let actEventsTest = require('./rules/act-events-test');
+let noReactKey = require('./rules/no-react-key');
+let sortImports = require('./rules/sort-imports');
const rules = {
'act-events-test': actEventsTest,
- 'no-getByRole-toThrow': noGetByRoleToThrow
+ 'no-getByRole-toThrow': noGetByRoleToThrow,
+ 'no-react-key': noReactKey,
+ 'sort-imports': sortImports
};
diff --git a/packages/dev/eslint-plugin-rsp-rules/rules/no-react-key.js b/packages/dev/eslint-plugin-rsp-rules/rules/no-react-key.js
new file mode 100644
index 00000000000..9cc1e22914b
--- /dev/null
+++ b/packages/dev/eslint-plugin-rsp-rules/rules/no-react-key.js
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2023 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+
+module.exports = {
+ meta: {
+ type: 'suggestion',
+ docs: {
+ description: 'Checks and fixes usage of React.Key'
+ },
+ fixable: 'code',
+ schema: [] // no options
+ },
+ create: function (context) {
+ return {
+ // Could be improved to look up the local name of Key and preserve it
+ ImportSpecifier(node) {
+ if (node.imported.name === 'Key' && node.parent.source.value === 'react') {
+ context.report({
+ node,
+ message: 'Do not use React.Key. Instead, use ReactAria.Key.',
+ fix: (fixer) => {
+ let defaultSpecifier = node.parent.specifiers.find(node => node.type === 'ImportDefaultSpecifier');
+ let fixes = [];
+ if (node.parent.specifiers.length === 1) {
+ // covers case 'import {Key} from 'react';'
+ fixes.push(fixer.remove(node.parent));
+ } else if (node.parent.specifiers.filter(node => node.type === 'ImportSpecifier').length === 1) {
+ // covers case 'import React, {Key} from 'react';'
+ fixes.push(fixer.removeRange([defaultSpecifier.range[1], node.range[1] + 1]));
+ } else if (node.parent.specifiers.filter(node => node.type === 'ImportSpecifier').length > 1) {
+ // covers case 'import {Foo, Key} from 'react';'
+ if (node.parent.specifiers[node.parent.specifiers.length - 1] === node) {
+ fixes.push(fixer.removeRange([node.range[0] - 2, node.range[1]]));
+ } else {
+ // and case 'import {Key, ReactElement, ReactNode} from 'react';'
+ fixes.push(fixer.removeRange([node.range[0], node.range[1] + 2]));
+ }
+ }
+ let sharedImport = node.parent.parent.body.find(node => node.type === 'ImportDeclaration' && node.source.value === '@react-types/shared');
+ if (sharedImport) {
+ // handles existing import from '@react-types/shared'
+ let firstSpecifier = sharedImport.specifiers.find(node => node.type === 'ImportSpecifier');
+ fixes.push(fixer.insertTextAfter(firstSpecifier, ', Key'));
+ return fixes;
+ }
+ // handles no existing import from '@react-types/shared'
+ let lastImport = node.parent.parent.body.findLast(node => node.type === 'ImportDeclaration');
+ fixes.push(fixer.insertTextAfter(lastImport, "\nimport {Key} from '@react-types/shared';"));
+ return fixes;
+ }
+ });
+ }
+ },
+ Identifier(node) {
+ // Could be improved by looking up the local name of React
+ if (node.name === 'Key' && (node.parent?.object?.name === 'React' || node.parent?.left?.name === 'React')) {
+ context.report({
+ node,
+ message: 'Do not use React.Key. Instead, use ReactAria.Key.'
+ });
+ }
+ }
+ };
+ }
+};
diff --git a/bin/sort-imports.js b/packages/dev/eslint-plugin-rsp-rules/rules/sort-imports.js
similarity index 100%
rename from bin/sort-imports.js
rename to packages/dev/eslint-plugin-rsp-rules/rules/sort-imports.js
diff --git a/packages/dev/eslint-plugin-rsp-rules/test/no-react-key.test.js b/packages/dev/eslint-plugin-rsp-rules/test/no-react-key.test.js
new file mode 100644
index 00000000000..e5e38b462be
--- /dev/null
+++ b/packages/dev/eslint-plugin-rsp-rules/test/no-react-key.test.js
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2023 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+
+import noReactKeyRule from '../rules/no-react-key';
+import {RuleTester} from 'eslint';
+
+
+const ruleTester = new RuleTester({
+ // Must use at least ecmaVersion 2015 because
+ // that's when `const` variables were introduced.
+ parserOptions: {
+ ecmaVersion: 2015,
+ 'sourceType': 'module'
+ }
+});
+
+// Throws error if the tests in ruleTester.run() do not pass
+ruleTester.run(
+ 'no-react-key', // rule name
+ noReactKeyRule, // rule code
+ { // checks
+ // 'valid' checks cases that should pass
+ valid: [{
+ code: "import {Key} from '@react-types/shared';"
+ }],
+ // 'invalid' checks cases that should not pass
+ invalid: [{
+ code: "import {Key} from 'react';",
+ output: `
+import {Key} from '@react-types/shared';`,
+ errors: 1
+ }, {
+ code: "import React, {Key} from 'react';",
+ output: `import React from 'react';
+import {Key} from '@react-types/shared';`,
+ errors: 1
+ }, {
+ code: `import React, {Key, useState} from 'react';
+import {Foo} from 'bar';
+
+let a = 'a';`,
+ output: `import React, {useState} from 'react';
+import {Foo} from 'bar';
+import {Key} from '@react-types/shared';
+
+let a = 'a';`,
+ errors: 1
+ }, {
+ code: "import {Key, ReactElement, ReactNode} from 'react';",
+ output: `import {ReactElement, ReactNode} from 'react';
+import {Key} from '@react-types/shared';`,
+ errors: 1
+ }, {
+ code: "import {HTMLAttributes, Key, RefObject} from 'react';",
+ output: `import {HTMLAttributes, RefObject} from 'react';
+import {Key} from '@react-types/shared';`,
+ errors: 1
+ }, {
+ code: `
+import {foo} from '@react-types/shared';
+import {Key} from 'react';`,
+ output: `
+import {foo, Key} from '@react-types/shared';
+`,
+ errors: 1
+ }, {
+ code: `
+import {Node} from '@react-types/shared';
+import React, {Fragment, Key} from 'react';
+`,
+ output: `
+import {Node, Key} from '@react-types/shared';
+import React, {Fragment} from 'react';
+`,
+ errors: 1
+ }, {
+ code: `
+import React from 'react';
+let a = React.Key;
+`,
+ errors: 1
+ }, {
+ code: `
+import React from 'react';
+let a = useState
(null);
+`,
+ errors: 1
+ }]
+ }
+);
diff --git a/packages/dev/eslint-plugin-rsp-rules/test/sort-imports.test.js b/packages/dev/eslint-plugin-rsp-rules/test/sort-imports.test.js
new file mode 100644
index 00000000000..5d60fa9a713
--- /dev/null
+++ b/packages/dev/eslint-plugin-rsp-rules/test/sort-imports.test.js
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2023 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+
+import {RuleTester} from 'eslint';
+import sortImportsRule from '../rules/sort-imports';
+
+
+const ruleTester = new RuleTester({
+ // Must use at least ecmaVersion 2015 because
+ // that's when `const` variables were introduced.
+ parserOptions: {
+ ecmaVersion: 2015,
+ 'sourceType': 'module'
+ }
+});
+
+// Throws error if the tests in ruleTester.run() do not pass
+ruleTester.run(
+ 'no-react-key', // rule name
+ sortImportsRule, // rule code
+ { // checks
+ // 'valid' checks cases that should pass
+ valid: [{
+ code: "import {A, B} from 'foo';"
+ }, {
+ code: `
+import {A} from 'foo';
+import {B} from 'bar';
+`
+ }],
+ // 'invalid' checks cases that should not pass
+ invalid: [{
+ code: "import {B, A} from 'foo';",
+ output: "import {A, B} from 'foo';",
+ errors: 1
+ }
+ // we don't support this case yet
+// {
+// code: `
+// import {B} from 'bar';
+// import {A} from 'foo';
+// `,
+// output: `
+// import {A} from 'foo';
+// import {B} from 'bar';
+// `,
+// errors: 1
+// }
+ ]
+ }
+);
diff --git a/packages/dev/parcel-transformer-docs/DocsTransformer.js b/packages/dev/parcel-transformer-docs/DocsTransformer.js
index 39af957a14f..bb48e794656 100644
--- a/packages/dev/parcel-transformer-docs/DocsTransformer.js
+++ b/packages/dev/parcel-transformer-docs/DocsTransformer.js
@@ -296,6 +296,12 @@ module.exports = new Transformer({
}
}
+ if (left.name === undefined) {
+ return Object.assign(node, {
+ type: 'identifier',
+ name: path.node.left.name + '.' + path.node.right.name
+ });
+ }
return Object.assign(node, {
type: 'identifier',
name: left.name + '.' + path.node.right.name
diff --git a/packages/dev/parcel-transformer-docs/__tests__/DocsTransformer.parceltest.tsx b/packages/dev/parcel-transformer-docs/__tests__/DocsTransformer.parceltest.tsx
index 505950368ae..e17116d2a15 100644
--- a/packages/dev/parcel-transformer-docs/__tests__/DocsTransformer.parceltest.tsx
+++ b/packages/dev/parcel-transformer-docs/__tests__/DocsTransformer.parceltest.tsx
@@ -205,7 +205,7 @@ describe('DocsTransformer - API', () => {
`);
await writeSourceFile('index', `
import {Column, SpectrumColumnProps} from './column';
- const SpectrumColumn = Column as (props: SpectrumColumnProps) => JSX.Element;
+ const SpectrumColumn = Column as (props: SpectrumColumnProps) => React.JSX.Element;
export {SpectrumColumn as Column};
`);
let code = await runBuild();
diff --git a/packages/react-aria-components/docs/Breadcrumbs.mdx b/packages/react-aria-components/docs/Breadcrumbs.mdx
index 6aa2e45d1d8..01dc3d85ae3 100644
--- a/packages/react-aria-components/docs/Breadcrumbs.mdx
+++ b/packages/react-aria-components/docs/Breadcrumbs.mdx
@@ -179,6 +179,7 @@ as shown below, can be used when the options come from an external data source s
As seen below, an iterable list of options is passed to the Breadcrumbs using the `items` prop. A function provided as `children` of the `` is called to render each item. When a breadcrumb is pressed, the `onAction` event is triggered and the breadcrumbs array is updated.
```tsx example
+import {Key} from '@react-types/shared';
function Example() {
let [breadcrumbs, setBreadcrumbs] = React.useState([
{id: 1, label: 'Home'},
@@ -186,7 +187,7 @@ function Example() {
{id: 3, label: 'March 2022 Assets'}
]);
- let navigate = (id: React.Key) => {
+ let navigate = (id: Key) => {
let i = breadcrumbs.findIndex(item => item.id === id);
setBreadcrumbs(breadcrumbs.slice(0, i + 1));
};
@@ -378,7 +379,7 @@ function Router({children}) {
]);
// Pop stack when a breadcrumb item is clicked.
- let onAction = (id: React.Key) => {
+ let onAction = (id: Key) => {
let i = items.findIndex(item => item.id === id);
setItems(items.slice(0, i + 1));
};
diff --git a/packages/react-aria-components/docs/ComboBox.mdx b/packages/react-aria-components/docs/ComboBox.mdx
index 227e6f967b6..6b0128bb6b3 100644
--- a/packages/react-aria-components/docs/ComboBox.mdx
+++ b/packages/react-aria-components/docs/ComboBox.mdx
@@ -413,6 +413,7 @@ is passed to the `onSelectionChange` handler to identify the selected item. Alte
as shown in the example below, then this is used automatically and an `id` prop is not required.
```tsx example
+import {Key} from '@react-types/shared';
function Example() {
let options = [
{id: 1, name: 'Aerospace'},
@@ -425,7 +426,7 @@ function Example() {
{id: 8, name: 'Agricultural'},
{id: 9, name: 'Electrical'}
];
- let [majorId, setMajorId] = React.useState(null);
+ let [majorId, setMajorId] = React.useState(null);
return (
<>
@@ -550,7 +551,7 @@ function Example() {
{id: 8, name: 'Adobe Fresco'},
{id: 9, name: 'Adobe Dreamweaver'}
];
- let [productId, setProductId] = React.useState(9);
+ let [productId, setProductId] = React.useState(9);
return (
@@ -842,7 +843,7 @@ function ControlledComboBox() {
inputValue: ''
});
- let onSelectionChange = (id: React.Key) => {
+ let onSelectionChange = (id: Key) => {
setFieldState({
inputValue: options.find(o => o.id === id)?.name ?? '',
selectedKey: id
@@ -1003,7 +1004,7 @@ The `description` slot can be used to associate additional help text with a Comb
```tsx example
function Example() {
- let [animalId, setAnimalId] = React.useState
(null);
+ let [animalId, setAnimalId] = React.useState(null);
let options = [
{ id: 1, name: 'Aardvark' },
{ id: 2, name: 'Cat' },
diff --git a/packages/react-aria-components/docs/Select.mdx b/packages/react-aria-components/docs/Select.mdx
index bfca5882a0e..892123ef79b 100644
--- a/packages/react-aria-components/docs/Select.mdx
+++ b/packages/react-aria-components/docs/Select.mdx
@@ -447,6 +447,7 @@ When `Select` is used with a dynamic collection as described above, the id of ea
See the `react-stately` [Selection docs](../react-stately/selection.html) for more details.
```tsx example
+import {Key} from '@react-types/shared';
function Example() {
let options = [
{name: 'Koala'},
@@ -456,7 +457,7 @@ function Example() {
{name: 'Bison'},
{name: 'Skunk'}
];
- let [animal, setAnimal] = React.useState("Bison");
+ let [animal, setAnimal] = React.useState("Bison");
return (
(null);
+ let [animalId, setAnimalId] = React.useState(null);
let options = [
{ id: 1, name: 'Aardvark' },
{ id: 2, name: 'Cat' },
diff --git a/packages/react-aria-components/docs/Tabs.mdx b/packages/react-aria-components/docs/Tabs.mdx
index dfae090be10..6196e619543 100644
--- a/packages/react-aria-components/docs/Tabs.mdx
+++ b/packages/react-aria-components/docs/Tabs.mdx
@@ -253,8 +253,9 @@ See the `react-stately` [Selection docs](../react-stately/selection.html) for mo
Selection can be controlled using the `selectedKey` prop, paired with the `onSelectionChange` event. The `id` prop from the selected tab will be passed into the callback when the tab is selected, allowing you to update state accordingly.
```tsx example
+import {Key} from '@react-types/shared';
function Example() {
- let [timePeriod, setTimePeriod] = React.useState('triassic');
+ let [timePeriod, setTimePeriod] = React.useState('triassic');
return (
<>
diff --git a/packages/react-aria-components/src/Breadcrumbs.tsx b/packages/react-aria-components/src/Breadcrumbs.tsx
index b3bea95cb39..6530eed75dc 100644
--- a/packages/react-aria-components/src/Breadcrumbs.tsx
+++ b/packages/react-aria-components/src/Breadcrumbs.tsx
@@ -14,8 +14,9 @@ import {Collection, Node} from 'react-stately';
import {CollectionProps, useCollection, useSSRCollectionNode} from './Collection';
import {ContextValue, forwardRefType, SlotProps, StyleProps, useContextProps} from './utils';
import {filterDOMProps} from '@react-aria/utils';
+import {Key} from '@react-types/shared';
import {LinkContext} from './Link';
-import React, {createContext, ForwardedRef, forwardRef, Key, ReactNode, RefObject} from 'react';
+import React, {createContext, ForwardedRef, forwardRef, ReactNode, RefObject} from 'react';
export interface BreadcrumbsProps extends Omit, 'disabledKeys'>, AriaBreadcrumbsProps, StyleProps, SlotProps {
/** Whether the breadcrumbs are disabled. */
@@ -78,7 +79,7 @@ export interface BreadcrumbProps extends StyleProps {
children: ReactNode
}
-function Breadcrumb(props: BreadcrumbProps, ref: ForwardedRef): JSX.Element | null {
+function Breadcrumb(props: BreadcrumbProps, ref: ForwardedRef): React.JSX.Element | null {
return useSSRCollectionNode('item', props, ref, props.children);
}
diff --git a/packages/react-aria-components/src/Collection.tsx b/packages/react-aria-components/src/Collection.tsx
index b979fc7ab02..27ae5f02205 100644
--- a/packages/react-aria-components/src/Collection.tsx
+++ b/packages/react-aria-components/src/Collection.tsx
@@ -9,12 +9,12 @@
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
-import {CollectionBase} from '@react-types/shared';
+import {CollectionBase, Key} from '@react-types/shared';
import {createPortal} from 'react-dom';
import {forwardRefType, StyleProps} from './utils';
import {Collection as ICollection, Node, SelectionBehavior, SelectionMode, SectionProps as SharedSectionProps} from 'react-stately';
import {mergeProps, useIsSSR} from 'react-aria';
-import React, {cloneElement, createContext, ForwardedRef, forwardRef, Key, ReactElement, ReactNode, useCallback, useContext, useMemo, useRef} from 'react';
+import React, {cloneElement, createContext, ForwardedRef, forwardRef, ReactElement, ReactNode, useCallback, useContext, useMemo, useRef} from 'react';
import {useSyncExternalStore as useSyncExternalStoreShim} from 'use-sync-external-store/shim/index.js';
// This Collection implementation is perhaps a little unusual. It works by rendering the React tree into a
@@ -892,7 +892,7 @@ export interface SectionProps extends Omit, 'children'
children?: ReactNode | ((item: T) => ReactElement)
}
-function Section(props: SectionProps, ref: ForwardedRef): JSX.Element | null {
+function Section(props: SectionProps, ref: ForwardedRef): React.JSX.Element | null {
let children = useCollectionChildren(props);
return useSSRCollectionNode('section', props, ref, null, children);
}
@@ -904,7 +904,7 @@ export const CollectionContext = createContext |
export const CollectionRendererContext = createContext['children']>(null);
/** A Collection renders a list of items, automatically managing caching and keys. */
-export function Collection(props: CollectionProps): JSX.Element {
+export function Collection(props: CollectionProps): React.JSX.Element {
let ctx = useContext(CollectionContext)!;
props = mergeProps(ctx, props);
let renderer = typeof props.children === 'function' ? props.children : null;
diff --git a/packages/react-aria-components/src/DateField.tsx b/packages/react-aria-components/src/DateField.tsx
index fd3f928008f..15d9a9378e2 100644
--- a/packages/react-aria-components/src/DateField.tsx
+++ b/packages/react-aria-components/src/DateField.tsx
@@ -201,7 +201,7 @@ export interface DateInputProps extends SlotProps, StyleRenderProps ReactElement
}
-function DateInput(props: DateInputProps, ref: ForwardedRef): JSX.Element {
+function DateInput(props: DateInputProps, ref: ForwardedRef): React.JSX.Element {
// If state is provided by DateField/TimeField, just render.
// Otherwise (e.g. in DatePicker), we need to call hooks and create state ourselves.
let dateFieldState = useContext(DateFieldStateContext);
diff --git a/packages/react-aria-components/src/GridList.tsx b/packages/react-aria-components/src/GridList.tsx
index 48c4346ece2..a6daa5b7ab7 100644
--- a/packages/react-aria-components/src/GridList.tsx
+++ b/packages/react-aria-components/src/GridList.tsx
@@ -17,9 +17,9 @@ import {CollectionProps, ItemRenderProps, useCachedChildren, useCollection, useS
import {ContextValue, defaultSlot, forwardRefType, Provider, RenderProps, SlotProps, StyleRenderProps, useContextProps, useRenderProps} from './utils';
import {DragAndDropContext, DragAndDropHooks, DropIndicator, DropIndicatorContext, DropIndicatorProps} from './useDragAndDrop';
import {filterDOMProps, useObjectRef} from '@react-aria/utils';
-import {LinkDOMProps} from '@react-types/shared';
+import {Key, LinkDOMProps} from '@react-types/shared';
import {ListStateContext} from './ListBox';
-import React, {createContext, ForwardedRef, forwardRef, HTMLAttributes, Key, ReactNode, RefObject, useContext, useEffect, useRef} from 'react';
+import React, {createContext, ForwardedRef, forwardRef, HTMLAttributes, ReactNode, RefObject, useContext, useEffect, useRef} from 'react';
import {TextContext} from './Text';
export interface GridListRenderProps {
@@ -119,7 +119,7 @@ function GridListInner({props, collection, gridListRef: ref}:
let dropState: DroppableCollectionState | undefined = undefined;
let droppableCollection: DroppableCollectionResult | undefined = undefined;
let isRootDropTarget = false;
- let dragPreview: JSX.Element | null = null;
+ let dragPreview: React.JSX.Element | null = null;
let preview = useRef(null);
if (isListDraggable && dragAndDropHooks) {
diff --git a/packages/react-aria-components/src/ListBox.tsx b/packages/react-aria-components/src/ListBox.tsx
index d7009e5322b..c4ba450e028 100644
--- a/packages/react-aria-components/src/ListBox.tsx
+++ b/packages/react-aria-components/src/ListBox.tsx
@@ -17,8 +17,8 @@ import {DragAndDropContext, DragAndDropHooks, DropIndicator, DropIndicatorContex
import {DraggableCollectionState, DroppableCollectionState, ListState, Node, Orientation, SelectionBehavior, useListState} from 'react-stately';
import {filterDOMProps, mergeRefs, useObjectRef} from '@react-aria/utils';
import {Header} from './Header';
-import {LinkDOMProps} from '@react-types/shared';
-import React, {createContext, ForwardedRef, forwardRef, Key, ReactNode, RefObject, useContext, useEffect, useMemo, useRef} from 'react';
+import {Key, LinkDOMProps} from '@react-types/shared';
+import React, {createContext, ForwardedRef, forwardRef, ReactNode, RefObject, useContext, useEffect, useMemo, useRef} from 'react';
import {Separator, SeparatorContext} from './Separator';
import {TextContext} from './Text';
@@ -137,7 +137,7 @@ function ListBoxInner({state, props, listBoxRef}: ListBoxInnerProps) {
collection,
collator,
ref: listBoxRef,
- disabledKeys: disabledBehavior === 'selection' ? new Set() : disabledKeys,
+ disabledKeys: disabledBehavior === 'selection' ? new Set() : disabledKeys,
layout,
orientation,
direction
@@ -181,7 +181,7 @@ function ListBoxInner({state, props, listBoxRef}: ListBoxInnerProps) {
let dropState: DroppableCollectionState | undefined = undefined;
let droppableCollection: DroppableCollectionResult | undefined = undefined;
let isRootDropTarget = false;
- let dragPreview: JSX.Element | null = null;
+ let dragPreview: React.JSX.Element | null = null;
let preview = useRef(null);
if (isListDraggable && dragAndDropHooks) {
@@ -229,7 +229,7 @@ function ListBoxInner({state, props, listBoxRef}: ListBoxInnerProps) {
values: renderValues
});
- let emptyState: JSX.Element | null = null;
+ let emptyState: React.JSX.Element | null = null;
if (state.collection.size === 0 && props.renderEmptyState) {
emptyState = (
(props: SelectValueProps
, ref: Forwarde
: null;
let rendered = selectedItem?.rendered;
if (typeof rendered === 'function') {
- // If the selected item has a function as a child, we need to call it to render to JSX.
+ // If the selected item has a function as a child, we need to call it to render to React.JSX.
let fn = rendered as (s: ItemRenderProps) => ReactNode;
rendered = fn({
isHovered: false,
diff --git a/packages/react-aria-components/src/Table.tsx b/packages/react-aria-components/src/Table.tsx
index 965555c1bb8..99b223248bc 100644
--- a/packages/react-aria-components/src/Table.tsx
+++ b/packages/react-aria-components/src/Table.tsx
@@ -1,4 +1,4 @@
-import {AriaLabelingProps, LinkDOMProps} from '@react-types/shared';
+import {AriaLabelingProps, Key, LinkDOMProps} from '@react-types/shared';
import {BaseCollection, CollectionContext, CollectionProps, CollectionRendererContext, ItemRenderProps, NodeValue, useCachedChildren, useCollection, useCollectionChildren, useSSRCollectionNode} from './Collection';
import {buildHeaderRows, TableColumnResizeState} from '@react-stately/table';
import {ButtonContext} from './Button';
@@ -12,7 +12,7 @@ import {filterDOMProps, useLayoutEffect, useObjectRef, useResizeObserver} from '
import {GridNode} from '@react-types/grid';
// @ts-ignore
import intlMessages from '../intl/*.json';
-import React, {createContext, ForwardedRef, forwardRef, Key, ReactElement, ReactNode, RefObject, useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react';
+import React, {createContext, ForwardedRef, forwardRef, ReactElement, ReactNode, RefObject, useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react';
import ReactDOM from 'react-dom';
class TableCollection extends BaseCollection implements ITableCollection {
@@ -324,7 +324,7 @@ function Table(props: TableProps, ref: ForwardedRef) {
let dropState: DroppableCollectionState | undefined = undefined;
let droppableCollection: DroppableCollectionResult | undefined = undefined;
let isRootDropTarget = false;
- let dragPreview: JSX.Element | null = null;
+ let dragPreview: React.JSX.Element | null = null;
let preview = useRef(null);
if (isListDraggable && dragAndDropHooks) {
@@ -547,7 +547,7 @@ export interface ColumnProps extends RenderProps
maxWidth?: ColumnStaticSize | null
}
-function Column(props: ColumnProps, ref: ForwardedRef): JSX.Element | null {
+function Column(props: ColumnProps, ref: ForwardedRef): React.JSX.Element | null {
let render = useContext(CollectionRendererContext);
let childColumns: ReactNode | ((item: T) => ReactNode);
if (typeof render === 'function') {
@@ -588,7 +588,7 @@ export interface TableBodyProps extends CollectionProps, StyleRenderProps<
renderEmptyState?: (props: TableBodyRenderProps) => ReactNode
}
-function TableBody(props: TableBodyProps, ref: ForwardedRef): JSX.Element | null {
+function TableBody(props: TableBodyProps, ref: ForwardedRef): React.JSX.Element | null {
let children = useCollectionChildren(props);
return useSSRCollectionNode('tablebody', props, ref, null, children);
}
@@ -611,7 +611,7 @@ export interface RowProps extends StyleRenderProps, LinkDOMPr
textValue?: string
}
-function Row(props: RowProps, ref: ForwardedRef): JSX.Element | null {
+function Row(props: RowProps, ref: ForwardedRef): React.JSX.Element | null {
let children = useCollectionChildren({
children: props.children,
items: props.columns,
@@ -662,7 +662,7 @@ export interface CellProps extends RenderProps {
textValue?: string
}
-function Cell(props: CellProps, ref: ForwardedRef): JSX.Element | null {
+function Cell(props: CellProps, ref: ForwardedRef): React.JSX.Element | null {
return useSSRCollectionNode('cell', props, ref, props.children);
}
diff --git a/packages/react-aria-components/src/Tabs.tsx b/packages/react-aria-components/src/Tabs.tsx
index a92d40b139c..abdc03b8a40 100644
--- a/packages/react-aria-components/src/Tabs.tsx
+++ b/packages/react-aria-components/src/Tabs.tsx
@@ -10,13 +10,13 @@
* governing permissions and limitations under the License.
*/
-import {AriaLabelingProps, LinkDOMProps} from '@react-types/shared';
+import {AriaLabelingProps, Key, LinkDOMProps} from '@react-types/shared';
import {AriaTabListProps, AriaTabPanelProps, mergeProps, Orientation, useFocusRing, useHover, useTab, useTabList, useTabPanel} from 'react-aria';
import {Collection, Node, TabListState, useTabListState} from 'react-stately';
import {CollectionDocumentContext, CollectionPortal, CollectionProps, useCollectionDocument, useSSRCollectionNode} from './Collection';
import {ContextValue, createHideableComponent, forwardRefType, Hidden, Provider, RenderProps, SlotProps, StyleRenderProps, useContextProps, useRenderProps, useSlottedContext} from './utils';
import {filterDOMProps, useObjectRef} from '@react-aria/utils';
-import React, {createContext, ForwardedRef, forwardRef, Key, RefObject, useContext, useMemo} from 'react';
+import React, {createContext, ForwardedRef, forwardRef, RefObject, useContext, useMemo} from 'react';
export interface TabsProps extends Omit, 'items' | 'children'>, RenderProps, SlotProps {}
@@ -191,7 +191,7 @@ function TabsInner({props, tabsRef: ref, collection}: TabsInnerProps) {
const _Tabs = /*#__PURE__*/ (forwardRef as forwardRefType)(Tabs);
export {_Tabs as Tabs};
-function TabList(props: TabListProps, ref: ForwardedRef