diff --git a/babel.config.json b/babel.config.json index 6815ebd872..f2421ecf77 100644 --- a/babel.config.json +++ b/babel.config.json @@ -1,14 +1,14 @@ { "presets": [ ["@babel/preset-env", { "modules": false } ], - ["@babel/preset-react", { "useSpread": true } ], + ["@babel/preset-react", { "useSpread": true, "runtime": "automatic" } ], "@babel/preset-typescript" ], "env": { "test": { "presets": [ ["@babel/preset-env", {}], - ["@babel/preset-react", { "useSpread": true } ], + ["@babel/preset-react", { "useSpread": true, "runtime": "automatic" } ], "@babel/preset-typescript" ] } diff --git a/src/Carousel/index.jsx b/src/Carousel/index.jsx index ef37322519..74f2247a30 100644 --- a/src/Carousel/index.jsx +++ b/src/Carousel/index.jsx @@ -1,4 +1,5 @@ -import React from 'react'; +// React import needed to support JSX outside functions, if removed build-docs will fail +import React, { forwardRef } from 'react'; import PropTypes from 'prop-types'; import BaseCarousel from 'react-bootstrap/Carousel'; import BaseCarouselItem from 'react-bootstrap/CarouselItem'; @@ -7,11 +8,11 @@ import BaseCarouselCaption from 'react-bootstrap/CarouselCaption'; export const CAROUSEL_NEXT_LABEL_TEXT = 'Next'; export const CAROUSEL_PREV_LABEL_TEXT = 'Previous'; -const Carousel = React.forwardRef((props, ref) => ); +const Carousel = forwardRef((props, ref) => ); -const CarouselItem = React.forwardRef((props, ref) => ); +const CarouselItem = forwardRef((props, ref) => ); -const CarouselCaption = React.forwardRef((props, ref) => ); +const CarouselCaption = forwardRef((props, ref) => ); Carousel.propTypes = { /** Specifies element type for this component. */ diff --git a/src/Chip/Chip.test.tsx b/src/Chip/Chip.test.tsx index 1624e62d36..6ef63417b8 100644 --- a/src/Chip/Chip.test.tsx +++ b/src/Chip/Chip.test.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import type { ComponentProps } from 'react'; import renderer from 'react-test-renderer'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; @@ -7,7 +7,7 @@ import { Close } from '../../icons'; import { STYLE_VARIANTS } from './constants'; import Chip from '.'; -function TestChip(props: Omit, 'children'>) { +function TestChip(props: Omit, 'children'>) { return ( Test diff --git a/src/Chip/ChipIcon.tsx b/src/Chip/ChipIcon.tsx index 8ef97ef1ee..10c36d1d9f 100644 --- a/src/Chip/ChipIcon.tsx +++ b/src/Chip/ChipIcon.tsx @@ -1,4 +1,5 @@ -import React, { KeyboardEventHandler, MouseEventHandler } from 'react'; +import type { ComponentType } from 'react'; +import { KeyboardEventHandler, MouseEventHandler } from 'react'; import PropTypes from 'prop-types'; import Icon from '../Icon'; import IconButton from '../IconButton'; @@ -6,7 +7,7 @@ import { STYLE_VARIANTS } from './constants'; export type ChipIconProps = { className: string, - src: React.ComponentType, + src: ComponentType, variant: typeof STYLE_VARIANTS[keyof typeof STYLE_VARIANTS], disabled?: boolean, } & ( diff --git a/src/Chip/index.tsx b/src/Chip/index.tsx index 79065e5ac0..f1aad30984 100644 --- a/src/Chip/index.tsx +++ b/src/Chip/index.tsx @@ -1,4 +1,7 @@ -import React, { ForwardedRef, KeyboardEventHandler, MouseEventHandler } from 'react'; +import type { ReactNode, ComponentType } from 'react'; +import { + forwardRef, ForwardedRef, KeyboardEventHandler, MouseEventHandler, +} from 'react'; import classNames from 'classnames'; import ChipIcon from './ChipIcon'; import { STYLE_VARIANTS } from './constants'; @@ -7,7 +10,7 @@ export const CHIP_PGN_CLASS = 'pgn__chip'; export interface IChip { /** Specifies the content of the `Chip`. */ - children: React.ReactNode, + children: ReactNode, /** Click handler for the whole `Chip`, has effect only when Chip does not have any interactive icons. */ onClick?: KeyboardEventHandler & MouseEventHandler, /** Specifies an additional `className` to add to the base element. */ @@ -20,7 +23,7 @@ export interface IChip { * * `import { Check } from '@openedx/paragon/icons';` */ - iconBefore?: React.ComponentType, + iconBefore?: ComponentType, /** Specifies icon alt text. */ iconBeforeAlt?: string, /** @@ -29,7 +32,7 @@ export interface IChip { * * `import { Check } from '@openedx/paragon/icons';` */ - iconAfter?: React.ComponentType, + iconAfter?: ComponentType, /** Specifies icon alt text. */ iconAfterAlt?: string, /** A click handler for the `Chip` icon before. */ @@ -42,7 +45,7 @@ export interface IChip { isSelected?: boolean, } -const Chip = React.forwardRef(({ +const Chip = forwardRef(({ children, className, variant = 'light', diff --git a/src/ChipCarousel/ChipCarousel.test.jsx b/src/ChipCarousel/ChipCarousel.test.jsx index 76e05ab252..ba2c59864f 100644 --- a/src/ChipCarousel/ChipCarousel.test.jsx +++ b/src/ChipCarousel/ChipCarousel.test.jsx @@ -1,6 +1,5 @@ /* eslint-disable jsx-a11y/click-events-have-key-events */ /* eslint-disable jsx-a11y/no-static-element-interactions */ -import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { IntlProvider } from 'react-intl'; diff --git a/src/ChipCarousel/index.tsx b/src/ChipCarousel/index.tsx index 062a21a347..415eee7053 100644 --- a/src/ChipCarousel/index.tsx +++ b/src/ChipCarousel/index.tsx @@ -1,4 +1,5 @@ -import React, { ForwardedRef } from 'react'; +import type { ReactElement } from 'react'; +import { forwardRef, createElement, ForwardedRef } from 'react'; import PropTypes from 'prop-types'; import { useIntl } from 'react-intl'; import classNames from 'classnames'; @@ -22,7 +23,7 @@ export interface OverflowScrollContextProps { export interface ChipCarouselProps { className?: string; - items: Array; + items: Array; ariaLabel: string; disableOpacityMasks?: boolean; onScrollPrevious?: () => void; @@ -33,7 +34,7 @@ export interface ChipCarouselProps { gap?: number; } -const ChipCarousel = React.forwardRef(({ +const ChipCarousel = forwardRef(({ className, items, ariaLabel, @@ -49,32 +50,33 @@ const ChipCarousel = React.forwardRef(({ const intl = useIntl(); return ( -
- - - {({ - setOverflowRef, - isScrolledToStart, - isScrolledToEnd, - scrollToPrevious, - scrollToNext, - }: OverflowScrollContextProps) => ( - <> + + + {({ + setOverflowRef, + isScrolledToStart, + isScrolledToEnd, + scrollToPrevious, + scrollToNext, + }: OverflowScrollContextProps) => ( <> - {!isScrolledToStart && ( + <> + {!isScrolledToStart && ( - )} - {!isScrolledToEnd && ( + )} + {!isScrolledToEnd && ( - )} + )} + +
+ + {items?.map((item, id) => { + const { children } = item?.props || {}; + if (!children) { + return null; + } + // eslint-disable-next-line react/no-array-index-key + return createElement(Chip, { ...item.props, key: id }); + })} + +
-
- - {items?.map((item, id) => { - const { children } = item?.props || {}; - if (!children) { - return null; - } - // eslint-disable-next-line react/no-array-index-key - return React.createElement(Chip, { ...item.props, key: id }); - })} - -
- - )} -
-
-
+ )} + + + + ) ); }); diff --git a/src/Collapsible/Collapsible.test.jsx b/src/Collapsible/Collapsible.test.jsx index d64d9103d2..8b722b6e45 100644 --- a/src/Collapsible/Collapsible.test.jsx +++ b/src/Collapsible/Collapsible.test.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import { createRef } from 'react'; import { render, screen, waitFor } from '@testing-library/react'; import renderer from 'react-test-renderer'; import userEvent from '@testing-library/user-event'; @@ -69,7 +69,7 @@ describe('', () => { }); describe('Imperative Methods', () => { - const ref = React.createRef(); + const ref = createRef(); beforeEach(() => { render( {collapsibleContent}, @@ -117,7 +117,7 @@ describe('', () => { describe('Mouse Interactions', () => { let collapsible; - const ref = React.createRef(); + const ref = createRef(); beforeEach(() => { render( {collapsibleContent}, @@ -167,7 +167,7 @@ describe('', () => { describe('Keyboard Interactions', () => { let collapsible; - const ref = React.createRef(); + const ref = createRef(); beforeEach(() => { render( {collapsibleContent}, diff --git a/src/Collapsible/CollapsibleAdvanced.jsx b/src/Collapsible/CollapsibleAdvanced.jsx index 8e11cf3a1b..2a696dae17 100644 --- a/src/Collapsible/CollapsibleAdvanced.jsx +++ b/src/Collapsible/CollapsibleAdvanced.jsx @@ -1,10 +1,11 @@ -import React from 'react'; +// React import needed to support JSX outside functions, if removed build-docs will fail +import React, { createContext, Component } from 'react'; import classNames from 'classnames'; import PropTypes from 'prop-types'; -export const CollapsibleContext = React.createContext(); +export const CollapsibleContext = createContext(); -class CollapsibleAdvanced extends React.Component { +class CollapsibleAdvanced extends Component { static getDerivedStateFromProps(props) { if (props.open !== undefined) { return { diff --git a/src/Collapsible/CollapsibleBody.jsx b/src/Collapsible/CollapsibleBody.jsx index b711eb25ec..996c1580c6 100644 --- a/src/Collapsible/CollapsibleBody.jsx +++ b/src/Collapsible/CollapsibleBody.jsx @@ -1,4 +1,5 @@ -import React, { useContext } from 'react'; +// React import needed to support JSX outside functions, if removed build-docs will fail +import React, { createElement, cloneElement, useContext } from 'react'; import PropTypes from 'prop-types'; import Collapse from '../Collapse'; @@ -13,11 +14,11 @@ function CollapsibleBody({ // Keys are added to these elements so that TransitionReplace // will recognize them as unique components and perform the // transition properly. - const content = React.createElement(tag, { key: 'body', ...props }, children); + const content = createElement(tag, { key: 'body', ...props }, children); const transitionBody = isOpen ? content :
; if (transitionWrapper) { - return React.cloneElement(transitionWrapper, {}, transitionBody); + return cloneElement(transitionWrapper, {}, transitionBody); } /* istanbul ignore next */ return unmountOnExit diff --git a/src/Collapsible/CollapsibleTrigger.jsx b/src/Collapsible/CollapsibleTrigger.jsx index 9cf321466d..79f0a3716c 100644 --- a/src/Collapsible/CollapsibleTrigger.jsx +++ b/src/Collapsible/CollapsibleTrigger.jsx @@ -1,4 +1,4 @@ -import React, { useContext, useCallback } from 'react'; +import { createElement, useContext, useCallback } from 'react'; import PropTypes from 'prop-types'; import { CollapsibleContext } from './CollapsibleAdvanced'; @@ -36,7 +36,7 @@ function CollapsibleTrigger({ } }, [onKeyDown, handleToggle]); - return React.createElement( + return createElement( tag, { ...props, diff --git a/src/Collapsible/CollapsibleVisible.jsx b/src/Collapsible/CollapsibleVisible.jsx index 482287e1ef..b097b255be 100644 --- a/src/Collapsible/CollapsibleVisible.jsx +++ b/src/Collapsible/CollapsibleVisible.jsx @@ -1,3 +1,4 @@ +// React import needed to support JSX outside functions, if removed build-docs will fail import React, { useContext } from 'react'; import PropTypes from 'prop-types'; diff --git a/src/Collapsible/index.jsx b/src/Collapsible/index.jsx index f8d9886b9b..f2d2ffe6ad 100644 --- a/src/Collapsible/index.jsx +++ b/src/Collapsible/index.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { forwardRef, isValidElement } from 'react'; import classNames from 'classnames'; import PropTypes from 'prop-types'; @@ -17,7 +17,7 @@ const styleIcons = { // card and card-lg use the defaults specified in defaultProps }; -const Collapsible = React.forwardRef((props, ref) => { +const Collapsible = forwardRef((props, ref) => { const { children, className, @@ -29,7 +29,7 @@ const Collapsible = React.forwardRef((props, ref) => { } = props; const icons = { iconWhenClosed, iconWhenOpen, ...styleIcons[styling] }; - const titleElement = React.isValidElement(title) ? title : {title}; + const titleElement = isValidElement(title) ? title : {title}; return ( { const hexRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; @@ -29,16 +29,16 @@ function ColorPicker({ return colorString.slice(0, 7); }; - const [hexValid, setHexValid] = React.useState(() => (color === '' || colorIsValid(formatHexColorString(color)))); + const [hexValid, setHexValid] = useState(() => (color === '' || colorIsValid(formatHexColorString(color)))); - const [hexColorString, setHexColorString] = React.useState(() => { + const [hexColorString, setHexColorString] = useState(() => { if (color === '') { return ''; } return formatHexColorString(color); }); - const [colorToDisplay, setColorToDisplay] = React.useState(() => { + const [colorToDisplay, setColorToDisplay] = useState(() => { const formattedColor = formatHexColorString(color); if (colorIsValid(formattedColor)) { return formattedColor; diff --git a/src/Container/Container.test.tsx b/src/Container/Container.test.tsx index 82efafa24b..8de8d85531 100644 --- a/src/Container/Container.test.tsx +++ b/src/Container/Container.test.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { render } from '@testing-library/react'; import Container, { type ContainerSize } from '.'; diff --git a/src/Container/index.tsx b/src/Container/index.tsx index ea95d58867..444a90130b 100644 --- a/src/Container/index.tsx +++ b/src/Container/index.tsx @@ -1,5 +1,6 @@ /* eslint-disable react/require-default-props */ -import React from 'react'; +// React import needed to support JSX outside functions, if removed build-docs will fail +import React, { forwardRef } from 'react'; import classNames from 'classnames'; import PropTypes from 'prop-types'; import RBContainer, { type ContainerProps as RBContainerProps } from 'react-bootstrap/Container'; @@ -22,7 +23,7 @@ interface ContainerProps extends RBContainerProps { type ContainerType = ComponentWithAsProp<'div', ContainerProps>; -const Container: ContainerType = React.forwardRef(({ +const Container: ContainerType = forwardRef(({ size, children, ...props