Skip to content
39 changes: 26 additions & 13 deletions src/components/component-playground.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { Component } from 'react';
import isEmpty from 'lodash/isEmpty';
import PropTypes from 'prop-types';
import styled, { css } from 'react-emotion';
import { defaultCode } from '../utils/playground.default-code';
Expand Down Expand Up @@ -138,10 +139,6 @@ function getEnhancedScope(scope = {}) {
return { Component, ...scope };
}

// TODO(540): Refactor to non-deprecated lifecycle methods.
// https://github.com/FormidableLabs/spectacle/issues/540
// - componentWillReceiveProps
// eslint-disable-next-line react/no-deprecated
class ComponentPlayground extends Component {
constructor() {
super(...arguments);
Expand All @@ -156,26 +153,42 @@ class ComponentPlayground extends Component {
};
}

static getDerivedStateFromProps(nextProps, prevState) {
const updatedState = {};
if (nextProps.code !== prevState.code) {
const code = (nextProps.code || defaultCode).trim();
updatedState.code = code;
}
if (nextProps.scope !== prevState.scope) {
const scope = getEnhancedScope(nextProps.scope);
updatedState.scope = scope;
}
return isEmpty(updatedState) ? null : updatedState;
}

componentDidMount() {
localStorage.setItem(STORAGE_KEY, this.state.code);
window.addEventListener('storage', this.syncCode);
}

componentWillReceiveProps(nextProps) {
if (nextProps.code !== this.props.code) {
const code = (this.props.code || defaultCode).trim();
this.setState({ code });
}
if (nextProps.scope !== this.props.scope) {
const scope = getEnhancedScope(nextProps.scope);
this.setState({ scope });
}
componentDidUpdate() {
this.playgroundSetState();
}

componentWillUnmount() {
window.removeEventListener('storage', this.syncCode);
}

playgroundSetState() {
if (this.props.code) {
const code = (this.props.code || defaultCode).trim();
this.setState({ code });
}
if (this.props.scope) {
const scope = getEnhancedScope(this.props.scope);
this.setState({ scope });
}
}
onKeyUp(evt) {
evt.stopPropagation();

Expand Down
16 changes: 10 additions & 6 deletions src/components/heading.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,6 @@ const dynamicStyledHeaders = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].reduce(
{}
);

// TODO(540): Refactor to non-deprecated lifecycle methods.
// https://github.com/FormidableLabs/spectacle/issues/540
// - componentWillReceiveProps
// eslint-disable-next-line react/no-deprecated
export default class Heading extends Component {
constructor() {
super(...arguments);
Expand All @@ -69,9 +65,17 @@ export default class Heading extends Component {
window.addEventListener('load', this.resize);
window.addEventListener('resize', this.resize);
}
componentWillReceiveProps() {
this.resize();

static getDerivedStateFromProps(nextProps, prevState) {
return nextProps.fit !== prevState.fit ? { fit: nextProps.fit } : null;
}

componentDidUpdate(prevProps) {
if (prevProps.fit !== this.props.fit) {
this.resize();
}
}

componentWillUnmount() {
window.removeEventListener('load', this.resize);
window.removeEventListener('resize', this.resize);
Expand Down
73 changes: 36 additions & 37 deletions src/components/magic-wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ class Context extends Component {
}
}

// TODO(540): Refactor to non-deprecated lifecycle methods.
// https://github.com/FormidableLabs/spectacle/issues/540
// - componentWillReceiveProps
// eslint-disable-next-line react/no-deprecated
export default class MagicText extends Component {
static contextTypes = {
contentHeight: PropTypes.number,
Expand Down Expand Up @@ -86,6 +82,12 @@ export default class MagicText extends Component {
renderedChildren: props.children
};
}

static getDerivedStateFromProps(nextProps, prevState) {
return nextProps.magicIndex !== prevState.magicIndex
? { magicIndex: nextProps.magicIndex }
: null;
}
componentDidMount() {
this.mounted = true;
this.portal = document.getElementById('portal');
Expand Down Expand Up @@ -122,42 +124,10 @@ export default class MagicText extends Component {
}
);
}
componentWillReceiveProps(nextProps) {
if (this.props.magicIndex === nextProps.magicIndex) {
return;
}
ReactDOM.render(
<Context context={this.context}>
<Deck>{nextProps.children}</Deck>
</Context>,
this.portal,
() => {
const styles = {};
const portalRoot = get(this.portal, 'childNodes[0].childNodes[0]');
if (portalRoot) {
updateChildren(portalRoot);
buildStyleMap(styles, portalRoot);
this.diffs = detailedDiff(this.portalMap, styles);
this.lastPortalMap = this.portalMap;
this.portalMap = styles;
if (this.mounted) {
this.setState(
{
renderedChildren: nextProps.children
},
() => {
this.forceUpdate();
}
);
}
}
}
);
}
shouldComponentUpdate() {
return false;
}
componentDidUpdate() {
componentDidUpdate(prevProps) {
const containerRoot = get(this.container, 'childNodes[0]');
if (containerRoot) {
updateChildren(containerRoot);
Expand Down Expand Up @@ -199,6 +169,35 @@ export default class MagicText extends Component {
}
});
}
if (this.props.magicIndex !== prevProps.magicIndex) {
ReactDOM.render(
<Context context={this.context}>
<Deck>{this.props.children}</Deck>
</Context>,
this.portal,
() => {
const styles = {};
const portalRoot = get(this.portal, 'childNodes[0].childNodes[0]');
if (portalRoot) {
updateChildren(portalRoot);
buildStyleMap(styles, portalRoot);
this.diffs = detailedDiff(this.portalMap, styles);
this.lastPortalMap = this.portalMap;
this.portalMap = styles;
if (this.mounted) {
this.setState(
{
renderedChildren: this.props.children
},
() => {
this.forceUpdate();
}
);
}
}
}
);
}
this.lastDiffs = this.diffs;
}
componentWillUnmount() {
Expand Down
96 changes: 42 additions & 54 deletions src/components/manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,44 @@ const StyledTransition = styled(ReactTransitionGroup)({
transformStyle: 'flat'
});

// TODO(540): Refactor to non-deprecated lifecycle methods.
// https://github.com/FormidableLabs/spectacle/issues/540
// - componentWillMount
// - componentWillReceiveProps
// eslint-disable-next-line react/no-deprecated
function buildSlideReference(props) {
const slideReference = [];
Children.toArray(props.children).forEach((child, rootIndex) => {
if (child.type === Magic) {
Children.toArray(child.props.children).forEach((setSlide, magicIndex) => {
const reference = {
id: setSlide.props.id || slideReference.length,
magicIndex,
rootIndex
};
slideReference.push(reference);
});
} else if (!child.props.hasSlideChildren) {
const reference = {
id: child.props.id || slideReference.length,
rootIndex
};
if (child.props.goTo) {
reference.goTo = child.props.goTo;
}
slideReference.push(reference);
} else {
child.props.children.forEach((setSlide, setIndex) => {
const reference = {
id: setSlide.props.id || slideReference.length,
setIndex,
rootIndex
};
if (child.props.goTo) {
reference.goTo = child.props.goTo;
}
slideReference.push(reference);
});
}
});
return slideReference;
}

export class Manager extends Component {
static displayName = 'Manager';

Expand Down Expand Up @@ -146,10 +179,8 @@ export class Manager extends Component {
};
}

componentWillMount() {
this.setState({
slideReference: this._buildSlideReference(this.props)
});
static getDerivedStateFromProps(nextProps) {
return { slideReference: buildSlideReference(nextProps) };
}

componentDidMount() {
Expand All @@ -163,12 +194,6 @@ export class Manager extends Component {
}
}

componentWillReceiveProps(nextProps) {
this.setState({
slideReference: this._buildSlideReference(nextProps)
});
}

componentDidUpdate() {
if (
this.props.globalStyles &&
Expand All @@ -177,6 +202,7 @@ export class Manager extends Component {
this.props.dispatch(setGlobalStyle());
}
}

componentWillUnmount() {
this._detachEvents();
}
Expand Down Expand Up @@ -670,45 +696,7 @@ export class Manager extends Component {

return 0;
}
_buildSlideReference(props) {
const slideReference = [];
Children.toArray(props.children).forEach((child, rootIndex) => {
if (child.type === Magic) {
Children.toArray(child.props.children).forEach(
(setSlide, magicIndex) => {
const reference = {
id: setSlide.props.id || slideReference.length,
magicIndex,
rootIndex
};
slideReference.push(reference);
}
);
} else if (!child.props.hasSlideChildren) {
const reference = {
id: child.props.id || slideReference.length,
rootIndex
};
if (child.props.goTo) {
reference.goTo = child.props.goTo;
}
slideReference.push(reference);
} else {
child.props.children.forEach((setSlide, setIndex) => {
const reference = {
id: setSlide.props.id || slideReference.length,
setIndex,
rootIndex
};
if (child.props.goTo) {
reference.goTo = child.props.goTo;
}
slideReference.push(reference);
});
}
});
return slideReference;
}

_getSlideIndex() {
let index = parseInt(this.props.route.slide);
if (!Number.isFinite(index)) {
Expand Down
6 changes: 1 addition & 5 deletions src/components/notes.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { Component } from 'react';
import PropTypes from 'prop-types';

// TODO(540): Refactor to non-deprecated lifecycle methods.
// https://github.com/FormidableLabs/spectacle/issues/540
// - componentWillMount
// eslint-disable-next-line react/no-deprecated
export default class Notes extends Component {
static contextTypes = {
store: PropTypes.object,
Expand All @@ -16,7 +12,7 @@ export default class Notes extends Component {
children: PropTypes.node.isRequired
};

componentWillMount() {
componentDidMount() {
const { store, slideHash: parentSlide, updateNotes } = this.context;
const currentSlide = store.getState().route.slide;

Expand Down
15 changes: 9 additions & 6 deletions src/components/text.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@ const UnfitText = styled.p(({ lineHeight, styles }) => [
styles.user
]);

// TODO(540): Refactor to non-deprecated lifecycle methods.
// https://github.com/FormidableLabs/spectacle/issues/540
// - componentWillReceiveProps
// eslint-disable-next-line react/no-deprecated
export default class Text extends Component {
constructor() {
super(...arguments);
Expand All @@ -49,13 +45,20 @@ export default class Text extends Component {
};
}

static getDerivedStateFromProps(nextProps, prevState) {
return nextProps.fit !== prevState.fit ? { fit: nextProps.fit } : null;
}

componentDidMount() {
this.resize();
window.addEventListener('load', this.resize);
window.addEventListener('resize', this.resize);
}
componentWillReceiveProps() {
this.resize();

componentDidUpdate(prevProps) {
if (prevProps.fit !== this.props.fit) {
this.resize();
}
}
componentWillUnmount() {
window.removeEventListener('load', this.resize);
Expand Down