` props. */
-export interface ICalloutProps extends IIntentProps, IProps {
+export interface ICalloutProps extends IIntentProps, IProps, HTMLDivProps {
/**
* Name of a Blueprint UI icon (or an icon element) to render on the left side.
*
@@ -30,7 +30,7 @@ export interface ICalloutProps extends IIntentProps, IProps {
title?: string;
}
-export class Callout extends React.PureComponent
, {}> {
+export class Callout extends React.PureComponent {
public render() {
const { className, children, icon: _nospread, intent, title, ...htmlProps } = this.props;
const iconName = this.getIconName();
diff --git a/packages/core/src/components/card/card.tsx b/packages/core/src/components/card/card.tsx
index 36f6fa1c21..3ee88922d4 100644
--- a/packages/core/src/components/card/card.tsx
+++ b/packages/core/src/components/card/card.tsx
@@ -7,9 +7,9 @@
import classNames from "classnames";
import * as React from "react";
import * as Classes from "../../common/classes";
-import { IProps } from "../../common/props";
+import { HTMLDivProps, IProps } from "../../common/props";
-export interface ICardProps extends IProps {
+export interface ICardProps extends IProps, HTMLDivProps {
/**
* Controls the intensity of the drop shadow beneath the card: the higher
* the elevation, the higher the drop shadow. At elevation `0`, no drop
@@ -61,20 +61,13 @@ export class Card extends React.PureComponent {
};
public render() {
- return (
-
- {this.props.children}
-
- );
- }
-
- private getClassName() {
- const { elevation, interactive, className } = this.props;
- return classNames(
+ const { className, elevation, interactive, ...htmlProps } = this.props;
+ const classes = classNames(
Classes.CARD,
{ [Classes.INTERACTIVE]: interactive },
ELEVATION_CLASSES[elevation],
className,
);
+ return ;
}
}
diff --git a/packages/core/src/components/forms/controlGroup.tsx b/packages/core/src/components/forms/controlGroup.tsx
index fa884f267e..a929c6d09b 100644
--- a/packages/core/src/components/forms/controlGroup.tsx
+++ b/packages/core/src/components/forms/controlGroup.tsx
@@ -7,9 +7,9 @@
import classNames from "classnames";
import * as React from "react";
import * as Classes from "../../common/classes";
-import { IProps } from "../../common/props";
+import { HTMLDivProps, IProps } from "../../common/props";
-export interface IControlGroupProps extends React.AllHTMLAttributes, IProps {
+export interface IControlGroupProps extends IProps, HTMLDivProps {
/**
* Whether the control group should take up the full width of its container.
*/
diff --git a/packages/core/src/components/forms/fileInput.tsx b/packages/core/src/components/forms/fileInput.tsx
index 837757d22c..75dee52e4c 100644
--- a/packages/core/src/components/forms/fileInput.tsx
+++ b/packages/core/src/components/forms/fileInput.tsx
@@ -10,7 +10,7 @@ import { Utils } from "../../common";
import * as Classes from "../../common/classes";
import { IProps } from "../../common/props";
-export interface IFileInputProps extends React.AllHTMLAttributes, IProps {
+export interface IFileInputProps extends React.LabelHTMLAttributes, IProps {
/**
* Whether the file input is non-interactive.
* Setting this to `true` will automatically disable the child input too.
@@ -56,7 +56,7 @@ export interface IFileInputProps extends React.AllHTMLAttributes {
+export class FileInput extends React.PureComponent {
public static displayName = "Blueprint2.FileInput";
public static defaultProps: IFileInputProps = {
diff --git a/packages/core/src/components/forms/inputGroup.tsx b/packages/core/src/components/forms/inputGroup.tsx
index 38a124ae62..ad17a74163 100644
--- a/packages/core/src/components/forms/inputGroup.tsx
+++ b/packages/core/src/components/forms/inputGroup.tsx
@@ -11,6 +11,8 @@ import * as Classes from "../../common/classes";
import { HTMLInputProps, IControlledProps, IIntentProps, IProps, removeNonHTMLProps } from "../../common/props";
import { Icon, IconName } from "../icon/icon";
+// NOTE: This interface does not extend HTMLInputProps due to incompatiblity with `IControlledProps`.
+// Instead, we union the props in the component definition, which does work and properly disallows `string[]` values.
export interface IInputGroupProps extends IControlledProps, IIntentProps, IProps {
/**
* Whether the input is non-interactive.
@@ -48,7 +50,7 @@ export interface IInputGroupState {
rightElementWidth?: number;
}
-export class InputGroup extends React.PureComponent {
+export class InputGroup extends React.PureComponent {
public static displayName = "Blueprint2.InputGroup";
public state: IInputGroupState = {
diff --git a/packages/core/src/components/forms/label.tsx b/packages/core/src/components/forms/label.tsx
index 3e862bbd0e..fadac921ad 100644
--- a/packages/core/src/components/forms/label.tsx
+++ b/packages/core/src/components/forms/label.tsx
@@ -9,7 +9,7 @@ import * as React from "react";
import * as Classes from "../../common/classes";
import { IProps } from "../../common/props";
-export interface ILabelProps extends React.AllHTMLAttributes, IProps {
+export interface ILabelProps extends React.LabelHTMLAttributes, IProps {
/**
* Whether the label is non-interactive.
* Be sure to explicitly disable any child controls as well.
diff --git a/packages/core/src/components/forms/textArea.tsx b/packages/core/src/components/forms/textArea.tsx
index 91968f826e..a62f095392 100644
--- a/packages/core/src/components/forms/textArea.tsx
+++ b/packages/core/src/components/forms/textArea.tsx
@@ -9,7 +9,7 @@ import * as React from "react";
import * as Classes from "../../common/classes";
import { IIntentProps, IProps } from "../../common/props";
-export interface ITextAreaProps extends React.AllHTMLAttributes, IIntentProps, IProps {
+export interface ITextAreaProps extends React.TextareaHTMLAttributes, IIntentProps, IProps {
/**
* Whether the text area should take up the full width of its container.
*/
diff --git a/packages/core/src/components/navbar/navbar.tsx b/packages/core/src/components/navbar/navbar.tsx
index 70093237f7..307e653663 100644
--- a/packages/core/src/components/navbar/navbar.tsx
+++ b/packages/core/src/components/navbar/navbar.tsx
@@ -7,7 +7,7 @@
import classNames from "classnames";
import * as React from "react";
import * as Classes from "../../common/classes";
-import { IProps } from "../../common/props";
+import { HTMLDivProps, IProps } from "../../common/props";
import { NavbarDivider } from "./navbarDivider";
import { NavbarGroup } from "./navbarGroup";
import { NavbarHeading } from "./navbarHeading";
@@ -15,8 +15,7 @@ import { NavbarHeading } from "./navbarHeading";
export { INavbarDividerProps } from "./navbarDivider";
// allow the empty interface so we can label it clearly in the docs
-// tslint:disable-next-line:no-empty-interface
-export interface INavbarProps extends React.HTMLProps, IProps {
+export interface INavbarProps extends IProps, HTMLDivProps {
// Empty
}
diff --git a/packages/core/src/components/navbar/navbarDivider.tsx b/packages/core/src/components/navbar/navbarDivider.tsx
index d9872b4fa1..14a45917fa 100644
--- a/packages/core/src/components/navbar/navbarDivider.tsx
+++ b/packages/core/src/components/navbar/navbarDivider.tsx
@@ -7,11 +7,10 @@
import classNames from "classnames";
import * as React from "react";
import * as Classes from "../../common/classes";
-import { IProps } from "../../common/props";
+import { HTMLDivProps, IProps } from "../../common/props";
// allow the empty interface so we can label it clearly in the docs
-// tslint:disable-next-line:no-empty-interface
-export interface INavbarDividerProps extends React.HTMLProps, IProps {
+export interface INavbarDividerProps extends IProps, HTMLDivProps {
// Empty
}
diff --git a/packages/core/src/components/navbar/navbarGroup.tsx b/packages/core/src/components/navbar/navbarGroup.tsx
index 46f1035ad3..1954e7b291 100644
--- a/packages/core/src/components/navbar/navbarGroup.tsx
+++ b/packages/core/src/components/navbar/navbarGroup.tsx
@@ -8,9 +8,9 @@ import classNames from "classnames";
import * as React from "react";
import { Alignment } from "../../common/alignment";
import * as Classes from "../../common/classes";
-import { IProps } from "../../common/props";
+import { HTMLDivProps, IProps } from "../../common/props";
-export interface INavbarGroupProps extends React.HTMLProps, IProps {
+export interface INavbarGroupProps extends IProps, HTMLDivProps {
/**
* The side of the navbar on which the group should appear.
* The `Alignment` enum provides constants for these values.
diff --git a/packages/core/src/components/navbar/navbarHeading.tsx b/packages/core/src/components/navbar/navbarHeading.tsx
index 6f4dbb4315..a19d651324 100644
--- a/packages/core/src/components/navbar/navbarHeading.tsx
+++ b/packages/core/src/components/navbar/navbarHeading.tsx
@@ -7,17 +7,16 @@
import classNames from "classnames";
import * as React from "react";
import * as Classes from "../../common/classes";
-import { IProps } from "../../common/props";
+import { HTMLDivProps, IProps } from "../../common/props";
// allow the empty interface so we can label it clearly in the docs
-// tslint:disable-next-line:no-empty-interface
-export interface INavbarHeadingProps extends React.HTMLProps, IProps {
+export interface INavbarHeadingProps extends IProps, HTMLDivProps {
// Empty
}
// this component is simple enough that tests would be purely tautological.
/* istanbul ignore next */
-export class NavbarHeading extends React.PureComponent, {}> {
+export class NavbarHeading extends React.PureComponent {
public static displayName = "Blueprint2.NavbarHeading";
public render() {
diff --git a/packages/core/src/components/popover/popover.tsx b/packages/core/src/components/popover/popover.tsx
index 188fdb3101..2e77d161a9 100644
--- a/packages/core/src/components/popover/popover.tsx
+++ b/packages/core/src/components/popover/popover.tsx
@@ -13,7 +13,7 @@ import { AbstractPureComponent } from "../../common/abstractPureComponent";
import * as Classes from "../../common/classes";
import * as Errors from "../../common/errors";
import { Position } from "../../common/position";
-import { IProps } from "../../common/props";
+import { HTMLDivProps, IProps } from "../../common/props";
import * as Utils from "../../common/utils";
import { IOverlayableProps, Overlay } from "../overlay/overlay";
import { Tooltip } from "../tooltip/tooltip";
@@ -406,7 +406,7 @@ export class Popover extends AbstractPureComponent
private renderPopper(content: JSX.Element) {
const { usePortal, interactionKind, modifiers } = this.props;
- const popoverHandlers: React.HTMLAttributes = {
+ const popoverHandlers: HTMLDivProps = {
// always check popover clicks for dismiss class
onClick: this.handlePopoverClick,
};
diff --git a/packages/core/src/components/portal/portal.tsx b/packages/core/src/components/portal/portal.tsx
index c8b876da34..4349d4ea35 100644
--- a/packages/core/src/components/portal/portal.tsx
+++ b/packages/core/src/components/portal/portal.tsx
@@ -9,10 +9,10 @@ import * as ReactDOM from "react-dom";
import * as Classes from "../../common/classes";
import * as Errors from "../../common/errors";
-import { IProps } from "../../common/props";
+import { HTMLDivProps, IProps } from "../../common/props";
import { safeInvoke } from "../../common/utils";
-export interface IPortalProps extends IProps, React.HTMLProps {
+export interface IPortalProps extends IProps, HTMLDivProps {
/**
* Callback invoked when the children of this `Portal` have been added to the DOM.
*/
diff --git a/packages/core/test/card/cardTests.tsx b/packages/core/test/card/cardTests.tsx
index 54f713102a..1e6586182f 100644
--- a/packages/core/test/card/cardTests.tsx
+++ b/packages/core/test/card/cardTests.tsx
@@ -37,4 +37,11 @@ describe("", () => {
shallow().simulate("click");
assert.isTrue(onClick.calledOnce);
});
+
+ it("supports HTML props", () => {
+ const onChange = sinon.spy();
+ const card = shallow().find("div");
+ assert.strictEqual(card.prop("onChange"), onChange);
+ assert.strictEqual(card.prop("title"), "foo");
+ });
});
diff --git a/packages/datetime/test/dateRangeInputTests.tsx b/packages/datetime/test/dateRangeInputTests.tsx
index 4171df7652..bee410dbb1 100644
--- a/packages/datetime/test/dateRangeInputTests.tsx
+++ b/packages/datetime/test/dateRangeInputTests.tsx
@@ -11,6 +11,7 @@ import * as sinon from "sinon";
import {
Classes as CoreClasses,
+ HTMLDivProps,
HTMLInputProps,
IInputGroupProps,
InputGroup,
@@ -26,8 +27,8 @@ import { DATE_FORMAT } from "./common/dateFormat";
import * as DateTestUtils from "./common/dateTestUtils";
type WrappedComponentRoot = ReactWrapper;
-type WrappedComponentInput = ReactWrapper, any>;
-type WrappedComponentDayElement = ReactWrapper, any>;
+type WrappedComponentInput = ReactWrapper;
+type WrappedComponentDayElement = ReactWrapper;
type OutOfRangeTestFunction = (
inputGetterFn: (root: WrappedComponentRoot) => WrappedComponentInput,
diff --git a/packages/docs-app/src/components/clickToCopy.tsx b/packages/docs-app/src/components/clickToCopy.tsx
index d0a6635a13..a8a590456a 100644
--- a/packages/docs-app/src/components/clickToCopy.tsx
+++ b/packages/docs-app/src/components/clickToCopy.tsx
@@ -7,10 +7,10 @@
import classNames from "classnames";
import * as React from "react";
-import { IProps, Keys, removeNonHTMLProps, Utils } from "@blueprintjs/core";
+import { HTMLDivProps, IProps, Keys, removeNonHTMLProps, Utils } from "@blueprintjs/core";
import { createKeyEventHandler } from "@blueprintjs/docs-theme";
-export interface IClickToCopyProps extends IProps, React.HTMLProps {
+export interface IClickToCopyProps extends IProps, HTMLDivProps {
/**
* Additional class names to apply after value has been copied
* @default "docs-clipboard-copied"