Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-virtualized

Package Overview
Dependencies
Maintainers
1
Versions
296
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-virtualized - npm Package Compare versions

Comparing version 2.8.0 to 3.0.0

9

CHANGELOG.md
Changelog
------------
## 3.0.0
CSS styles have been split into two groups: functional styles (eg. `position`, `overflow`) and presentational styles (eg. `text-transform`, `color`) and both have been converted to inline styles rather than being loaded as CSS. This was done primarily to simplify usage for universal/isomorphic rendering.
For more information on customizing styles refer to the [documentation](https://github.com/bvaughn/react-virtualized/#customizing-styles)...
#### 2.8.0

@@ -53,3 +58,3 @@ Changed `Autosizer` component to support a single child instead of the `ChildComponent` property.

#### 2.0.0
## 2.0.0
Set `shouldPureComponentUpdate` on component prototypes instead of instances.

@@ -70,3 +75,3 @@ Dropped half-ass support for React 0.13. This module has always depended on React 0.14 but it was checking in previous versions and trying to be backwards compatible with 0.13. Since that check is no longer in place, this is a major version bump (even though there is no real new functionality being added).

#### 1.0.0
## 1.0.0
Package JSON updated so that "main" entry points to `dist/react-virtualized.js` to provide easier integration for users that don't want Babel/Webpack to have to process their `node_modules` folder.

@@ -73,0 +78,0 @@

@@ -9,2 +9,13 @@ AutoSizer

|:---|:---|:---:|:---|
| ChildComponent| ReactComponent | ✓ | React component (class or function) to be created and managed. |
| children | element | ✓ | Element to be parameterized with `width` and `height` properties |
| ChildComponent| ReactComponent | | React component (class or function) to be created and managed. This property has been deprecated in favor of `children`. |
| className | string | | Optional CSS class name. |
| styleSheet | object | | Presentational styles for component. |
### Stylesheet properties
The AutoSizer component supports the following nested styles in its `styleSheet` property:
| Property | Description |
|:---|:---|:---:|:---|
| AutoSizer | Main (outer) element |

@@ -27,2 +27,3 @@ FlexTable

| sortDirection | [SortDirection](SortDirection.md) | | Data is currently sorted in this direction (if it is sorted at all) |
| styleSheet | object | | Presentational styles for component. |
| width | Number | ✓ | Fixed/available width for out DOM element |

@@ -41,1 +42,17 @@ | verticalPadding | Number | | Vertical padding of outer DOM element |

Scroll the list to ensure the row at the specified index is visible. This method exists so that a user can forcefully scroll to the same row twice. (The `scrollToIndex` property would not change in that case and so it would not be picked up by VirtualScroll.)
### Stylesheet properties
The FlexTable component supports the following nested styles in its `styleSheet` property:
| Property | Description |
|:---|:---|:---:|:---|
| FlexTable | Main (outer) element |
| headerColumn | Header cell (similar to `thead > tr > th`) |
| headerRow | Header row (similar to `thead > tr`) |
| headerTruncatedText | Element within header cell responsible for truncating text |
| row | Table row (akin to `tbody > tr`) |
| rowColumn | Table column (akin to `tbody > tr > td`) |
| sortableHeaderColumn | Applied to header columns that are sortable |
| sortableHeaderIcon | SVG sort indicator |
| truncatedColumnText | Element within table column responsible for truncating text |

@@ -17,2 +17,3 @@ VirtualScroll

| scrollToIndex | Number | | Row index to ensure visible (by forcefully scrolling if necessary) |
| styleSheet | object | | Presentational styles for component. |

@@ -29,1 +30,9 @@ ### Public Methods

Scroll the list to ensure the row at the specified index is visible. This method exists so that a user can forcefully scroll to the same row twice. (The `scrollToIndex` property would not change in that case and so it would not be picked up by VirtualScroll.)
### Stylesheet properties
The VirtualScroll component supports the following nested styles in its `styleSheet` property:
| Property | Description |
|:---|:---|:---:|:---|
| VirtualScroll | Main (outer) element |

@@ -6,3 +6,3 @@ {

"user": "bvaughn",
"version": "2.8.0",
"version": "3.0.0",
"scripts": {

@@ -109,3 +109,4 @@ "build": "npm run build:demo && npm run build:dist",

"dependencies": {
"classnames": "^2.2.1",
"classnames": "^2.2.3",
"inline-style-prefixer": "^0.6.2",
"raf": "^3.1.0",

@@ -112,0 +113,0 @@ "react-pure-render": "^1.0.2"

@@ -25,2 +25,28 @@ <img src="https://cloud.githubusercontent.com/assets/29597/11737732/0ca1e55e-9f91-11e5-97f3-098f2f8ed866.png" alt="React virtualized" data-canonical-src="https://cloud.githubusercontent.com/assets/29597/11737732/0ca1e55e-9f91-11e5-97f3-098f2f8ed866.png" width="330" height="100" />

### Customizing Styles
React virtual CSS styles are split into two groups: functional styles (eg. `position`, `overflow`) and presentational styles (eg. `text-transform`, `color`). Both are defined as inline styles (rather than external CSS) to simplify usage for universal/isomorphic rendering.
Functional styles cannot be overridden but you can override presentational styles in a variety of ways:
###### Styling a single component
Supply a custom `styleSheet` to a component (eg. `<VirtualScroll styleSheet={...}/>`) to override default styles for a single component instance. Styles injected as properties will be automatically processed to add vendor prefixes.
Learn more about which styles a component supports in the [API docs](https://github.com/bvaughn/react-virtualized/blob/master/docs/).
###### Styling all instances
Override the static `defaultStyleSheet` property of a component class (eg. `FlexTable.defaultStyleSheet = {...}` to customize styles for all instances.
###### Global CSS
Load an external CSS file that defines global classes (eg. `FlexTable`, `FlexTable__row`) to append to default inline styles.
Learn more about which class names a component supports in the [API docs](https://github.com/bvaughn/react-virtualized/blob/master/docs/).
###### CSS Modules
If you are using CSS modules you can specify custom class names to be appended to a component instance (eg. `FlexTable` supports `className`, `headerClassName`, and `rowClassName` properties).
Learn more about which class names are supported in the [API docs](https://github.com/bvaughn/react-virtualized/blob/master/docs/).
Examples

@@ -27,0 +53,0 @@ ---------------

/** @flow */
import cn from 'classnames'
import React, { Component, PropTypes } from 'react'
import shouldPureComponentUpdate from 'react-pure-render/function'
import styles from './AutoSizer.css'
import { prefixStyleSheet } from '../utils'

@@ -19,3 +20,2 @@ /**

children: PropTypes.element,
/**

@@ -27,3 +27,7 @@ * React component to manage as a child.

*/
ChildComponent: PropTypes.any
ChildComponent: PropTypes.any,
/** Optional CSS class name */
className: PropTypes.string,
/** Specifies presentational styles for component. */
styleSheet: PropTypes.object
}

@@ -36,2 +40,3 @@

height: 0,
styleSheet: prefixStyleSheet(props.styleSheet || AutoSizer.defaultStyleSheet),
width: 0

@@ -57,5 +62,13 @@ }

componentWillUpdate (nextProps, nextState) {
if (this.props.styleSheet !== nextProps.styleSheet) {
this.setState({
styleSheet: prefixStyleSheet(nextProps.styleSheet)
})
}
}
render () {
const { children, ChildComponent, ...props } = this.props
const { height, width } = this.state
const { children, ChildComponent, className, ...props } = this.props
const { height, styleSheet, width } = this.state

@@ -80,3 +93,7 @@ let child

ref={this._setRef}
className={styles.Wrapper}
className={cn('AutoSizer', className)}
style={{
...styleSheet.AutoSizer,
...functionalStyles.AutoSizer
}}
>

@@ -101,1 +118,14 @@ {child}

}
const functionalStyles = {
AutoSizer: {
width: '100%',
height: '100%'
}
}
/** Default presentational styles for all <AutoSizer> instances. */
AutoSizer.defaultStyleSheet = {
AutoSizer: {
}
}

@@ -15,3 +15,3 @@ import React from 'react'

// Used by the renderOrUpdateList() helper method
// Used by the renderOrUpdateComponent() helper method
// Unless we attach the node to body, getBoundingClientRect() won't work

@@ -31,4 +31,6 @@ var node = null

bar = 123,
className = undefined,
foo = 456,
height = 100,
styleSheet = undefined,
width = 200

@@ -41,3 +43,6 @@ } = {}

autoSizer = (
<AutoSizer>
<AutoSizer
className={className}
styleSheet={styleSheet}
>
<ChildComponent

@@ -54,3 +59,5 @@ bar={bar}

bar={bar}
className={className}
foo={foo}
styleSheet={styleSheet}
/>

@@ -67,4 +74,4 @@ )

function renderOrUpdateList (useReactChild, props) {
let rendered = render(getMarkup(props), node)
function renderOrUpdateComponent (useReactChild, props) {
let rendered = render(getMarkup(useReactChild, props), node)

@@ -76,3 +83,3 @@ return findDOMNode(rendered)

[false, true].forEach(useReactChild => {
const component = renderOrUpdateList(useReactChild)
const component = renderOrUpdateComponent(useReactChild)
expect(findDOMNode(component).textContent).toContain('foo:456')

@@ -85,3 +92,3 @@ expect(findDOMNode(component).textContent).toContain('bar:123')

[false, true].forEach(useReactChild => {
const component = renderOrUpdateList(useReactChild)
const component = renderOrUpdateComponent(useReactChild)
let domNode = findDOMNode(component)

@@ -93,3 +100,32 @@ expect(domNode.textContent).toContain('height:100')

describe('styles and classeNames', () => {
it('should use the expected global CSS classNames', () => {
const node = renderOrUpdateComponent()
expect(node.querySelector('.AutoSizer')).toBeTruthy()
})
it('should use a custom :className if specified', () => {
const node = renderOrUpdateComponent(true, { className: 'foo' })
expect(node.querySelector('.AutoSizer').className).toContain('foo')
})
it('should use custom :styleSheet if specified', () => {
const node = renderOrUpdateComponent(true, {
styleSheet: {
AutoSizer: { color: 'red' }
}
})
expect(node.querySelector('.AutoSizer').style.color).toEqual('red')
})
it('should use overriden static styles', () => {
const backup = { ...AutoSizer.defaultStyleSheet }
AutoSizer.defaultStyleSheet.AutoSizer = { color: 'blue' }
const node = renderOrUpdateComponent()
expect(node.querySelector('.AutoSizer').style.color).toEqual('blue')
AutoSizer.defaultStyleSheet = backup
})
})
// TODO It would be nice to test that resize events update the width/height
})

@@ -117,2 +117,3 @@ /** @flow */

width={430}
headerClassName={styles.headerColumn}
headerHeight={headerHeight}

@@ -119,0 +120,0 @@ height={height}

/** @flow */
import cn from 'classnames'
import FlexColumn from './FlexColumn'
import React, { Component, PropTypes } from 'react'
import cn from 'classnames'
import shouldPureComponentUpdate from 'react-pure-render/function'
import VirtualScroll from '../VirtualScroll'
import FlexColumn from './FlexColumn'
import styles from './FlexTable.css'
import { prefixStyle, prefixStyleSheet } from '../utils'

@@ -30,11 +30,2 @@ export const SortDirection = {

static defaultProps = {
disableHeader: false,
horizontalPadding: 0,
noRowsRenderer: () => null,
onRowClick: () => null,
onRowsRendered: () => null,
verticalPadding: 0
}
static propTypes = {

@@ -98,2 +89,4 @@ /** One or more FlexColumns describing the data displayed in this row */

sortDirection: PropTypes.oneOf([SortDirection.ASC, SortDirection.DESC]),
/** Specifies presentational styles for component. */
styleSheet: PropTypes.object,
/** Fixed/available width for out DOM element */

@@ -105,2 +98,11 @@ width: PropTypes.number.isRequired,

static defaultProps = {
disableHeader: false,
horizontalPadding: 0,
noRowsRenderer: () => null,
onRowClick: () => null,
onRowsRendered: () => null,
verticalPadding: 0
}
constructor (props) {

@@ -110,2 +112,6 @@ super(props)

this._createRow = this._createRow.bind(this)
this.state = {
styleSheet: prefixStyleSheet(props.styleSheet || FlexTable.defaultStyleSheet)
}
}

@@ -127,2 +133,10 @@

componentWillUpdate (nextProps, nextState) {
if (this.props.styleSheet !== nextProps.styleSheet) {
this.setState({
styleSheet: prefixStyleSheet(nextProps.styleSheet)
})
}
}
render () {

@@ -143,2 +157,4 @@ const {

const { styleSheet } = this.state
const availableRowsHeight = height - headerHeight - verticalPadding

@@ -151,2 +167,3 @@

}
const rowClass = rowClassName instanceof Function ? rowClassName(-1) : rowClassName

@@ -156,4 +173,6 @@

<div
className={cn(styles.FlexTable, className)}
className={cn('FlexTable', className)}
style={{
...styleSheet.FlexTable,
...functionalStyles.FlexTable,
maxWidth: width

@@ -164,4 +183,6 @@ }}

<div
className={cn(styles.headerRow, rowClass)}
className={cn('FlexTable__headerRow', rowClass)}
style={{
...styleSheet.headerRow,
...functionalStyles.headerRow,
height: headerHeight

@@ -196,2 +217,3 @@ }}

} = column.props
const { styleSheet } = this.state
const cellData = cellDataGetter(dataKey, rowData, columnData)

@@ -201,7 +223,2 @@ const renderedCell = cellRenderer(cellData, dataKey, rowData, rowIndex, columnData)

const flex = this._getFlexStyleForColumn(column)
const style = {
WebkitFlex: flex,
msFlex: flex,
flex: flex
}

@@ -215,7 +232,12 @@ const title = typeof renderedCell === 'string'

key={`Row${rowIndex}-Col${columnIndex}`}
className={styles.rowColumn}
style={style}
className={cn('FlexTable__rowColumn', cellClassName)}
style={{
...styleSheet.rowColumn,
...functionalStyles.rowColumn,
...prefixStyle({ flex })
}}
>
<div
className={cn(styles.truncatedColumnText, cellClassName)}
className='FlexTable__truncatedColumnText'
style={styleSheet.truncatedColumnText}
title={title}

@@ -230,3 +252,4 @@ >

_createHeader (column, columnIndex) {
const { sort, sortBy, sortDirection } = this.props
const { headerClassName, sort, sortBy, sortDirection } = this.props
const { styleSheet } = this.state
const { dataKey, disableSort, label } = column.props

@@ -236,12 +259,15 @@ const showSortIndicator = sortBy === dataKey

const classNames = cn(styles.headerColumn,
this.props.headerClassName,
const sortableStyles = sortEnabled
? styleSheet.sortableHeaderColumn
: {}
const classNames = cn(
'FlexTable__headerColumn',
headerClassName,
column.props.headerClassName,
{
[styles.sortableHeaderColumn]: sortEnabled
'FlexTable__sortableHeaderColumn': sortEnabled
}
)
const style = {
flex: this._getFlexStyleForColumn(column)
}
const flex = this._getFlexStyleForColumn(column)

@@ -258,7 +284,13 @@ // If this is a sortable header, clicking it should update the table data's sorting.

className={classNames}
style={style}
style={{
...styleSheet.headerColumn,
...functionalStyles.headerColumn,
...sortableStyles,
...prefixStyle({ flex })
}}
onClick={onClick}
>
<div
className={styles.headerTruncatedText}
className='FlexTable__headerTruncatedText'
style={styleSheet.headerTruncatedText}
title={label}

@@ -269,3 +301,6 @@ >

{showSortIndicator &&
<SortIndicator sortDirection={sortDirection} />
<SortIndicator
sortDirection={sortDirection}
styleSheet={styleSheet}
/>
}

@@ -284,4 +319,6 @@ </div>

} = this.props
const { styleSheet } = this.state
const rowClass = rowClassName instanceof Function ? rowClassName(rowIndex) : rowClassName
const renderedRow = React.Children.map(

@@ -300,5 +337,7 @@ children,

key={rowIndex}
className={cn(styles.row, rowClass)}
className={cn('FlexTable__row', rowClass)}
onClick={() => onRowClick(rowIndex)}
style={{
...styleSheet.row,
...functionalStyles.row,
height: rowHeight

@@ -340,19 +379,22 @@ }}

*/
export function SortIndicator ({ sortDirection }) {
export function SortIndicator ({ sortDirection, styleSheet }) {
const classNames = cn('FlexTable__sortableHeaderIcon', {
'FlexTable__sortableHeaderIcon--ASC': sortDirection === SortDirection.ASC,
'FlexTable__sortableHeaderIcon--DESC': sortDirection === SortDirection.DESC
})
return (
<div data-sort-direction={sortDirection}>
<svg
className={styles.sortableHeaderIcon}
width={18}
height={18}
viewBox='0 0 24 24'
xmlns='http://www.w3.org/2000/svg'
>
{sortDirection === SortDirection.ASC
? <path d='M7 14l5-5 5 5z'/>
: <path d='M7 10l5 5 5-5z'/>
}
<path d='M0 0h24v24H0z' fill='none'/>
</svg>
</div>
<svg
className={classNames}
style={styleSheet.sortableHeaderIcon}
width={18}
height={18}
viewBox='0 0 24 24'
xmlns='http://www.w3.org/2000/svg'
>
{sortDirection === SortDirection.ASC
? <path d='M7 14l5-5 5 5z'/>
: <path d='M7 10l5 5 5-5z'/>
}
<path d='M0 0h24v24H0z' fill='none'/>
</svg>
)

@@ -363,1 +405,74 @@ }

}
/** Functional styles can't be overridden so they only need to be prefixed once. */
const functionalStyles = prefixStyleSheet({
FlexTable: {
width: '100%'
},
headerColumn: {
display: 'flex',
flexDirection: 'row',
overflow: 'hidden'
},
headerRow: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
overflow: 'hidden'
},
row: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
overflow: 'hidden'
},
rowColumn: {
display: 'flex',
overflow: 'hidden',
height: '100%'
}
})
/** Default presentational styles for all <FlexTable> instances. */
FlexTable.defaultStyleSheet = {
FlexTable: {
},
headerColumn: {
marginRight: 10,
minWidth: 0,
alignItems: 'center'
},
headerRow: {
fontWeight: 700,
textTransform: 'uppercase',
paddingLeft: 10
},
headerTruncatedText: {
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
overflow: 'hidden'
},
row: {
paddingLeft: 10
},
rowColumn: {
marginRight: 10,
minWidth: 0,
justifyContent: 'center',
flexDirection: 'column'
},
sortableHeaderColumn: {
cursor: 'pointer'
},
sortableHeaderIcon: {
flex: '0 0 24',
height: '1em',
width: '1em',
fill: 'currentColor'
},
truncatedColumnText: {
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
overflow: 'hidden'
}
}

@@ -8,16 +8,3 @@ import React from 'react'

import FlexTable, { SortDirection } from './FlexTable'
import styles from './FlexTable.css'
// Helper functions to convert className style selectors to css-module friendly selector.
function findAll (element, expression) {
var parts = expression.replace('.', '').split(':')
var className = styles[parts.shift()]
var modifier = parts.length ? `:${parts.shift()}` : ''
return element.querySelectorAll(`.${className}${modifier}`)
}
function find (element, expression) {
const matches = findAll(element, expression)
return matches.length ? matches[0] : null
}
describe('FlexTable', () => {

@@ -56,3 +43,5 @@ beforeAll(() => jasmine.clock().install())

cellDataGetter = undefined,
className = undefined,
disableSort = false,
headerClassName = undefined,
headerHeight = 20,

@@ -63,6 +52,6 @@ height = 100,

onRowsRendered = undefined,
rowClassName = undefined,
rowGetter = immutableRowGetter,
rowHeight = 10,
rowsCount = list.size,
rowClassName = undefined,
scrollToIndex = undefined,

@@ -72,2 +61,3 @@ sort = undefined,

sortDirection = undefined,
styleSheet = undefined,
width = 100

@@ -77,3 +67,4 @@ } = {}) {

<FlexTable
width={width}
className={className}
headerClassName={headerClassName}
headerHeight={headerHeight}

@@ -84,9 +75,11 @@ height={height}

onRowsRendered={onRowsRendered}
rowClassName={rowClassName}
rowGetter={rowGetter}
rowHeight={rowHeight}
rowsCount={rowsCount}
rowClassName={rowClassName}
sort={sort}
sortBy={sortBy}
sortDirection={sortDirection}
styleSheet={styleSheet}
width={width}
>

@@ -147,4 +140,4 @@ <FlexColumn

// 100px height should fit 1 header (20px) and 8 rows (10px each) -
expect(findAll(tableDOMNode, '.headerRow').length).toEqual(1)
expect(findAll(tableDOMNode, '.row').length).toEqual(8)
expect(tableDOMNode.querySelectorAll('.FlexTable__headerRow').length).toEqual(1)
expect(tableDOMNode.querySelectorAll('.FlexTable__row').length).toEqual(8)
})

@@ -157,3 +150,3 @@

const tableDOMNode = findDOMNode(table)
const columns = findAll(tableDOMNode, '.headerColumn')
const columns = tableDOMNode.querySelectorAll('.FlexTable__headerColumn')

@@ -173,3 +166,3 @@ expect(columns.length).toEqual(2)

const tableDOMNode = findDOMNode(table)
const rows = findAll(tableDOMNode, '.row')
const rows = tableDOMNode.querySelectorAll('.FlexTable__row')
expect(rows.length).toEqual(2)

@@ -180,3 +173,3 @@

let rowData = list.get(index)
let columns = findAll(row, '.rowColumn')
let columns = row.querySelectorAll('.FlexTable__rowColumn')
expect(columns.length).toEqual(2)

@@ -196,3 +189,3 @@ expect(columns[0].textContent).toEqual(rowData.get('name'))

const tableDOMNode = findDOMNode(table)
const nameColumns = findAll(tableDOMNode, '.rowColumn:first-of-type')
const nameColumns = tableDOMNode.querySelectorAll('.FlexTable__rowColumn:first-of-type')

@@ -210,3 +203,3 @@ for (let index = 0; index < nameColumns.length; index++) {

const tableDOMNode = findDOMNode(table)
const nameColumns = findAll(tableDOMNode, '.rowColumn:first-of-type')
const nameColumns = tableDOMNode.querySelectorAll('.FlexTable__rowColumn:first-of-type')

@@ -225,3 +218,3 @@ for (let index = 0; index < nameColumns.length; index++) {

const tableDOMNode = findDOMNode(table)
const nameColumn = find(tableDOMNode, '.rowColumn:first-of-type')
const nameColumn = tableDOMNode.querySelector('.FlexTable__rowColumn:first-of-type')
expect(nameColumn.children[0].getAttribute('title')).toContain('Custom')

@@ -235,3 +228,3 @@ })

const tableDOMNode = findDOMNode(table)
const nameColumn = find(tableDOMNode, '.rowColumn:first-of-type')
const nameColumn = tableDOMNode.querySelector('.FlexTable__rowColumn:first-of-type')
expect(nameColumn.children[0].getAttribute('title')).toEqual(null)

@@ -245,5 +238,5 @@ })

const tableDOMNode = findDOMNode(table)
const nameColumn = findAll(tableDOMNode, '.headerColumn:first-of-type')
const nameColumn = tableDOMNode.querySelectorAll('.FlexTable__headerColumn:first-of-type')
expect(nameColumn.className).not.toContain(styles.sortableHeaderColumn)
expect(nameColumn.className).not.toContain('FlexTable__sortableHeaderColumn')
})

@@ -257,6 +250,6 @@

const tableDOMNode = findDOMNode(table)
const nameColumn = findAll(tableDOMNode, '.headerColumn:first-of-type')
const nameColumn = tableDOMNode.querySelectorAll('.FlexTable__headerColumn:first-of-type')
expect(nameColumn.className).not.toContain(styles.sortableHeaderColumn)
expect(findAll(tableDOMNode, '.sortableHeaderColumn').length).toEqual(1) // Email only
expect(nameColumn.className).not.toContain('FlexTable__sortableHeaderColumn')
expect(tableDOMNode.querySelectorAll('.FlexTable__sortableHeaderColumn').length).toEqual(1) // Email only
})

@@ -269,6 +262,6 @@

const tableDOMNode = findDOMNode(table)
const nameColumn = find(tableDOMNode, '.headerColumn:first-of-type')
const nameColumn = tableDOMNode.querySelector('.FlexTable__headerColumn:first-of-type')
expect(nameColumn.className).toContain(styles.sortableHeaderColumn)
expect(findAll(tableDOMNode, '.sortableHeaderColumn').length).toEqual(2) // Email and Name
expect(nameColumn.className).toContain('FlexTable__sortableHeaderColumn')
expect(tableDOMNode.querySelectorAll('.FlexTable__sortableHeaderColumn').length).toEqual(2) // Email and Name
})

@@ -285,6 +278,6 @@

const tableDOMNode = findDOMNode(table)
const nameColumn = find(tableDOMNode, '.headerColumn:first-of-type')
const nameColumn = tableDOMNode.querySelector('.FlexTable__headerColumn:first-of-type')
expect(find(nameColumn, '.sortableHeaderIcon')).not.toEqual(null)
expect(nameColumn.querySelector(`[data-sort-direction=${sortDirection}]`)).not.toEqual(null)
expect(nameColumn.querySelector('.FlexTable__sortableHeaderIcon')).not.toEqual(null)
expect(nameColumn.querySelector(`.FlexTable__sortableHeaderIcon--${sortDirection}`)).not.toEqual(null)
})

