* Preview markdown table as 5x5 max * Make linter happy * Determine max columns from device width * Add snapshot test * Use Dimensions and update unit tests * Remove async
This commit is contained in:
parent
1111818d9f
commit
b7d4d592cc
3 changed files with 281 additions and 1 deletions
|
|
@ -0,0 +1,177 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`MarkdownTable should match snapshot 1`] = `
|
||||
<TouchableWithFeedbackIOS
|
||||
onPress={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"paddingRight": 10,
|
||||
}
|
||||
}
|
||||
type="opacity"
|
||||
>
|
||||
<ScrollViewMock
|
||||
contentContainerStyle={
|
||||
Object {
|
||||
"width": 1000,
|
||||
}
|
||||
}
|
||||
onContentSizeChange={[Function]}
|
||||
onLayout={[Function]}
|
||||
scrollEnabled={false}
|
||||
showsVerticalScrollIndicator={false}
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"borderBottomWidth": 1,
|
||||
"borderColor": "rgba(61,60,64,0.2)",
|
||||
"borderRightWidth": 1,
|
||||
"maxHeight": 300,
|
||||
},
|
||||
Object {
|
||||
"maxWidth": 1000,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"borderColor": "rgba(61,60,64,0.2)",
|
||||
"borderLeftWidth": 1,
|
||||
"borderTopWidth": 1,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<
|
||||
className="row"
|
||||
>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
</>
|
||||
<
|
||||
className="row"
|
||||
>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
</>
|
||||
<
|
||||
className="row"
|
||||
>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
</>
|
||||
<
|
||||
className="row"
|
||||
>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
</>
|
||||
<
|
||||
className="row"
|
||||
isLastRow={true}
|
||||
>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
<
|
||||
className="col"
|
||||
/>
|
||||
</>
|
||||
</View>
|
||||
</ScrollViewMock>
|
||||
<TouchableWithFeedbackIOS
|
||||
onPress={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
"borderColor": "rgba(61,60,64,0.2)",
|
||||
"borderRadius": 15,
|
||||
"borderWidth": 1,
|
||||
"bottom": 20,
|
||||
"height": 30,
|
||||
"left": -20,
|
||||
"paddingLeft": 7,
|
||||
"paddingTop": 6,
|
||||
"width": 30,
|
||||
}
|
||||
}
|
||||
type="native"
|
||||
>
|
||||
<Icon
|
||||
allowFontScaling={false}
|
||||
name="expand"
|
||||
size={12}
|
||||
style={
|
||||
Object {
|
||||
"color": "#2389d7",
|
||||
"fontSize": 15,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</TouchableWithFeedbackIOS>
|
||||
</TouchableWithFeedbackIOS>
|
||||
`;
|
||||
|
|
@ -7,6 +7,7 @@ import {intlShape} from 'react-intl';
|
|||
import {
|
||||
ScrollView,
|
||||
View,
|
||||
Dimensions,
|
||||
} from 'react-native';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import Icon from 'react-native-vector-icons/FontAwesome';
|
||||
|
|
@ -19,6 +20,7 @@ import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
|
|||
import {goToScreen} from 'app/actions/navigation';
|
||||
|
||||
const MAX_HEIGHT = 300;
|
||||
const MAX_PREVIEW_COLUMNS = 5;
|
||||
|
||||
export default class MarkdownTable extends React.PureComponent {
|
||||
static propTypes = {
|
||||
|
|
@ -38,9 +40,23 @@ export default class MarkdownTable extends React.PureComponent {
|
|||
containerWidth: 0,
|
||||
contentHeight: 0,
|
||||
contentWidth: 0,
|
||||
maxPreviewColumns: MAX_PREVIEW_COLUMNS,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
Dimensions.addEventListener('change', this.setMaxPreviewColumns);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
Dimensions.removeEventListener('change', this.setMaxPreviewColumns);
|
||||
}
|
||||
|
||||
setMaxPreviewColumns = ({window}) => {
|
||||
const maxPreviewColumns = Math.floor(window.width / CELL_WIDTH);
|
||||
this.setState({maxPreviewColumns});
|
||||
}
|
||||
|
||||
getTableWidth = () => {
|
||||
return this.props.numColumns * CELL_WIDTH;
|
||||
};
|
||||
|
|
@ -73,6 +89,38 @@ export default class MarkdownTable extends React.PureComponent {
|
|||
});
|
||||
};
|
||||
|
||||
renderPreviewRows = (drawExtraBorders = true) => {
|
||||
const {maxPreviewColumns} = this.state;
|
||||
const style = getStyleSheet(this.props.theme);
|
||||
|
||||
const tableStyle = [style.table];
|
||||
if (drawExtraBorders) {
|
||||
tableStyle.push(style.tableExtraBorders);
|
||||
}
|
||||
|
||||
// Add an extra prop to the last row of the table so that it knows not to render a bottom border
|
||||
// since the container should be rendering that
|
||||
const rows = React.Children.toArray(this.props.children).slice(0, maxPreviewColumns).map((row) => {
|
||||
const children = React.Children.toArray(row.props.children).slice(0, maxPreviewColumns);
|
||||
return {
|
||||
...row,
|
||||
props: {
|
||||
...row.props,
|
||||
children,
|
||||
},
|
||||
};
|
||||
});
|
||||
rows[rows.length - 1] = React.cloneElement(rows[rows.length - 1], {
|
||||
isLastRow: true,
|
||||
});
|
||||
|
||||
return (
|
||||
<View style={tableStyle}>
|
||||
{rows}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
renderRows = (drawExtraBorders = true) => {
|
||||
const style = getStyleSheet(this.props.theme);
|
||||
|
||||
|
|
@ -152,7 +200,7 @@ export default class MarkdownTable extends React.PureComponent {
|
|||
showsVerticalScrollIndicator={false}
|
||||
style={[style.container, {maxWidth: this.getTableWidth()}]}
|
||||
>
|
||||
{this.renderRows(false)}
|
||||
{this.renderPreviewRows(false)}
|
||||
</ScrollView>
|
||||
{moreRight}
|
||||
{moreBelow}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {shallowWithIntl} from 'test/intl-test-helper';
|
||||
|
||||
import Preferences from 'mattermost-redux/constants/preferences';
|
||||
|
||||
import MarkdownTable from './markdown_table';
|
||||
|
||||
describe('MarkdownTable', () => {
|
||||
const createCell = (type, children = null) => {
|
||||
return React.createElement('', {key: Date.now(), className: type}, children);
|
||||
};
|
||||
|
||||
const numColumns = 10;
|
||||
const children = [];
|
||||
for (let i = 0; i <= numColumns; i++) {
|
||||
const cols = [];
|
||||
for (let j = 0; j <= numColumns; j++) {
|
||||
cols.push(createCell('col'));
|
||||
}
|
||||
|
||||
children.push(createCell('row', cols));
|
||||
}
|
||||
|
||||
const baseProps = {
|
||||
children,
|
||||
numColumns,
|
||||
theme: Preferences.THEMES.default,
|
||||
};
|
||||
|
||||
test('should match snapshot', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<MarkdownTable {...baseProps}/>
|
||||
);
|
||||
|
||||
expect(wrapper.getElement()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should slice rows and columns', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<MarkdownTable {...baseProps}/>
|
||||
);
|
||||
|
||||
const {maxPreviewColumns} = wrapper.state();
|
||||
expect(wrapper.find('.row')).toHaveLength(maxPreviewColumns);
|
||||
expect(wrapper.find('.col')).toHaveLength(Math.pow(maxPreviewColumns, 2));
|
||||
|
||||
const newMaxPreviewColumns = maxPreviewColumns - 1;
|
||||
wrapper.setState({maxPreviewColumns: newMaxPreviewColumns});
|
||||
expect(wrapper.find('.row')).toHaveLength(newMaxPreviewColumns);
|
||||
expect(wrapper.find('.col')).toHaveLength(Math.pow(newMaxPreviewColumns, 2));
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue