From 2767f03e46ff3af9c94bc707aebcc0bce9428c10 Mon Sep 17 00:00:00 2001 From: Adi Dahiya Date: Fri, 15 Apr 2022 16:42:11 +0000 Subject: [PATCH 1/3] fix: declare children prop explicitly for FCs --- .../src/components/breadcrumbs/breadcrumb.tsx | 33 +++++++++---------- .../core/src/components/dialog/dialog.tsx | 3 ++ .../core/src/components/forms/controls.tsx | 2 +- packages/core/src/components/html/html.tsx | 18 ++++++---- .../components/panel-stack2/panelView2.tsx | 2 +- .../src/components/popover/popoverArrow.tsx | 5 +-- .../src/components/slider/multiSlider.tsx | 2 +- packages/core/src/components/tabs/tabs.tsx | 2 +- .../multistep-dialog/multistepDialogTests.tsx | 2 +- .../test/overflow-list/overflowListTests.tsx | 4 +-- .../test/resize-sensor/resizeSensorTests.tsx | 16 ++++----- packages/core/test/tabs/tabsTests.tsx | 2 +- .../docs-app/src/components/colorPalettes.tsx | 8 ++--- .../docs-app/src/components/colorSchemes.tsx | 6 ++-- packages/docs-app/src/components/logo.tsx | 2 +- packages/docs-app/src/components/navIcons.tsx | 2 +- .../docs-app/src/components/resources.tsx | 2 +- packages/docs-app/src/components/welcome.tsx | 3 +- .../core-examples/common/fileMenu.tsx | 2 +- .../core-examples/common/intentSelect.tsx | 2 +- .../examples/core-examples/menuExample.tsx | 2 +- .../core-examples/multistepDialogExample.tsx | 4 +-- .../examples/core-examples/tabsExample.tsx | 8 ++--- .../datetime-examples/common/momentDate.tsx | 11 ++++--- .../common/precisionSelect.tsx | 2 +- .../src/components/modifierTable.tsx | 3 ++ .../docs-theme/src/components/navMenuItem.tsx | 2 ++ packages/popover2/src/popover2Arrow.tsx | 5 +-- 28 files changed, 82 insertions(+), 73 deletions(-) diff --git a/packages/core/src/components/breadcrumbs/breadcrumb.tsx b/packages/core/src/components/breadcrumbs/breadcrumb.tsx index 7de9515d51..b059a96ea7 100644 --- a/packages/core/src/components/breadcrumbs/breadcrumb.tsx +++ b/packages/core/src/components/breadcrumbs/breadcrumb.tsx @@ -25,6 +25,8 @@ import { Icon } from "../icon/icon"; export type BreadcrumbProps = IBreadcrumbProps; /** @deprecated use BreadcrumbProps */ export interface IBreadcrumbProps extends ActionProps, LinkProps { + children?: React.ReactNode; + /** Whether this breadcrumb is the current breadcrumb. */ current?: boolean; @@ -35,41 +37,38 @@ export interface IBreadcrumbProps extends ActionProps, LinkProps { iconTitle?: string; } -export const Breadcrumb: React.FunctionComponent = breadcrumbProps => { +export const Breadcrumb: React.FC = props => { const classes = classNames( Classes.BREADCRUMB, { - [Classes.BREADCRUMB_CURRENT]: breadcrumbProps.current, - [Classes.DISABLED]: breadcrumbProps.disabled, + [Classes.BREADCRUMB_CURRENT]: props.current, + [Classes.DISABLED]: props.disabled, }, - breadcrumbProps.className, + props.className, ); - const icon = - breadcrumbProps.icon != null ? ( - - ) : undefined; + const icon = props.icon != null ? : undefined; - if (breadcrumbProps.href == null && breadcrumbProps.onClick == null) { + if (props.href == null && props.onClick == null) { return ( {icon} - {breadcrumbProps.text} - {breadcrumbProps.children} + {props.text} + {props.children} ); } return ( {icon} - {breadcrumbProps.text} - {breadcrumbProps.children} + {props.text} + {props.children} ); }; diff --git a/packages/core/src/components/dialog/dialog.tsx b/packages/core/src/components/dialog/dialog.tsx index 65b8935c26..488e4f754f 100644 --- a/packages/core/src/components/dialog/dialog.tsx +++ b/packages/core/src/components/dialog/dialog.tsx @@ -30,6 +30,9 @@ import { IBackdropProps, OverlayableProps, Overlay } from "../overlay/overlay"; export type DialogProps = IDialogProps; /** @deprecated use DialogProps */ export interface IDialogProps extends OverlayableProps, IBackdropProps, Props { + /** Dialog contents. */ + children: React.ReactNode; + /** * Toggles the visibility of the overlay and its children. * This prop is required because the component is controlled. diff --git a/packages/core/src/components/forms/controls.tsx b/packages/core/src/components/forms/controls.tsx index a2b31eb1cd..8599ddf836 100644 --- a/packages/core/src/components/forms/controls.tsx +++ b/packages/core/src/components/forms/controls.tsx @@ -101,7 +101,7 @@ interface IControlInternalProps extends ControlProps { * Renders common control elements, with additional props to customize appearance. * This component is not exported and is only used in this file for `Checkbox`, `Radio`, and `Switch` below. */ -const Control: React.FunctionComponent = ({ +const Control: React.FC = ({ alignIndicator, children, className, diff --git a/packages/core/src/components/html/html.tsx b/packages/core/src/components/html/html.tsx index 1ead8f376d..3d0eaa7311 100644 --- a/packages/core/src/components/html/html.tsx +++ b/packages/core/src/components/html/html.tsx @@ -24,15 +24,19 @@ function htmlElement( tagName: keyof JSX.IntrinsicElements, tagClassName: string, // eslint-disable-next-line deprecation/deprecation -): React.FunctionComponent & IElementRefProps> { +): React.FC & IElementRefProps & { children?: React.ReactNode }> { /* eslint-disable-next-line react/display-name */ return props => { - const { className, elementRef, ...htmlProps } = props; - return React.createElement(tagName, { - ...htmlProps, - className: classNames(tagClassName, className), - ref: elementRef, - }); + const { className, elementRef, children, ...htmlProps } = props; + return React.createElement( + tagName, + { + ...htmlProps, + className: classNames(tagClassName, className), + ref: elementRef, + }, + children, + ); }; } diff --git a/packages/core/src/components/panel-stack2/panelView2.tsx b/packages/core/src/components/panel-stack2/panelView2.tsx index 27358a27f0..e1abd95746 100644 --- a/packages/core/src/components/panel-stack2/panelView2.tsx +++ b/packages/core/src/components/panel-stack2/panelView2.tsx @@ -72,7 +72,7 @@ export const PanelView2: PanelView2Component = >(props: // `props.panel.renderPanel` is simply a function that returns a JSX.Element. It may be an FC which // uses hooks. In order to avoid React errors due to inconsistent hook calls, we must encapsulate // those hooks with their own lifecycle through a very simple wrapper component. - const PanelWrapper: React.FunctionComponent = React.useMemo( + const PanelWrapper: React.FC = React.useMemo( () => () => // N.B. A type cast is required because of error TS2345, where technically `panel.props` could be // instantiated with a type unrelated to our generic constraint `T` here. We know diff --git a/packages/core/src/components/popover/popoverArrow.tsx b/packages/core/src/components/popover/popoverArrow.tsx index 6d51bbbd02..e1ffcd4bfe 100644 --- a/packages/core/src/components/popover/popoverArrow.tsx +++ b/packages/core/src/components/popover/popoverArrow.tsx @@ -54,10 +54,7 @@ export interface IPopoverArrowProps { placement: Placement; } -export const PopoverArrow: React.FunctionComponent = ({ - arrowProps: { ref, style }, - placement, -}) => ( +export const PopoverArrow: React.FC = ({ arrowProps: { ref, style }, placement }) => (
diff --git a/packages/core/src/components/slider/multiSlider.tsx b/packages/core/src/components/slider/multiSlider.tsx index 7b4853dec7..602559f9aa 100644 --- a/packages/core/src/components/slider/multiSlider.tsx +++ b/packages/core/src/components/slider/multiSlider.tsx @@ -29,7 +29,7 @@ import { argMin, fillValues, formatPercentage } from "./sliderUtils"; * SFC used to pass slider handle props to a `MultiSlider`. * This element is not rendered directly. */ -const MultiSliderHandle: React.FunctionComponent = () => null; +const MultiSliderHandle: React.FC = () => null; MultiSliderHandle.displayName = `${DISPLAYNAME_PREFIX}.MultiSliderHandle`; export interface ISliderBaseProps extends Props, IntentProps { diff --git a/packages/core/src/components/tabs/tabs.tsx b/packages/core/src/components/tabs/tabs.tsx index eb0e77de9c..52619de9b3 100644 --- a/packages/core/src/components/tabs/tabs.tsx +++ b/packages/core/src/components/tabs/tabs.tsx @@ -23,7 +23,7 @@ import * as Utils from "../../common/utils"; import { TabProps, Tab, TabId } from "./tab"; import { generateTabPanelId, generateTabTitleId, TabTitle } from "./tabTitle"; -export const Expander: React.FunctionComponent = () =>
; +export const Expander: React.FC = () =>
; type TabElement = React.ReactElement; diff --git a/packages/core/test/multistep-dialog/multistepDialogTests.tsx b/packages/core/test/multistep-dialog/multistepDialogTests.tsx index b0db0b11e9..a39389c88a 100644 --- a/packages/core/test/multistep-dialog/multistepDialogTests.tsx +++ b/packages/core/test/multistep-dialog/multistepDialogTests.tsx @@ -243,4 +243,4 @@ describe("", () => { }); }); -const Panel: React.FunctionComponent = () => panel; +const Panel: React.FC = () => panel; diff --git a/packages/core/test/overflow-list/overflowListTests.tsx b/packages/core/test/overflow-list/overflowListTests.tsx index f1932234d5..9f6d5f9272 100644 --- a/packages/core/test/overflow-list/overflowListTests.tsx +++ b/packages/core/test/overflow-list/overflowListTests.tsx @@ -30,8 +30,8 @@ interface ITestItem { const IDS = [0, 1, 2, 3, 4, 5]; const ITEMS: ITestItem[] = IDS.map(id => ({ id })); -const TestItem: React.FunctionComponent = () =>
; -const TestOverflow: React.FunctionComponent<{ items: ITestItem[] }> = () =>
; +const TestItem: React.FC = () =>
; +const TestOverflow: React.FC<{ items: ITestItem[] }> = () =>
; describe.skip("", function (this) { // these tests rely on DOM measurement which can be flaky, so we allow some retries diff --git a/packages/core/test/resize-sensor/resizeSensorTests.tsx b/packages/core/test/resize-sensor/resizeSensorTests.tsx index 1634f67a03..e97bacf499 100644 --- a/packages/core/test/resize-sensor/resizeSensorTests.tsx +++ b/packages/core/test/resize-sensor/resizeSensorTests.tsx @@ -19,11 +19,11 @@ import { mount, ReactWrapper } from "enzyme"; import * as React from "react"; import { spy } from "sinon"; -import { IResizeSensorProps, ResizeSensor } from "../../src/components/resize-sensor/resizeSensor"; +import { ResizeSensorProps, ResizeSensor } from "../../src/components/resize-sensor/resizeSensor"; describe("", () => { // this scope variable is assigned in mountResizeSensor() and used in resize() - let wrapper: ReactWrapper | undefined; + let wrapper: ReactWrapper | undefined; const testsContainerElement = document.createElement("div"); document.documentElement.appendChild(testsContainerElement); @@ -68,15 +68,15 @@ describe("", () => { assert.equal(onResize2.callCount, 2); }); - function mountResizeSensor(onResize: IResizeSensorProps["onResize"]) { - return (wrapper = mount( + function mountResizeSensor(onResize: ResizeSensorProps["onResize"]) { + return (wrapper = mount( , // must be in the DOM for measurement { attachTo: testsContainerElement }, )); } - function resize(size: ISizeProps) { + function resize(size: SizeProps) { wrapper!.setProps(size); return new Promise(resolve => setTimeout(resolve, 30)); } @@ -91,15 +91,15 @@ describe("", () => { } }); -interface ISizeProps { +interface SizeProps { /** Used as React `key`, so changing it will force a new element to be created. */ id?: number; width?: number; height?: number; } -type IResizeTesterProps = IResizeSensorProps & ISizeProps; -const ResizeTester: React.FunctionComponent = ({ id, width, height, ...resizeProps }) => ( +type ResizeTesterProps = ResizeSensorProps & SizeProps; +const ResizeTester: React.FC = ({ id, width, height, ...resizeProps }) => (
diff --git a/packages/core/test/tabs/tabsTests.tsx b/packages/core/test/tabs/tabsTests.tsx index 269348000a..963db91bed 100644 --- a/packages/core/test/tabs/tabsTests.tsx +++ b/packages/core/test/tabs/tabsTests.tsx @@ -409,4 +409,4 @@ describe("", () => { } }); -const Panel: React.FunctionComponent<{ title: string }> = ({ title }) => {title} panel; +const Panel: React.FC<{ title: string }> = ({ title }) => {title} panel; diff --git a/packages/docs-app/src/components/colorPalettes.tsx b/packages/docs-app/src/components/colorPalettes.tsx index 3dabb728b5..2fd9571a05 100644 --- a/packages/docs-app/src/components/colorPalettes.tsx +++ b/packages/docs-app/src/components/colorPalettes.tsx @@ -50,7 +50,7 @@ function getLuminance(hex: string) { const DARK_LUMA_CUTOFF = 111; // a single swatch of color, name on left & hex on right. click to copy hex. -const ColorSwatch: React.FunctionComponent<{ colorName: string; hexCode: string }> = ({ colorName, hexCode }) => { +const ColorSwatch: React.FC<{ colorName: string; hexCode: string }> = ({ colorName, hexCode }) => { const style = { backgroundColor: hexCode, color: getLuminance(hexCode) < DARK_LUMA_CUTOFF ? Colors.WHITE : Colors.BLACK, @@ -65,7 +65,7 @@ const ColorSwatch: React.FunctionComponent<{ colorName: string; hexCode: string }; // vertical list of swatches for each color -const ColorPalette: React.FunctionComponent<{ colors: string[] }> = ({ colors }) => ( +const ColorPalette: React.FC<{ colors: string[] }> = ({ colors }) => (
= ({ colors }) // horizontal list of swatches for each color // no text in swatch; display all hex codes underneath -export const ColorBar: React.FunctionComponent<{ colors: string[] }> = ({ colors }) => { +export const ColorBar: React.FC<{ colors: string[] }> = ({ colors }) => { const hexString = colors.map(getHexCode).join(", "); const jsonString = `[${colors.map(c => `"${getHexCode(c)}"`).join(", ")}]`; @@ -104,7 +104,7 @@ export const ColorBar: React.FunctionComponent<{ colors: string[] }> = ({ colors }; // a group of ColorPalettes, arranged by default in two columns -function createPaletteBook(palettes: string[][], className?: string): React.FunctionComponent { +function createPaletteBook(palettes: string[][], className?: string): React.FC { return () => (
{palettes.map((palette, index) => ( diff --git a/packages/docs-app/src/components/colorSchemes.tsx b/packages/docs-app/src/components/colorSchemes.tsx index a8caf0f497..da2f50b461 100644 --- a/packages/docs-app/src/components/colorSchemes.tsx +++ b/packages/docs-app/src/components/colorSchemes.tsx @@ -205,9 +205,9 @@ export class ColorScheme extends React.PureComponent ; +export const QualitativeSchemePalette: React.FC = () => ; -export const SequentialSchemePalette: React.FunctionComponent = () => { +export const SequentialSchemePalette: React.FC = () => { const schemes = [ { label: "Single hue", palettes: SINGLE_HUE }, { label: "Multi-hue", palettes: SEQUENTIAL }, @@ -215,7 +215,7 @@ export const SequentialSchemePalette: React.FunctionComponent = () => { return ; }; -export const DivergingSchemePalette: React.FunctionComponent = () => { +export const DivergingSchemePalette: React.FC = () => { const schemes = [{ diverging: true, label: "Diverging", palettes: DIVERGING }]; return ; }; diff --git a/packages/docs-app/src/components/logo.tsx b/packages/docs-app/src/components/logo.tsx index da61447564..d5e821a62b 100644 --- a/packages/docs-app/src/components/logo.tsx +++ b/packages/docs-app/src/components/logo.tsx @@ -16,7 +16,7 @@ import * as React from "react"; -export const Logo: React.FunctionComponent = () => ( +export const Logo: React.FC = () => ( diff --git a/packages/docs-app/src/components/navIcons.tsx b/packages/docs-app/src/components/navIcons.tsx index 9c9b0efb01..af9bfa1a1b 100644 --- a/packages/docs-app/src/components/navIcons.tsx +++ b/packages/docs-app/src/components/navIcons.tsx @@ -16,7 +16,7 @@ import * as React from "react"; -export const NavIcon: React.FunctionComponent<{ route: string }> = ({ route }) => { +export const NavIcon: React.FC<{ route: string }> = ({ route }) => { return ( {ICON_CONTENTS[route]} diff --git a/packages/docs-app/src/components/resources.tsx b/packages/docs-app/src/components/resources.tsx index 60c991627f..d47e516613 100644 --- a/packages/docs-app/src/components/resources.tsx +++ b/packages/docs-app/src/components/resources.tsx @@ -27,7 +27,7 @@ const RESOURCES: IResourceProps[] = [ { fileName: "blueprint-colors.sketchpalette", lastUpdated: "January 22, 2020" }, ]; -export const Resources: React.FunctionComponent = () => ( +export const Resources: React.FC = () => ( <>
{RESOURCES.map(resource => ( diff --git a/packages/docs-app/src/components/welcome.tsx b/packages/docs-app/src/components/welcome.tsx index 5efd1492a8..3c992e0a93 100644 --- a/packages/docs-app/src/components/welcome.tsx +++ b/packages/docs-app/src/components/welcome.tsx @@ -39,7 +39,8 @@ export class Welcome extends React.PureComponent { } } -const WelcomeCard: React.FunctionComponent<{ +const WelcomeCard: React.FC<{ + children?: React.ReactNode; icon: IconName; title: string; href: string; diff --git a/packages/docs-app/src/examples/core-examples/common/fileMenu.tsx b/packages/docs-app/src/examples/core-examples/common/fileMenu.tsx index b3c8ee068a..90ee77e881 100644 --- a/packages/docs-app/src/examples/core-examples/common/fileMenu.tsx +++ b/packages/docs-app/src/examples/core-examples/common/fileMenu.tsx @@ -22,7 +22,7 @@ export interface IFileMenuProps extends Props { shouldDismissPopover?: boolean; } -export const FileMenu: React.FunctionComponent = props => ( +export const FileMenu: React.FC = props => ( diff --git a/packages/docs-app/src/examples/core-examples/common/intentSelect.tsx b/packages/docs-app/src/examples/core-examples/common/intentSelect.tsx index 8e432424e7..3189f1eb86 100644 --- a/packages/docs-app/src/examples/core-examples/common/intentSelect.tsx +++ b/packages/docs-app/src/examples/core-examples/common/intentSelect.tsx @@ -32,7 +32,7 @@ export interface IIntentSelectProps { onChange: React.FormEventHandler; } -export const IntentSelect: React.FunctionComponent = props => ( +export const IntentSelect: React.FC = props => (