@@ -303,3 +296,3 @@ })

const tableDOMNode = findDOMNode(table)
const nameColumn = find(tableDOMNode, '.headerColumn:first-of-type')
const nameColumn = tableDOMNode.querySelector('.FlexTable__headerColumn:first-of-type')

@@ -324,3 +317,3 @@ Simulate.click(nameColumn)

const tableDOMNode = findDOMNode(table)
const nameColumn = find(tableDOMNode, '.headerColumn:first-of-type')
const nameColumn = tableDOMNode.querySelector('.FlexTable__headerColumn:first-of-type')

@@ -362,3 +355,3 @@ Simulate.click(nameColumn)

const tableDOMNode = findDOMNode(table)
const rows = findAll(tableDOMNode, '.row')
const rows = tableDOMNode.querySelectorAll('.FlexTable__row')
Simulate.click(rows[0])

@@ -376,3 +369,3 @@ Simulate.click(rows[3])

const tableDOMNode = findDOMNode(table)
const rows = findAll(tableDOMNode, '.row')
const rows = tableDOMNode.querySelectorAll('.FlexTable__row')
for (let index = 0; index < rows.length; index++) {

@@ -389,3 +382,3 @@ let row = rows[index]

const tableDOMNode = findDOMNode(table)
const rows = findAll(tableDOMNode, '.row')
const rows = tableDOMNode.querySelectorAll('.FlexTable__row')
for (let index = 0; index < rows.length; index++) {

@@ -465,2 +458,53 @@ let row = rows[index]

})
describe('styles and classeNames', () => {
it('should use the expected global CSS classNames', () => {
const node = findDOMNode(renderTable({
sort: () => {},
sortBy: 'name',
sortDirection: SortDirection.ASC
}))
expect(node.className).toEqual('FlexTable')
expect(node.querySelector('.FlexTable__headerRow')).toBeTruthy()
expect(node.querySelector('.FlexTable__rowColumn')).toBeTruthy()
expect(node.querySelector('.FlexTable__truncatedColumnText')).toBeTruthy()
expect(node.querySelector('.FlexTable__headerColumn')).toBeTruthy()
expect(node.querySelector('.FlexTable__headerTruncatedText')).toBeTruthy()
expect(node.querySelector('.FlexTable__row')).toBeTruthy()
expect(node.querySelector('.FlexTable__sortableHeaderColumn')).toBeTruthy()
expect(node.querySelector('.FlexTable__sortableHeaderIcon')).toBeTruthy()
})
it('should use a custom :className if specified', () => {
const node = findDOMNode(renderTable({
className: 'foo',
headerClassName: 'bar',
rowClassName: 'baz'
}))
expect(node.className).toContain('foo')
expect(node.querySelectorAll('.bar').length).toEqual(2)
expect(node.querySelectorAll('.baz').length).toEqual(9)
})
it('should use custom :styleSheet if specified', () => {
const node = findDOMNode(renderTable({
styleSheet: {
headerColumn: { color: 'red' },
rowColumn: { color: 'green' }
}
}))
expect(node.querySelector('.FlexTable__headerColumn').style.color).toEqual('red')
expect(node.querySelector('.FlexTable__rowColumn').style.color).toEqual('green')
})
it('should use overriden static styles', () => {
const backup = { ...FlexTable.defaultStyleSheet }
FlexTable.defaultStyleSheet.headerColumn = { color: 'blue' }
FlexTable.defaultStyleSheet.rowColumn = { color: 'purple' }
const node = findDOMNode(renderTable())
expect(node.querySelector('.FlexTable__headerColumn').style.color).toEqual('blue')
expect(node.querySelector('.FlexTable__rowColumn').style.color).toEqual('purple')
FlexTable.defaultStyleSheet = backup
})
})
})

