Skip to content

Commit e28ece5

Browse files
author
Carlos Paelinck
authored
Added <Appear /> order prop. (#400)
1 parent 7bd9626 commit e28ece5

File tree

4 files changed

+101
-16
lines changed

4 files changed

+101
-16
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,11 @@ The element tags are the bread and butter of your slide content. Most of these t
464464

465465
This tag does not extend from Base. It's special. Wrapping elements in the appear tag makes them appear/disappear in order in response to navigation.
466466

467+
|Name|PropType|Description|
468+
|---|---|---|
469+
|order|PropTypes.number| An optional integer starting at 1 for the presentation order of the Appear tags within a slide. If a slide contains ordered and unordered Appear tags, the unordered will show first.
470+
471+
467472
<a name="blockquote-quote-and-cite-base"></a>
468473
#### BlockQuote, Quote and Cite (Base)
469474

src/components/appear.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ class Appear extends Component {
2121
this.setState({ active: true });
2222
return;
2323
}
24+
25+
const order = this.props.order || 0;
26+
const node = findDOMNode(this.fragmentRef);
27+
if (!node.dataset) {
28+
node.dataset = {};
29+
}
30+
node.dataset.order = order;
2431
}
2532

2633
componentWillReceiveProps(nextProps) {
@@ -55,7 +62,6 @@ class Appear extends Component {
5562
const child = React.Children.only(this.props.children);
5663
const endValue = this.state.active ? 1 : 0;
5764
const transitionDuration = this.props.transitionDuration;
58-
5965
return (
6066
<VictoryAnimation
6167
data={{ opacity: endValue }}
@@ -64,7 +70,7 @@ class Appear extends Component {
6470
>
6571
{({ opacity }) =>
6672
React.cloneElement(child, {
67-
className: 'fragment',
73+
className: `fragment ${child.props.className}`.trim(),
6874
style: { ...child.props.style, ...this.props.style, opacity },
6975
ref: f => {
7076
this.fragmentRef = f;
@@ -82,6 +88,7 @@ Appear.defaultProps = {
8288
Appear.propTypes = {
8389
children: PropTypes.node,
8490
fragment: PropTypes.object,
91+
order: PropTypes.number,
8592
route: PropTypes.object,
8693
style: PropTypes.object,
8794
transitionDuration: PropTypes.number

src/components/slide.js

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,24 @@ class Slide extends React.PureComponent {
3232
this.setZoom();
3333
const slide = this.slideRef;
3434
const frags = slide.querySelectorAll('.fragment');
35+
let currentOrder = 0;
3536
if (frags && frags.length && !this.context.overview) {
36-
Array.prototype.slice.call(frags, 0).forEach((frag, i) => {
37-
frag.dataset.fid = i;
38-
return (
39-
this.props.dispatch &&
40-
this.props.dispatch(
41-
addFragment({
42-
slide: this.props.hash,
43-
id: `${this.props.slideIndex}-${i}`,
44-
visible: this.props.lastSlideIndex > this.props.slideIndex,
45-
})
46-
)
47-
);
48-
});
37+
Array.prototype.slice.call(frags, 0)
38+
.sort((lhs, rhs) => parseInt(lhs.dataset.order, 10) - parseInt(rhs.dataset.order, 10))
39+
.forEach(frag => {
40+
frag.dataset.fid = currentOrder;
41+
if (this.props.dispatch) {
42+
this.props.dispatch(
43+
addFragment({
44+
className: frag.className || '',
45+
slide: this.props.hash,
46+
id: `${this.props.slideIndex}-${currentOrder}`,
47+
visible: this.props.lastSlideIndex > this.props.slideIndex,
48+
})
49+
);
50+
}
51+
currentOrder += 1;
52+
});
4953
}
5054
window.addEventListener('load', this.setZoom);
5155
window.addEventListener('resize', this.setZoom);

src/components/slide.test.js

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react';
22
import { mount } from 'enzyme';
33
import Slide from './slide';
4+
import Appear from './appear';
45

56
const _mockContext = function() {
67
return {
@@ -15,7 +16,9 @@ const _mockContext = function() {
1516
},
1617
},
1718
store: {
18-
getState: () => ({ route: '' }),
19+
getState: () => ({ route: { params: '', slide: 0 } }),
20+
subscribe: () => {},
21+
dispatch: () => {}
1922
},
2023
};
2124
};
@@ -75,4 +78,70 @@ describe('<Slide />', () => {
7578
expect(spy).toHaveBeenCalledTimes(1);
7679
expect(spy).toBeCalledWith(5);
7780
});
81+
82+
test('should create <Appear /> fragments with their appearance in order', () => {
83+
const spy = jest.fn();
84+
mount(
85+
<Slide slideIndex={4} dispatch={spy} hash={4}>
86+
<Appear order={2} fragment={{ fragments: [] }}>
87+
<div className="second">This shows second</div>
88+
</Appear>
89+
<Appear order={3} fragment={{ fragments: [] }}>
90+
<div className="third">This shows third</div>
91+
</Appear>
92+
<Appear order={1} fragment={{ fragments: [] }}>
93+
<div className="first">This shows first</div>
94+
</Appear>
95+
</Slide>,
96+
{ context: _mockContext() }
97+
);
98+
expect(spy).toHaveBeenCalledTimes(3);
99+
expect(spy.mock.calls).toEqual([
100+
[{
101+
payload: { slide: 4, id: '4-0', visible: false, className: 'fragment first' },
102+
type: 'ADD_FRAGMENT'
103+
}],
104+
[{
105+
payload: { slide: 4, id: '4-1', visible: false, className: 'fragment second' },
106+
type: 'ADD_FRAGMENT'
107+
}],
108+
[{
109+
payload: { slide: 4, id: '4-2', visible: false, className: 'fragment third' },
110+
type: 'ADD_FRAGMENT'
111+
}]
112+
]);
113+
});
114+
115+
test('should order <Appear /> fragments without an order first', () => {
116+
const spy = jest.fn();
117+
mount(
118+
<Slide slideIndex={7} dispatch={spy} hash={7}>
119+
<Appear order={1} fragment={{ fragments: [] }}>
120+
<div className="first">This shows second</div>
121+
</Appear>
122+
<Appear fragment={{ fragments: [] }}>
123+
<div className="no-order">This shows third</div>
124+
</Appear>
125+
<Appear order={2} fragment={{ fragments: [] }}>
126+
<div className="second">This shows first</div>
127+
</Appear>
128+
</Slide>,
129+
{ context: _mockContext() }
130+
);
131+
expect(spy).toHaveBeenCalledTimes(3);
132+
expect(spy.mock.calls).toEqual([
133+
[{
134+
payload: { slide: 7, id: '7-0', visible: false, className: 'fragment no-order' },
135+
type: 'ADD_FRAGMENT'
136+
}],
137+
[{
138+
payload: { slide: 7, id: '7-1', visible: false, className: 'fragment first' },
139+
type: 'ADD_FRAGMENT'
140+
}],
141+
[{
142+
payload: { slide: 7, id: '7-2', visible: false, className: 'fragment second' },
143+
type: 'ADD_FRAGMENT'
144+
}]
145+
]);
146+
});
78147
});

0 commit comments

Comments
 (0)