Skip to content

Commit

Permalink
Rename new abstract components to keep name for legacy components
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobias committed Sep 21, 2019
1 parent 97bd162 commit 7a523f4
Show file tree
Hide file tree
Showing 39 changed files with 289 additions and 89 deletions.
1 change: 1 addition & 0 deletions packages/core/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module.exports = function (config) {
// not worth full coverage
"src/accessibility/*",
"src/common/abstractComponent*",
"src/common/abstractPureComponent*",
],
});
config.set(baseConfig);
Expand Down
39 changes: 21 additions & 18 deletions packages/core/src/common/abstractComponent.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* Copyright 2015 Palantir Technologies, Inc. All rights reserved.
*
* Licensed under the terms of the LICENSE file distributed with this project.
* Licensed 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
Expand All @@ -20,40 +21,28 @@ import { isNodeEnv } from "./utils";
/**
* An abstract component that Blueprint components can extend
* in order to add some common functionality like runtime props validation.
* This version will not work with React 17 upwards and only exists for legacy purposes
*/
export abstract class AbstractComponent<P, S, SS = {}> extends React.Component<P, S, SS> {
export abstract class AbstractComponent<P, S> extends React.Component<P, S> {
/** Component displayName should be `public static`. This property exists to prevent incorrect usage. */
protected displayName: never;

// Not bothering to remove entries when their timeouts finish because clearing invalid ID is a no-op
private timeoutIds: number[] = [];

protected constructor(props?: P, context?: any) {
constructor(props?: P, context?: any) {
super(props, context);
if (!isNodeEnv("production")) {
this.validateProps(this.props, true);
this.validateProps(this.props);
}
}

public componentDidUpdate(_: P, __: S, ___: SS) {
public componentWillReceiveProps(nextProps: P & { children?: React.ReactNode }) {
if (!isNodeEnv("production")) {
this.validateProps(this.props);
this.validateProps(nextProps);
}
}

/**
* Ensures that the props specified for a component are valid.
* Implementations should check that props are valid and usually throw an Error if they are not.
* Implementations should not duplicate checks that the type system already guarantees.
*
* This method should be used instead of React's
* [propTypes](https://facebook.github.io/react/docs/reusable-components.html#prop-validation) feature.
* Like propTypes, these runtime checks run only in development mode.
*/
protected validateProps(_: P, __: boolean = false) {
// implement in subclass
}

public componentWillUnmount() {
this.clearTimeouts();
}
Expand All @@ -80,4 +69,18 @@ export abstract class AbstractComponent<P, S, SS = {}> extends React.Component<P
this.timeoutIds = [];
}
};

/**
* Ensures that the props specified for a component are valid.
* Implementations should check that props are valid and usually throw an Error if they are not.
* Implementations should not duplicate checks that the type system already guarantees.
*
* This method should be used instead of React's
* [propTypes](https://facebook.github.io/react/docs/reusable-components.html#prop-validation) feature.
* Like propTypes, these runtime checks run only in development mode.
*/
protected validateProps(_: P & { children?: React.ReactNode }) {
// implement in subclass
}
}

83 changes: 83 additions & 0 deletions packages/core/src/common/abstractComponentNewLifecycles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright 2015 Palantir Technologies, Inc. All rights reserved.
*
* Licensed 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 CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import * as React from "react";
import { isNodeEnv } from "./utils";

/**
* An abstract component that Blueprint components can extend
* in order to add some common functionality like runtime props validation.
*/
export abstract class AbstractComponentNewLifecycles<P, S, SS = {}> extends React.Component<P, S, SS> {
/** Component displayName should be `public static`. This property exists to prevent incorrect usage. */
protected displayName: never;

// Not bothering to remove entries when their timeouts finish because clearing invalid ID is a no-op
private timeoutIds: number[] = [];

protected constructor(props?: P, context?: any) {
super(props, context);
if (!isNodeEnv("production")) {
this.validateProps(this.props, true);
}
}

public componentDidUpdate(_: P, __: S, ___: SS) {
if (!isNodeEnv("production")) {
this.validateProps(this.props);
}
}

/**
* Ensures that the props specified for a component are valid.
* Implementations should check that props are valid and usually throw an Error if they are not.
* Implementations should not duplicate checks that the type system already guarantees.
*
* This method should be used instead of React's
* [propTypes](https://facebook.github.io/react/docs/reusable-components.html#prop-validation) feature.
* Like propTypes, these runtime checks run only in development mode.
*/
protected validateProps(_: P, __: boolean = false) {
// implement in subclass
}

public componentWillUnmount() {
this.clearTimeouts();
}

/**
* Set a timeout and remember its ID.
* All stored timeouts will be cleared when component unmounts.
* @returns a "cancel" function that will clear timeout when invoked.
*/
public setTimeout(callback: () => void, timeout?: number) {
const handle = window.setTimeout(callback, timeout);
this.timeoutIds.push(handle);
return () => window.clearTimeout(handle);
}

/**
* Clear all known timeouts.
*/
public clearTimeouts = () => {
if (this.timeoutIds.length > 0) {
for (const timeoutId of this.timeoutIds) {
window.clearTimeout(timeoutId);
}
this.timeoutIds = [];
}
};
}
17 changes: 10 additions & 7 deletions packages/core/src/common/abstractPureComponent.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* Copyright 2015 Palantir Technologies, Inc. All rights reserved.
*
* Licensed under the terms of the LICENSE file distributed with this project.
* Licensed 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
Expand All @@ -20,8 +21,9 @@ import { isNodeEnv } from "./utils";
/**
* An abstract component that Blueprint components can extend
* in order to add some common functionality like runtime props validation.
* This version will not work with React 17 upwards and only exists for legacy purposes
*/
export abstract class AbstractPureComponent<P, S = {}, SS = {}> extends React.PureComponent<P, S, SS> {
export abstract class AbstractPureComponent<P, S = {}> extends React.PureComponent<P, S> {
/** Component displayName should be `public static`. This property exists to prevent incorrect usage. */
protected displayName: never;

Expand All @@ -30,14 +32,14 @@ export abstract class AbstractPureComponent<P, S = {}, SS = {}> extends React.Pu

constructor(props?: P, context?: any) {
super(props, context);
if (!isNodeEnv('production')) {
this.validateProps(this.props, true);
if (!isNodeEnv("production")) {
this.validateProps(this.props);
}
}

public componentDidUpdate(_: P, __: S, ___: SS) {
if (!isNodeEnv('production')) {
this.validateProps(this.props);
public componentWillReceiveProps(nextProps: P & { children?: React.ReactNode }) {
if (!isNodeEnv("production")) {
this.validateProps(nextProps);
}
}

Expand Down Expand Up @@ -77,7 +79,8 @@ export abstract class AbstractPureComponent<P, S = {}, SS = {}> extends React.Pu
* [propTypes](https://facebook.github.io/react/docs/reusable-components.html#prop-validation) feature.
* Like propTypes, these runtime checks run only in development mode.
*/
protected validateProps(_: P, __: boolean = false) {
protected validateProps(_: P & { children?: React.ReactNode }) {
// implement in subclass
}
}

83 changes: 83 additions & 0 deletions packages/core/src/common/abstractPureComponentNewLifecycles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright 2015 Palantir Technologies, Inc. All rights reserved.
*
* Licensed 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 CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import * as React from "react";
import { isNodeEnv } from "./utils";

/**
* An abstract component that Blueprint components can extend
* in order to add some common functionality like runtime props validation.
*/
export abstract class AbstractPureComponentNewLifecycles<P, S = {}, SS = {}> extends React.PureComponent<P, S, SS> {
/** Component displayName should be `public static`. This property exists to prevent incorrect usage. */
protected displayName: never;

// Not bothering to remove entries when their timeouts finish because clearing invalid ID is a no-op
private timeoutIds: number[] = [];

constructor(props?: P, context?: any) {
super(props, context);
if (!isNodeEnv('production')) {
this.validateProps(this.props, true);
}
}

public componentDidUpdate(_: P, __: S, ___: SS) {
if (!isNodeEnv('production')) {
this.validateProps(this.props);
}
}

public componentWillUnmount() {
this.clearTimeouts();
}

/**
* Set a timeout and remember its ID.
* All stored timeouts will be cleared when component unmounts.
* @returns a "cancel" function that will clear timeout when invoked.
*/
public setTimeout(callback: () => void, timeout?: number) {
const handle = window.setTimeout(callback, timeout);
this.timeoutIds.push(handle);
return () => window.clearTimeout(handle);
}

/**
* Clear all known timeouts.
*/
public clearTimeouts = () => {
if (this.timeoutIds.length > 0) {
for (const timeoutId of this.timeoutIds) {
window.clearTimeout(timeoutId);
}
this.timeoutIds = [];
}
};

/**
* Ensures that the props specified for a component are valid.
* Implementations should check that props are valid and usually throw an Error if they are not.
* Implementations should not duplicate checks that the type system already guarantees.
*
* This method should be used instead of React's
* [propTypes](https://facebook.github.io/react/docs/reusable-components.html#prop-validation) feature.
* Like propTypes, these runtime checks run only in development mode.
*/
protected validateProps(_: P, __: boolean = false) {
// implement in subclass
}
}
2 changes: 2 additions & 0 deletions packages/core/src/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
*/

export * from "./abstractComponent";
export * from "./abstractComponentNewLifecycles";
export * from "./abstractPureComponent";
export * from "./abstractPureComponentNewLifecycles";
export * from "./alignment";
export * from "./boundary";
export * from "./colors";
Expand Down
11 changes: 9 additions & 2 deletions packages/core/src/components/alert/alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@
import classNames from "classnames";
import * as React from "react";

import { AbstractPureComponent, Classes, DISPLAYNAME_PREFIX, Intent, IProps, MaybeElement } from "../../common";
import {
AbstractPureComponentNewLifecycles,
Classes,
DISPLAYNAME_PREFIX,
Intent,
IProps,
MaybeElement,
} from "../../common";
import {
ALERT_WARN_CANCEL_ESCAPE_KEY,
ALERT_WARN_CANCEL_OUTSIDE_CLICK,
Expand Down Expand Up @@ -117,7 +124,7 @@ export interface IAlertProps extends IOverlayLifecycleProps, IProps {
onClose?(confirmed: boolean, evt?: React.SyntheticEvent<HTMLElement>): void;
}

export class Alert extends AbstractPureComponent<IAlertProps, {}> {
export class Alert extends AbstractPureComponentNewLifecycles<IAlertProps, {}> {
public static defaultProps: IAlertProps = {
canEscapeKeyCancel: false,
canOutsideClickCancel: false,
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/components/collapse/collapse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import classNames from "classnames";
import * as React from "react";
import { polyfill } from "react-lifecycles-compat";

import { AbstractPureComponent } from "../../common/abstractPureComponent";
import { AbstractPureComponentNewLifecycles } from "../../common/abstractPureComponentNewLifecycles";
import * as Classes from "../../common/classes";
import { DISPLAYNAME_PREFIX, IProps } from "../../common/props";

Expand Down Expand Up @@ -111,7 +111,7 @@ export interface ICollapseSnapshot {
height?: string;
}

export class Collapse extends AbstractPureComponent<ICollapseProps, ICollapseState, ICollapseSnapshot> {
export class Collapse extends AbstractPureComponentNewLifecycles<ICollapseProps, ICollapseState, ICollapseSnapshot> {
public static displayName = `${DISPLAYNAME_PREFIX}.Collapse`;

public static defaultProps: ICollapseProps = {
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/components/context-menu/contextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import classNames from "classnames";
import * as React from "react";
import * as ReactDOM from "react-dom";

import { AbstractPureComponent } from "../../common/abstractPureComponent";
import { AbstractPureComponentNewLifecycles } from "../../common/abstractPureComponentNewLifecycles";
import * as Classes from "../../common/classes";
import { Position } from "../../common/position";
import { safeInvoke } from "../../common/utils";
Expand Down Expand Up @@ -47,7 +47,7 @@ const TRANSITION_DURATION = 100;
type IContextMenuProps = IOverlayLifecycleProps;

/* istanbul ignore next */
class ContextMenu extends AbstractPureComponent<IContextMenuProps, IContextMenuState> {
class ContextMenu extends AbstractPureComponentNewLifecycles<IContextMenuProps, IContextMenuState> {
public state: IContextMenuState = {
isDarkTheme: false,
isOpen: false,
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/components/dialog/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import classNames from "classnames";
import * as React from "react";

import { AbstractPureComponent } from "../../common/abstractPureComponent";
import { AbstractPureComponentNewLifecycles } from "../../common/abstractPureComponentNewLifecycles";
import * as Classes from "../../common/classes";
import * as Errors from "../../common/errors";
import { DISPLAYNAME_PREFIX, IProps, MaybeElement } from "../../common/props";
Expand Down Expand Up @@ -72,7 +72,7 @@ export interface IDialogProps extends IOverlayableProps, IBackdropProps, IProps
transitionName?: string;
}

export class Dialog extends AbstractPureComponent<IDialogProps, {}> {
export class Dialog extends AbstractPureComponentNewLifecycles<IDialogProps, {}> {
public static defaultProps: IDialogProps = {
canOutsideClickClose: true,
isOpen: false,
Expand Down
Loading

0 comments on commit 7a523f4

Please sign in to comment.