@@ -0,1 +1,5 @@

import Prefixer from 'inline-style-prefixer'
const prefixer = new Prefixer()
/**

@@ -173,1 +177,19 @@ * Binary search function inspired by react-infinite.

}
/**
* Adds vender prefixes to a style object.
*/
export function prefixStyle (style) {
return prefixer.prefix(style)
}
/**
* Adds vender prefixes for all of the styles in a stylesheet and returns a prefixed copy.
*/
export function prefixStyleSheet (styleSheet) {
const prefixedStyleSheet = {}
for (var style in styleSheet) {
prefixedStyleSheet[style] = prefixStyle(styleSheet[style])
}
return prefixedStyleSheet
}
/** @flow */
import shouldPureComponentUpdate from 'react-pure-render/function'
import React, { Component, PropTypes } from 'react'
import cn from 'classnames'
import raf from 'raf'
import {

@@ -10,6 +6,14 @@ getUpdatedOffsetForIndex,

initCellMetadata,
initOnRowsRenderedHelper
initOnRowsRenderedHelper,
prefixStyleSheet
} from '../utils'
import styles from './VirtualScroll.css'
import cn from 'classnames'
import raf from 'raf'
import React, { Component, PropTypes } from 'react'
import shouldPureComponentUpdate from 'react-pure-render/function'
/**
* Specifies the number of miliseconds during which to disable pointer events while a scroll is in progress.
* This improves performance and makes scrolling smoother.
*/
const IS_SCROLLING_TIMEOUT = 150

