Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: declare children prop explicitly for FCs #5258

Merged
merged 3 commits into from
Apr 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 16 additions & 17 deletions packages/core/src/components/breadcrumbs/breadcrumb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -35,41 +37,38 @@ export interface IBreadcrumbProps extends ActionProps, LinkProps {
iconTitle?: string;
}

export const Breadcrumb: React.FunctionComponent<BreadcrumbProps> = breadcrumbProps => {
export const Breadcrumb: React.FC<BreadcrumbProps> = 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 ? (
<Icon title={breadcrumbProps.iconTitle} icon={breadcrumbProps.icon} />
) : undefined;
const icon = props.icon != null ? <Icon title={props.iconTitle} icon={props.icon} /> : undefined;

if (breadcrumbProps.href == null && breadcrumbProps.onClick == null) {
if (props.href == null && props.onClick == null) {
return (
<span className={classes}>
{icon}
{breadcrumbProps.text}
{breadcrumbProps.children}
{props.text}
{props.children}
</span>
);
}
return (
<a
className={classes}
href={breadcrumbProps.href}
onClick={breadcrumbProps.disabled ? undefined : breadcrumbProps.onClick}
tabIndex={breadcrumbProps.disabled ? undefined : 0}
target={breadcrumbProps.target}
href={props.href}
onClick={props.disabled ? undefined : props.onClick}
tabIndex={props.disabled ? undefined : 0}
target={props.target}
>
{icon}
{breadcrumbProps.text}
{breadcrumbProps.children}
{props.text}
{props.children}
</a>
);
};
3 changes: 3 additions & 0 deletions packages/core/src/components/dialog/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/forms/controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<IControlInternalProps> = ({
const Control: React.FC<IControlInternalProps> = ({
alignIndicator,
children,
className,
Expand Down
18 changes: 11 additions & 7 deletions packages/core/src/components/html/html.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,19 @@ function htmlElement<E extends HTMLElement>(
tagName: keyof JSX.IntrinsicElements,
tagClassName: string,
// eslint-disable-next-line deprecation/deprecation
): React.FunctionComponent<React.HTMLProps<E> & IElementRefProps<E>> {
): React.FC<React.HTMLProps<E> & IElementRefProps<E> & { 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,
);
};
}

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/panel-stack2/panelView2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const PanelView2: PanelView2Component = <T extends Panel<object>>(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
Expand Down
5 changes: 1 addition & 4 deletions packages/core/src/components/popover/popoverArrow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,7 @@ export interface IPopoverArrowProps {
placement: Placement;
}

export const PopoverArrow: React.FunctionComponent<IPopoverArrowProps> = ({
arrowProps: { ref, style },
placement,
}) => (
export const PopoverArrow: React.FC<IPopoverArrowProps> = ({ arrowProps: { ref, style }, placement }) => (
<div className={Classes.POPOVER_ARROW} ref={ref} style={style.left == null || isNaN(+style.left) ? {} : style}>
<svg viewBox="0 0 30 30" style={{ transform: `rotate(${getArrowAngle(placement)}deg)` }}>
<path className={Classes.POPOVER_ARROW + "-border"} d={SVG_SHADOW_PATH} />
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/slider/multiSlider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<HandleProps> = () => null;
const MultiSliderHandle: React.FC<HandleProps> = () => null;
MultiSliderHandle.displayName = `${DISPLAYNAME_PREFIX}.MultiSliderHandle`;

export interface ISliderBaseProps extends Props, IntentProps {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/tabs/tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = () => <div className={Classes.FLEX_EXPANDER} />;
export const Expander: React.FC = () => <div className={Classes.FLEX_EXPANDER} />;

type TabElement = React.ReactElement<TabProps & { children: React.ReactNode }>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,4 +243,4 @@ describe("<MultistepDialog>", () => {
});
});

const Panel: React.FunctionComponent = () => <strong> panel</strong>;
const Panel: React.FC = () => <strong> panel</strong>;
4 changes: 2 additions & 2 deletions packages/core/test/overflow-list/overflowListTests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<ITestItem> = () => <div style={{ width: 10, flex: "0 0 auto" }} />;
const TestOverflow: React.FunctionComponent<{ items: ITestItem[] }> = () => <div />;
const TestItem: React.FC<ITestItem> = () => <div style={{ width: 10, flex: "0 0 auto" }} />;
const TestOverflow: React.FC<{ items: ITestItem[] }> = () => <div />;

describe.skip("<OverflowList>", function (this) {
// these tests rely on DOM measurement which can be flaky, so we allow some retries
Expand Down
16 changes: 8 additions & 8 deletions packages/core/test/resize-sensor/resizeSensorTests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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("<ResizeSensor>", () => {
// this scope variable is assigned in mountResizeSensor() and used in resize()
let wrapper: ReactWrapper<IResizeTesterProps, any> | undefined;
let wrapper: ReactWrapper<ResizeTesterProps, any> | undefined;
const testsContainerElement = document.createElement("div");
document.documentElement.appendChild(testsContainerElement);

Expand Down Expand Up @@ -68,15 +68,15 @@ describe("<ResizeSensor>", () => {
assert.equal(onResize2.callCount, 2);
});

function mountResizeSensor(onResize: IResizeSensorProps["onResize"]) {
return (wrapper = mount<IResizeTesterProps>(
function mountResizeSensor(onResize: ResizeSensorProps["onResize"]) {
return (wrapper = mount<ResizeTesterProps>(
<ResizeTester onResize={onResize} />,
// 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));
}
Expand All @@ -91,15 +91,15 @@ describe("<ResizeSensor>", () => {
}
});

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<IResizeTesterProps> = ({ id, width, height, ...resizeProps }) => (
type ResizeTesterProps = ResizeSensorProps & SizeProps;
const ResizeTester: React.FC<ResizeTesterProps> = ({ id, width, height, ...resizeProps }) => (
<ResizeSensor {...resizeProps}>
<div key={id} style={{ width, height }} />
</ResizeSensor>
Expand Down
2 changes: 1 addition & 1 deletion packages/core/test/tabs/tabsTests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -409,4 +409,4 @@ describe("<Tabs>", () => {
}
});

const Panel: React.FunctionComponent<{ title: string }> = ({ title }) => <strong>{title} panel</strong>;
const Panel: React.FC<{ title: string }> = ({ title }) => <strong>{title} panel</strong>;
8 changes: 4 additions & 4 deletions packages/docs-app/src/components/colorPalettes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 }) => (
<div
className={classNames("docs-color-palette", {
"docs-color-palette-single": colors.length === 1,
Expand All @@ -79,7 +79,7 @@ const ColorPalette: React.FunctionComponent<{ colors: string[] }> = ({ 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(", ")}]`;

Expand All @@ -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 () => (
<section className={classNames("docs-color-book", className)}>
{palettes.map((palette, index) => (
Expand Down
6 changes: 3 additions & 3 deletions packages/docs-app/src/components/colorSchemes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -205,17 +205,17 @@ export class ColorScheme extends React.PureComponent<IColorSchemeProps, IColorSc
}
}

export const QualitativeSchemePalette: React.FunctionComponent = () => <ColorBar colors={QUALITATIVE} />;
export const QualitativeSchemePalette: React.FC = () => <ColorBar colors={QUALITATIVE} />;

export const SequentialSchemePalette: React.FunctionComponent = () => {
export const SequentialSchemePalette: React.FC = () => {
const schemes = [
{ label: "Single hue", palettes: SINGLE_HUE },
{ label: "Multi-hue", palettes: SEQUENTIAL },
];
return <ColorScheme schemes={schemes} />;
};

export const DivergingSchemePalette: React.FunctionComponent = () => {
export const DivergingSchemePalette: React.FC = () => {
const schemes = [{ diverging: true, label: "Diverging", palettes: DIVERGING }];
return <ColorScheme schemes={schemes} />;
};
2 changes: 1 addition & 1 deletion packages/docs-app/src/components/logo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import * as React from "react";

export const Logo: React.FunctionComponent = () => (
export const Logo: React.FC = () => (
<svg width="65" height="76" xmlns="http://www.w3.org/2000/svg">
<g fillRule="nonzero">
<path d="M28.795 2.421l2.177-1.254a4 4 0 0 1 4.039.027l28.032 16.643A4 4 0 0 1 65 21.277v33.446a4 4 0 0 1-1.958 3.44l-28.03 16.644a4 4 0 0 1-4.039.027L2.004 58.154A4 4 0 0 1 0 54.687V21.313a4 4 0 0 1 2.004-3.467l26.79-15.425zm3.175.48l-.499-.867v-1h3.742L32.01 2.878a2.008 2.008 0 0 0-.04.023zM3.002 19.58A2 2 0 0 0 2 21.313v33.374a2 2 0 0 0 1.002 1.733l28.97 16.68a2 2 0 0 0 2.018-.013l28.03-16.644a2 2 0 0 0 .98-1.72V21.277a2 2 0 0 0-.979-1.72L33.99 2.914a2 2 0 0 0-1.98-.036L3.003 19.58z" />
Expand Down
2 changes: 1 addition & 1 deletion packages/docs-app/src/components/navIcons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<svg className="docs-nav-package-icon" width="24" height="24" xmlns="http://www.w3.org/2000/svg">
{ICON_CONTENTS[route]}
Expand Down
2 changes: 1 addition & 1 deletion packages/docs-app/src/components/resources.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = () => (
<>
<div className="blueprint-resources">
{RESOURCES.map(resource => (
Expand Down
3 changes: 2 additions & 1 deletion packages/docs-app/src/components/welcome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export interface IFileMenuProps extends Props {
shouldDismissPopover?: boolean;
}

export const FileMenu: React.FunctionComponent<IFileMenuProps> = props => (
export const FileMenu: React.FC<IFileMenuProps> = props => (
<Menu className={props.className}>
<MenuItem text="New" icon="document" {...props} />
<MenuItem text="Open" icon="folder-shared" {...props} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export interface IIntentSelectProps {
onChange: React.FormEventHandler<HTMLSelectElement>;
}

export const IntentSelect: React.FunctionComponent<IIntentSelectProps> = props => (
export const IntentSelect: React.FC<IIntentSelectProps> = props => (
<Label>
Intent
<HTMLSelect value={props.intent} onChange={props.onChange} options={INTENTS} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class MenuExample extends React.PureComponent<IExampleProps> {
}
}

const PalantirLogo: React.FunctionComponent = () => (
const PalantirLogo: React.FC = () => (
<svg className={Classes.ICON} width="16" height="16" viewBox="0 0 18 23" xmlns="http://www.w3.org/2000/svg">
<path
d="M16.718 16.653L9 20.013l-7.718-3.36L0 19.133 9 23l9-3.868-1.282-2.48zM9 14.738c-3.297 0-5.97-2.696-5.97-6.02C3.03 5.39 5.703 2.695 9 2.695c3.297 0 5.97 2.696 5.97 6.02 0 3.326-2.673 6.022-5.97 6.022zM9 0C4.23 0 .366 3.9.366 8.708c0 4.81 3.865 8.71 8.634 8.71 4.77 0 8.635-3.9 8.635-8.71C17.635 3.898 13.77 0 9 0z"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ export interface ISelectPanelProps {
onChange: (event: React.FormEvent<HTMLInputElement>) => void;
}

const SelectPanel: React.FunctionComponent<ISelectPanelProps> = props => (
const SelectPanel: React.FC<ISelectPanelProps> = props => (
<div className={classNames(Classes.DIALOG_BODY, "docs-multistep-dialog-example-step")}>
<p>Use this dialog to divide content into multiple sequential steps.</p>
<p>Select one of the options below in order to proceed to the next step:</p>
Expand All @@ -218,7 +218,7 @@ export interface IConfirmPanelProps {
selectedValue: string;
}

const ConfirmPanel: React.FunctionComponent<IConfirmPanelProps> = props => {
const ConfirmPanel: React.FC<IConfirmPanelProps> = props => {
return (
<div className={classNames(Classes.DIALOG_BODY, "docs-multistep-dialog-example-step")}>
<p>
Expand Down
8 changes: 4 additions & 4 deletions packages/docs-app/src/examples/core-examples/tabsExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export class TabsExample extends React.PureComponent<IExampleProps, ITabsExample
private handleNavbarTabChange = (navbarTabId: TabId) => this.setState({ navbarTabId });
}

const ReactPanel: React.FunctionComponent = () => (
const ReactPanel: React.FC = () => (
<div>
<H3>Example panel: React</H3>
<p className={Classes.RUNNING_TEXT}>
Expand All @@ -109,7 +109,7 @@ const ReactPanel: React.FunctionComponent = () => (
</div>
);

const AngularPanel: React.FunctionComponent = () => (
const AngularPanel: React.FC = () => (
<div>
<H3>Example panel: Angular</H3>
<p className={Classes.RUNNING_TEXT}>
Expand All @@ -120,7 +120,7 @@ const AngularPanel: React.FunctionComponent = () => (
</div>
);

const EmberPanel: React.FunctionComponent = () => (
const EmberPanel: React.FC = () => (
<div>
<H3>Example panel: Ember</H3>
<p className={Classes.RUNNING_TEXT}>
Expand All @@ -132,7 +132,7 @@ const EmberPanel: React.FunctionComponent = () => (
</div>
);

const BackbonePanel: React.FunctionComponent = () => (
const BackbonePanel: React.FC = () => (
<div>
<H3>Backbone</H3>
</div>
Expand Down
Loading