Skip to content

Commit

Permalink
fix(react-grid-bootstrap3): add fallback position sticky css property…
Browse files Browse the repository at this point in the history
… for Safari
  • Loading branch information
Andrey Churkin committed Apr 11, 2019
1 parent 87143b9 commit c135acc
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export const TableContainer = ({
WebkitOverflowScrolling: 'touch',
border: 0,
margin: 0,
// NOTE: fix sticky positioning in Safari
width: '100%',
flexDirection: 'column',
...style,
}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
import * as React from 'react';
import * as PropTypes from 'prop-types';
import { ThemeColors } from './layout';
import { getStickyPosition } from '../utils/css-fallback-properties';

export class FixedCell extends React.PureComponent {
constructor(props) {
super(props);

this.state = {
stickyPosition: getStickyPosition(),
};
}

componentDidMount() {
this.setState({ stickyPosition: getStickyPosition() });
}

render() {
const {
component: CellPlaceholder,
Expand All @@ -14,12 +27,13 @@ export class FixedCell extends React.PureComponent {
...restProps
} = this.props;
const { backgroundColor, borderColor } = this.context;
const { stickyPosition } = this.state;

return (
<CellPlaceholder
style={{
...style,
position: 'sticky',
position: stickyPosition,
backgroundClip: 'padding-box',
zIndex: 300,
backgroundColor,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,61 @@
import * as React from 'react';
import * as PropTypes from 'prop-types';
import { getStickyPosition } from '../utils/css-fallback-properties';

export const TableNoDataCell = ({
style,
colSpan,
getMessage,
tableRow,
tableColumn,
...restProps
}) => (
<td
style={{
padding: '50px 0',
...style,
}}
colSpan={colSpan}
{...restProps}
>
<div
style={{
display: 'inline-block',
position: 'sticky',
left: '50%',
}}
>
<big
className="text-muted"
export class TableNoDataCell extends React.PureComponent {
constructor(props) {
super(props);

this.state = {
stickyPosition: getStickyPosition(),
};
}

componentDidMount() {
this.setState({ stickyPosition: getStickyPosition() });
}

render() {
const {
style,
colSpan,
getMessage,
tableRow,
tableColumn,
...restProps
} = this.props;
const { stickyPosition } = this.state;

return (
<td
style={{
display: 'inline-block',
transform: 'translateX(-50%)',
padding: '50px 0',
...style,
}}
colSpan={colSpan}
{...restProps}
>
{getMessage('noData')}
</big>
</div>
</td>
);
<div
style={{
display: 'inline-block',
position: stickyPosition,
left: '50%',
}}
>
<big
className="text-muted"
style={{
display: 'inline-block',
transform: 'translateX(-50%)',
}}
>
{getMessage('noData')}
</big>
</div>
</td>
);
}
}

TableNoDataCell.propTypes = {
style: PropTypes.object,
Expand Down
30 changes: 8 additions & 22 deletions packages/dx-react-grid-bootstrap3/src/templates/table.jsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,16 @@
/* globals document:true */
import * as React from 'react';
import * as PropTypes from 'prop-types';
import classNames from 'classnames';
import { RefType } from '@devexpress/dx-react-core';
import { ThemeColors } from './layout';

let globalStickyProp;
const testCSSProp = (property, value, noPrefixes) => {
const prop = `${property}:`;
const el = document.createElement('test');
const mStyle = el.style;

if (!noPrefixes) {
mStyle.cssText = `${prop + ['-webkit-', '-moz-', '-ms-', '-o-', ''].join(`${value};${prop}`) + value};`;
} else {
mStyle.cssText = prop + value;
}
return mStyle[property];
};
import { getStickyPosition } from '../utils/css-fallback-properties';

export class Table extends React.Component {
constructor() {
super();

this.state = {
stickyProp: globalStickyProp,
stickyPosition: getStickyPosition(),
};
this.tableRef = React.createRef();
}
Expand All @@ -34,19 +20,19 @@ export class Table extends React.Component {
}

checkStyles() {
globalStickyProp = testCSSProp('position', 'sticky');
const { stickyProp } = this.state;
const { stickyPosition } = this.state;
const realStickyPosition = getStickyPosition();

if (stickyProp !== globalStickyProp) {
this.setState({ stickyProp: globalStickyProp });
if (stickyPosition !== realStickyPosition) {
this.setState({ stickyPosition: realStickyPosition });
}
}

render() {
const {
children, use, style, className, tableRef, ...restProps
} = this.props;
const { stickyProp } = this.state;
const { stickyPosition } = this.state;
const { backgroundColor } = this.context;
return (
<table
Expand All @@ -60,7 +46,7 @@ export class Table extends React.Component {
borderCollapse: 'separate',
marginBottom: 0,
...use ? {
position: stickyProp,
position: stickyPosition,
zIndex: 500,
background: backgroundColor,
} : null,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* globals document:true */

const cache = {};
let sandboxElement = null;

const getBrowserStyles = () => {
sandboxElement = sandboxElement || document.createElement('test');

return sandboxElement.style;
};

const findOutValidPropertyValue = (property, value) => {
const prop = `${property}:`;
const style = getBrowserStyles();

style.cssText = `${prop + ['-webkit-', '-moz-', '-ms-', '-o-', ''].join(`${value};${prop}`) + value};`;

return style[property];
};

const getValidPropertyValue = (property, value) => {
const isServerRender = typeof document === 'undefined';

if (isServerRender) {
return undefined;
}

if (!(value in cache)) {
cache[value] = findOutValidPropertyValue(property, value);
}

return cache[value];
};

export const getStickyPosition = () => getValidPropertyValue('position', 'sticky');
1 change: 1 addition & 0 deletions packages/dx-styles/dx-grid-bs4.css
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ button.dx-g-bs4-table-edit-command-cell {
}
.dx-g-bs4-fixed-block {
display: inline-block;
position: -webkit-sticky;
position: sticky;
left: 50%;
}
Expand Down

0 comments on commit c135acc

Please sign in to comment.