Skip to content

Commit

Permalink
React 16 step 1, squashed
Browse files Browse the repository at this point in the history
  • Loading branch information
tlrobinson committed Apr 2, 2018
1 parent adcd6b4 commit d97214b
Show file tree
Hide file tree
Showing 27 changed files with 1,095 additions and 787 deletions.
4 changes: 4 additions & 0 deletions .flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
.*/node_modules/react-resizable/.*
.*/node_modules/documentation/.*
.*/node_modules/.*/\(lib\|test\).*\.json$
.*/node_modules/react-element-to-jsx-string/.*
.*/node_modules/react-element-to-jsx-string/.*
.*/node_modules/resize-observer-polyfill/.*
.*/node_modules/react-virtualized/.*

[include]
.*/frontend/.*
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/metabase/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,22 @@ const getErrorComponent = ({ status, data, context }) => {

@connect(mapStateToProps)
export default class App extends Component {
state = {
hasError: false,
};

componentDidCatch(error, info) {
console.error("Error caught in <App>", error, info);
this.setState({ hasError: true });
}

render() {
const { children, location, errorPage } = this.props;

if (this.state.hasError) {
return <div>😢</div>;
}

return (
<div className="spread flex flex-column">
<Navbar location={location} className="flex-no-shrink" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { Component, PropTypes } from "react";
import React, { Component } from "react";
import PropTypes from "prop-types";

import _ from "underscore";
import cx from "classnames";
Expand Down
36 changes: 20 additions & 16 deletions frontend/src/metabase/components/ExplicitSize.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,22 @@ export default ComposedComponent =>
this._mql.addListener(this._updateSize);
}

// resize observer, ensure re-layout when container element changes size
this._ro = new ResizeObserver((entries, observer) => {
const element = ReactDOM.findDOMNode(this);
for (const entry of entries) {
if (entry.target === element) {
this._updateSize();
break;
const element = ReactDOM.findDOMNode(this);
if (element) {
// resize observer, ensure re-layout when container element changes size
this._ro = new ResizeObserver((entries, observer) => {
const element = ReactDOM.findDOMNode(this);
for (const entry of entries) {
if (entry.target === element) {
this._updateSize();
break;
}
}
}
});
this._ro.observe(ReactDOM.findDOMNode(this));
});
this._ro.observe(element);

this._updateSize();
this._updateSize();
}
}

componentDidUpdate() {
Expand All @@ -53,11 +56,12 @@ export default ComposedComponent =>
}

_updateSize = () => {
const { width, height } = ReactDOM.findDOMNode(
this,
).getBoundingClientRect();
if (this.state.width !== width || this.state.height !== height) {
this.setState({ width, height });
const element = ReactDOM.findDOMNode(this);
if (element) {
const { width, height } = element.getBoundingClientRect();
if (this.state.width !== width || this.state.height !== height) {
this.setState({ width, height });
}
}
};

Expand Down
6 changes: 3 additions & 3 deletions frontend/src/metabase/components/Modal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import cx from "classnames";

import { getScrollX, getScrollY } from "metabase/lib/dom";

import ReactCSSTransitionGroup from "react-addons-css-transition-group";
import { CSSTransitionGroup } from "react-transition-group";
import { Motion, spring } from "react-motion";

import OnClickOutsideWrapper from "./OnClickOutsideWrapper.jsx";
Expand Down Expand Up @@ -88,7 +88,7 @@ export class WindowModal extends Component {
"flex justify-center align-center fixed top left bottom right";
ReactDOM.unstable_renderSubtreeIntoContainer(
this,
<ReactCSSTransitionGroup
<CSSTransitionGroup
transitionName="Modal"
transitionAppear={true}
transitionAppearTimeout={250}
Expand All @@ -104,7 +104,7 @@ export class WindowModal extends Component {
{this._modalComponent()}
</div>
)}
</ReactCSSTransitionGroup>,
</CSSTransitionGroup>,
this._modalElement,
);
}
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/metabase/components/Popover.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import ReactDOM from "react-dom";
import ReactCSSTransitionGroup from "react-addons-css-transition-group";
import { CSSTransitionGroup } from "react-transition-group";

import OnClickOutsideWrapper from "./OnClickOutsideWrapper";
import Tether from "tether";
Expand Down Expand Up @@ -259,7 +259,7 @@ export default class Popover extends Component {
const popoverElement = this._getPopoverElement();
ReactDOM.unstable_renderSubtreeIntoContainer(
this,
<ReactCSSTransitionGroup
<CSSTransitionGroup
transitionName="Popover"
transitionAppear
transitionEnter
Expand All @@ -269,7 +269,7 @@ export default class Popover extends Component {
transitionLeaveTimeout={POPOVER_TRANSITION_LEAVE}
>
{isOpen ? this._popoverComponent() : null}
</ReactCSSTransitionGroup>,
</CSSTransitionGroup>,
popoverElement,
);

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/metabase/components/UserAvatar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default class UserAvatar extends Component {
return (
<div
className={cx(classes)}
style={Object.assign(this.styles, this.props.style)}
style={{ ...this.styles, ...this.props.style }}
>
{this.userInitials()}
</div>
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/metabase/containers/SaveQuestionModal.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { Component } from "react";
import PropTypes from "prop-types";

import ReactCSSTransitionGroup from "react-addons-css-transition-group";
import { CSSTransitionGroup } from "react-transition-group";

import FormField from "metabase/components/FormField.jsx";
import ModalContent from "metabase/components/ModalContent.jsx";
Expand Down Expand Up @@ -201,7 +201,7 @@ export default class SaveQuestionModal extends Component {
>
<form className="Form-inputs" onSubmit={this.formSubmitted}>
{saveOrUpdate}
<ReactCSSTransitionGroup
<CSSTransitionGroup
transitionName="saveQuestionModalFields"
transitionEnterTimeout={500}
transitionLeaveTimeout={500}
Expand Down Expand Up @@ -275,7 +275,7 @@ export default class SaveQuestionModal extends Component {
</CollectionList>
</div>
)}
</ReactCSSTransitionGroup>
</CSSTransitionGroup>
</form>
</ModalContent>
);
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/metabase/containers/UndoListing.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { t } from "c-3po";
import Icon from "metabase/components/Icon";
import BodyComponent from "metabase/components/BodyComponent";

import ReactCSSTransitionGroup from "react-addons-css-transition-group";
import { CSSTransitionGroup } from "react-transition-group";

const mapStateToProps = (state, props) => {
return {
Expand All @@ -37,7 +37,7 @@ export default class UndoListing extends Component {
const { undos, performUndo, dismissUndo } = this.props;
return (
<ul className={S.listing}>
<ReactCSSTransitionGroup
<CSSTransitionGroup
transitionName="UndoListing"
transitionEnterTimeout={300}
transitionLeaveTimeout={300}
Expand Down Expand Up @@ -65,7 +65,7 @@ export default class UndoListing extends Component {
)}
</li>
))}
</ReactCSSTransitionGroup>
</CSSTransitionGroup>
</ul>
);
}
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/metabase/internal/components/ComponentsApp.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ import React, { Component } from "react";
import { Link, Route } from "react-router";

import { slugify } from "metabase/lib/formatting";

// $FlowFixMe: react-virtualized ignored
import reactElementToJSXString from "react-element-to-jsx-string";

import COMPONENTS from "../lib/components-webpack";

import AceEditor from "metabase/components/TextEditor";
import CopyButton from "metabase/components/CopyButton";

Expand Down
3 changes: 3 additions & 0 deletions frontend/src/metabase/lib/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ export function addCSSRule(selector, rules, index = 0) {
}

export function constrainToScreen(element, direction, padding) {
if (!element) {
return false;
}
if (direction === "bottom") {
let screenBottom = window.innerHeight + getScrollY();
let overflowY = element.getBoundingClientRect().bottom - screenBottom;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export default class AggregationPopover extends Component {
customFields: PropTypes.object,
availableAggregations: PropTypes.array,
// Restricts the shown options to contents of `availableActions` only
showOnlyProvidedAggregations: PropTypes.boolean,
showOnlyProvidedAggregations: PropTypes.bool,
};

componentDidUpdate() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
/* eslint "react/prop-types": "warn" */

import React from "react";
import React, { Component } from "react";
import { t, jt } from "c-3po";

import VisualizationErrorMessage from "./VisualizationErrorMessage";
import Visualization from "metabase/visualizations/components/Visualization.jsx";
import { datasetContainsNoResults } from "metabase/lib/dataset";
import { DatasetQuery } from "metabase/meta/types/Card";
import { CreateAlertModalContent } from "metabase/query_builder/components/AlertModals";
import { Component } from "react/lib/ReactBaseClasses";
import Modal from "metabase/components/Modal";
import { ALERT_TYPE_ROWS } from "metabase-lib/lib/Alert";

Expand Down
1 change: 1 addition & 0 deletions frontend/src/metabase/questions/components/List.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Item from "./Item";

import S from "./List.css";

// $FlowFixMe: react-virtualized ignored
import { List as VirtalizedList, WindowScroller } from "react-virtualized";
import "react-virtualized/styles.css";

Expand Down
6 changes: 3 additions & 3 deletions frontend/src/metabase/reference/components/Formula.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { Component } from "react";
import cx from "classnames";
import { connect } from "react-redux";
import { t } from "c-3po";
import ReactCSSTransitionGroup from "react-addons-css-transition-group";
import { CSSTransitionGroup } from "react-transition-group";

import S from "./Formula.css";

Expand Down Expand Up @@ -52,7 +52,7 @@ export default class Formula extends Component {
<Icon name="beaker" size={24} />
<span className={S.formulaTitle}>{t`View the ${type} formula`}</span>
</div>
<ReactCSSTransitionGroup
<CSSTransitionGroup
transitionName="formulaDefinition"
transitionEnterTimeout={300}
transitionLeaveTimeout={300}
Expand All @@ -66,7 +66,7 @@ export default class Formula extends Component {
/>
</div>
)}
</ReactCSSTransitionGroup>
</CSSTransitionGroup>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as React from "react";
import React from "react";
import { t } from "c-3po";

import AdminAwareEmptyState from "metabase/components/AdminAwareEmptyState";
Expand Down
1 change: 1 addition & 0 deletions frontend/src/metabase/tutorial/PageFlag.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
}

.PageFlag:after {
top: 0;
left: -12px;
border-top: 12px solid transparent;
border-bottom: 12px solid transparent;
Expand Down
33 changes: 28 additions & 5 deletions frontend/src/metabase/tutorial/PageFlag.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,39 @@ import React, { Component } from "react";

import "./PageFlag.css";

import ReactCSSTransitionGroup from "react-addons-css-transition-group";
import { CSSTransitionGroup } from "react-transition-group";

import BodyComponent from "metabase/components/BodyComponent.jsx";
import BodyComponent from "metabase/components/BodyComponent";

import cx from "classnames";

@BodyComponent
export default class PageFlag extends Component {
componentWillMount() {
// sometimes the position of target changes, track it here
this._timer = setInterval(() => {
if (this.props.target) {
const p1 = this._position;
const p2 = this.props.target.getBoundingClientRect();
if (
!p1 ||
p1.left !== p2.left ||
p1.top !== p2.top ||
p1.width !== p2.width ||
p1.height !== p2.height
) {
this.forceUpdate();
}
}
}, 100);
}

componentWillUnmount() {
clearInterval(this._timer);
}

renderPageFlag() {
let position = this.props.target.getBoundingClientRect();
let position = (this._position = this.props.target.getBoundingClientRect());
let isLarge = !!this.props.text;
let style = {
position: "absolute",
Expand All @@ -34,13 +57,13 @@ export default class PageFlag extends Component {

render() {
return (
<ReactCSSTransitionGroup
<CSSTransitionGroup
transitionName="PageFlag"
transitionEnterTimeout={250}
transitionLeaveTimeout={250}
>
{this.props.target ? [this.renderPageFlag()] : []}
</ReactCSSTransitionGroup>
</CSSTransitionGroup>
);
}
}
Loading

0 comments on commit d97214b

Please sign in to comment.