Skip to content

Commit bb0356d

Browse files
authored
Merge pull request wadackel#27 from ilyalesik/master
horizontal prop
2 parents dbd63ac + 3f8afdb commit bb0356d

6 files changed

Lines changed: 233 additions & 9 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ You can set the following properties.
107107
| `userAgent` | `PropTypes.string` | `undefined` | Specify userAgent for determinig the vendor prefix. See [inline-style-prefixer](https://github.com/rofrischmann/inline-style-prefixer). |
108108
| `enableSSR` | `PropTypes.bool` | `false` | Render component on the server side. [More info](https://github.com/ctrlplusb/react-sizeme#server-side-rendering). |
109109
| `onLayout` | `PropTypes.func` | `null` | It is called at the timing when the layout is confirmed, or at the updated timing. (Called only by client.) |
110-
110+
| `horizontal` | `PropTypes.bool` | `false` | The transposed (horizontal) order of drawing elements. Retains the original order of the items. |
111111

112112

113113

‎docs/js/components/Header.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const Header = () => (
99
<nav>
1010
<ul>
1111
<li><IndexLink to="/" activeClassName="is-active">Home</IndexLink></li>
12+
<li><Link to="/horizontal/" activeClassName="is-active">Horizontal</Link></li>
1213
<li><Link to="/change-size/" activeClassName="is-active">Change Size</Link></li>
1314
<li><Link to="/real-world/" activeClassName="is-active">Real World</Link></li>
1415
<li><a href="https://github.com/tsuyoshiwada/react-stack-grid">GitHub</a></li>

‎docs/js/pages/HorizontalFlow.js‎

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
/* eslint-disable class-methods-use-this */
2+
/* eslint-disable react/prop-types */
3+
/* eslint-disable jsx-a11y/no-static-element-interactions */
4+
import React, { Component } from 'react';
5+
import StackGrid, { transitions, easings } from '../../../src/';
6+
import DemoControl from '../components/DemoControl';
7+
8+
const itemModifier = [
9+
'pattern1',
10+
'pattern2',
11+
'pattern3',
12+
'gray',
13+
'gray-light',
14+
'gray-dark',
15+
'yellow',
16+
'pink',
17+
'purple',
18+
];
19+
20+
export default class HorizontalFlow extends Component {
21+
constructor(props) {
22+
super(props);
23+
24+
const items = [];
25+
26+
for (let i = 0; i < 10; i += 1) {
27+
items.push(this.createItem());
28+
}
29+
30+
this.state = {
31+
items,
32+
duration: 480,
33+
columnWidth: 150,
34+
gutter: 5,
35+
easing: easings.quartOut,
36+
transition: 'fadeDown',
37+
};
38+
}
39+
40+
createItem() {
41+
const id = Math.random().toString(36).substr(2, 9);
42+
const height = Math.floor((Math.random() * (300 - 80)) + 80);
43+
const modifier = itemModifier[Math.floor(Math.random() * itemModifier.length)];
44+
45+
return { id, height, modifier };
46+
}
47+
48+
shuffleItems = () => {
49+
const newItems = [...this.state.items];
50+
let i = newItems.length;
51+
52+
while (i) {
53+
const j = Math.floor(Math.random() * i);
54+
const t = newItems[--i]; // eslint-disable-line no-plusplus
55+
newItems[i] = newItems[j];
56+
newItems[j] = t;
57+
}
58+
59+
this.setState({ items: newItems });
60+
}
61+
62+
prependItem = () => {
63+
this.setState({
64+
items: [this.createItem(), ...this.state.items],
65+
});
66+
}
67+
68+
appendItem = () => {
69+
this.setState({
70+
items: [...this.state.items, this.createItem()],
71+
});
72+
}
73+
74+
multipleAppendItem = () => {
75+
const newItems = [];
76+
77+
for (let i = 0; i < 5; i += 1) {
78+
newItems.push(this.createItem());
79+
}
80+
81+
this.setState({
82+
items: [...this.state.items, ...newItems],
83+
});
84+
}
85+
86+
removeItem = (id) => {
87+
this.setState({
88+
items: this.state.items.filter(o => o.id !== id),
89+
});
90+
}
91+
92+
handleDurationChange = (duration) => {
93+
this.setState({ duration });
94+
}
95+
96+
handleColumnWidthChange = (columnWidth) => {
97+
this.setState({ columnWidth });
98+
}
99+
100+
handleGutterChange = (gutter) => {
101+
this.setState({ gutter });
102+
}
103+
104+
handleEasingChange = (easing) => {
105+
this.setState({ easing });
106+
}
107+
108+
handleTransitionChange = (transition) => {
109+
this.setState({ transition });
110+
}
111+
112+
render() {
113+
const {
114+
items,
115+
duration,
116+
columnWidth,
117+
gutter,
118+
easing,
119+
transition: transitionSelect,
120+
} = this.state;
121+
122+
const transition = transitions[transitionSelect];
123+
124+
return (
125+
<div>
126+
<DemoControl
127+
duration={duration}
128+
columnWidth={columnWidth}
129+
gutter={gutter}
130+
easing={easing}
131+
transition={transition}
132+
onShuffle={this.shuffleItems}
133+
onPrepend={this.prependItem}
134+
onAppend={this.appendItem}
135+
onMultipleAppend={this.multipleAppendItem}
136+
onDurationChange={this.handleDurationChange}
137+
onColumnWidthChange={this.handleColumnWidthChange}
138+
onGutterChange={this.handleGutterChange}
139+
onEasingChange={this.handleEasingChange}
140+
onTransitionChange={this.handleTransitionChange}
141+
/>
142+
143+
<StackGrid
144+
horizontal
145+
duration={duration}
146+
columnWidth={columnWidth}
147+
gutterWidth={gutter}
148+
gutterHeight={gutter}
149+
easing={easing}
150+
appear={transition.appear}
151+
appeared={transition.appeared}
152+
enter={transition.enter}
153+
entered={transition.entered}
154+
leaved={transition.leaved}
155+
onLayout={() => {
156+
console.log('[DEMO] `onLayout()` has been called.'); // eslint-disable-line
157+
}}
158+
>
159+
{items.map(item =>
160+
(<div
161+
key={item.id}
162+
className={`item item--${item.modifier}`}
163+
style={{ height: item.height }}
164+
onClick={() => this.removeItem(item.id)}
165+
/>)
166+
)}
167+
</StackGrid>
168+
</div>
169+
);
170+
}
171+
}

‎docs/js/routes.js‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ import App from './App';
55
import Home from './pages/Home';
66
import ChangeSize from './pages/ChangeSize';
77
import RealWorld from './pages/RealWorld';
8+
import HorizontalFlow from './pages/HorizontalFlow';
89

910
const routes = () => (
1011
<Route path="/" component={App}>
1112
<IndexRoute component={Home} />
13+
<Route path="/horizontal/" component={HorizontalFlow} />
1214
<Route path="/change-size/" component={ChangeSize} />
1315
<Route path="/real-world/" component={RealWorld} />
1416
</Route>

‎src/components/StackGrid.js‎

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ const propTypes = {
132132
userAgent: PropTypes.string,
133133
enableSSR: PropTypes.bool,
134134
onLayout: PropTypes.func,
135+
horizontal: PropTypes.bool,
135136
};
136137
/* eslint-enable react/no-unused-prop-types */
137138

@@ -220,6 +221,7 @@ export class GridInline extends Component {
220221
columnWidth: rawColumnWidth,
221222
gutterWidth,
222223
gutterHeight,
224+
horizontal,
223225
} = props;
224226

225227
const childArray = React.Children.toArray(props.children);
@@ -230,16 +232,38 @@ export class GridInline extends Component {
230232
);
231233
const columnHeights = createArray(0, maxColumn);
232234

233-
const rects = childArray.map((child) => {
234-
const column = columnHeights.indexOf(Math.min(...columnHeights));
235-
const height = this.getItemHeight(child);
236-
const left = (column * columnWidth) + (column * gutterWidth);
237-
const top = columnHeights[column];
235+
let rects;
236+
if (!horizontal) {
237+
rects = childArray.map((child) => {
238+
const column = columnHeights.indexOf(Math.min(...columnHeights));
239+
const height = this.getItemHeight(child);
240+
const left = (column * columnWidth) + (column * gutterWidth);
241+
const top = columnHeights[column];
238242

239-
columnHeights[column] += Math.round(height) + gutterHeight;
243+
columnHeights[column] += Math.round(height) + gutterHeight;
240244

241-
return { top, left, width: columnWidth, height };
242-
});
245+
return { top, left, width: columnWidth, height };
246+
});
247+
} else {
248+
const sumHeights = childArray.reduce(
249+
(sum, child) => sum + Math.round(this.getItemHeight(child)) + gutterHeight, 0);
250+
const maxHeight = sumHeights / maxColumn;
251+
252+
let currentColumn = 0;
253+
rects = childArray.map((child) => {
254+
const column = currentColumn >= maxColumn - 1 ? maxColumn - 1 : currentColumn;
255+
const height = this.getItemHeight(child);
256+
const left = (column * columnWidth) + (column * gutterWidth);
257+
const top = columnHeights[column];
258+
259+
columnHeights[column] += Math.round(height) + gutterHeight;
260+
if (columnHeights[column] >= maxHeight) {
261+
currentColumn += 1;
262+
}
263+
264+
return { top, left, width: columnWidth, height };
265+
});
266+
}
243267

244268
const width = (maxColumn * columnWidth) + ((maxColumn - 1) * gutterWidth);
245269
const height = Math.max(...columnHeights) - gutterHeight;
@@ -315,6 +339,7 @@ export class GridInline extends Component {
315339
monitorImagesLoaded,
316340
enableSSR,
317341
onLayout,
342+
horizontal,
318343
refCallback,
319344
/* eslint-enable no-unused-vars */
320345
className,
@@ -399,6 +424,7 @@ export default class StackGrid extends Component {
399424
userAgent: null,
400425
enableSSR: false,
401426
onLayout: null,
427+
horizontal: false,
402428
};
403429

404430
props: Props;

‎src/components/__tests__/StackGrid.spec.js‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,28 @@ describe('<StackGrid /> (GridInline)', () => {
128128

129129
expect(callback.mock.calls.length).toBe(2);
130130
});
131+
132+
test('Should be use horizontal', () => {
133+
const testMockProps = Object.assign({}, mockProps, {
134+
size: {
135+
width: 320,
136+
height: 0,
137+
},
138+
horizontal: true,
139+
});
140+
141+
const wrapper = mount(
142+
<GridInline {...testMockProps}>
143+
<div className="item" key="1">ITEM 1</div>
144+
<div className="item" key="2">ITEM 2</div>
145+
<div className="item" key="3">ITEM 3</div>
146+
<div className="item" key="4">ITEM 4</div>
147+
</GridInline>
148+
);
149+
150+
expect(wrapper.find('span').at(0).prop('style').transform).toBe('translateX(7.5px) translateY(10px)');
151+
expect(wrapper.find('span').at(1).prop('style').transform).toBe('translateX(7.5px) translateY(15px)');
152+
expect(wrapper.find('span').at(2).prop('style').transform).toBe('translateX(162.5px) translateY(10px)');
153+
expect(wrapper.find('span').at(3).prop('style').transform).toBe('translateX(162.5px) translateY(15px)');
154+
});
131155
});

0 commit comments

Comments
 (0)