@@ -50,3 +54,5 @@

/** Row index to ensure visible (by forcefully scrolling if necessary) */
scrollToIndex: PropTypes.number
scrollToIndex: PropTypes.number,
/** Specifies presentational styles for component. */
styleSheet: PropTypes.object
}

@@ -65,2 +71,3 @@

isScrolling: false,
styleSheet: prefixStyleSheet(props.styleSheet || VirtualScroll.defaultStyleSheet),
scrollTop: 0

@@ -188,2 +195,8 @@ }

if (this.props.styleSheet !== nextProps.styleSheet) {
this.setState({
styleSheet: prefixStyleSheet(nextProps.styleSheet)
})
}
// Don't compare rowHeight if it's a function because inline functions would cause infinite loops.

@@ -227,3 +240,4 @@ // In that event users should use recomputeRowHeights() to inform of changes.

isScrolling,
scrollTop
scrollTop,
styleSheet
} = this.state

@@ -251,5 +265,8 @@

let datum = this._cellMetadata[i]
let child = React.cloneElement(
rowRenderer(i), {
let child = rowRenderer(i)
child = React.cloneElement(
child,
{
style: {
...child.props.style,
position: 'absolute',

@@ -270,3 +287,3 @@ top: datum.offset,

ref='scrollingContainer'
className={cn(styles.VirtualScroll, className)}
className={cn('VirtualScroll', className)}
onKeyDown={this._onKeyPress}

@@ -277,2 +294,4 @@ onScroll={this._onScroll}

style={{
...styleSheet.VirtualScroll,
...functionalStyles.VirtualScroll,
height: height

@@ -283,4 +302,4 @@ }}

<div
className={styles.InnerScrollContainer}
style={{
...functionalStyles.innerScrollContainer,
height: this._getTotalRowsHeight(),

@@ -486,1 +505,21 @@ maxHeight: this._getTotalRowsHeight(),

}
/** Functional styles can't be overridden so they only need to be prefixed once. */
const functionalStyles = prefixStyleSheet({
VirtualScroll: {
position: 'relative',
overflow: 'auto',
outline: 0
},
innerScrollContainer: {
boxSizing: 'border-box',
overflowX: 'auto',
overflowY: 'hidden'
}
})
/** Default presentational styles for all <VirtualScroll> instances. */
VirtualScroll.defaultStyleSheet = {
VirtualScroll: {
}
}

@@ -24,2 +24,3 @@ import React from 'react'

function getMarkup ({
className = undefined,
height = 100,

@@ -30,3 +31,4 @@ noRowsRenderer = undefined,

rowsCount = list.size,
scrollToIndex = undefined
scrollToIndex = undefined,
styleSheet = undefined
} = {}) {

@@ -46,2 +48,3 @@ function rowRenderer (index) {

<VirtualScroll
className={className}
height={height}

@@ -54,2 +57,3 @@ noRowsRenderer={noRowsRenderer}

scrollToIndex={scrollToIndex}
styleSheet={styleSheet}
/>

@@ -229,2 +233,31 @@ )

})
describe('styles and classeNames', () => {
it('should use the expected global CSS classNames', () => {
const node = findDOMNode(renderList())
expect(node.className).toEqual('VirtualScroll')
})
it('should use a custom :className if specified', () => {
const node = findDOMNode(renderList({ className: 'foo' }))
expect(node.className).toContain('foo')
})
it('should use custom :styleSheet if specified', () => {
const node = findDOMNode(renderList({
styleSheet: {
VirtualScroll: { color: 'red' }
}
}))
expect(node.style.color).toEqual('red')
})
it('should use overriden static styles', () => {
const backup = { ...VirtualScroll.defaultStyleSheet }
VirtualScroll.defaultStyleSheet.VirtualScroll = { color: 'blue' }
const node = findDOMNode(renderList())
expect(node.style.color).toEqual('blue')
VirtualScroll.defaultStyleSheet = backup
})
})
})

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc