├── site ├── ZyngaScroller.js ├── variables.less ├── images │ ├── favicon.png │ ├── arrowBullet.png │ ├── arrowBullet-2x.png │ ├── fdt_logo_transparent_ondark_23px.png │ ├── fdt_logo_transparent_onlight_50px.png │ ├── fdt_logo_transparent_onlight_80px.png │ ├── fdt_logo_transparent_ondark_23px-2x.png │ ├── fdt_logo_transparent_onlight_50px-2x.png │ └── fdt_logo_transparent_onlight_80px-2x.png ├── client.js ├── renderPath.js ├── StaticHTMLBlock.js ├── README.md ├── home │ ├── HomePage.js │ ├── HeroTable.js │ ├── Header.js │ └── homePageStyle.less ├── MiniHeader.js ├── examples │ ├── ExampleHeader.js │ ├── ExamplesWrapper.js │ ├── TouchableArea.js │ ├── TouchExampleWrapper.js │ └── ExamplesPage.js ├── miniHeader.less ├── SideBar.js ├── docs │ └── DocsPage.js ├── webpack-prerender.config.js ├── webpack-client.config.js ├── base.less ├── Constants.js └── IndexPage.js ├── main.js ├── .babelrc ├── .gitignore ├── .npmignore ├── .editorconfig ├── src ├── stubs │ ├── react │ │ ├── React.js │ │ ├── ReactDOM.js │ │ └── ReactComponentWithPureRenderMixin.js │ ├── Locale.js │ ├── cssVar.js │ ├── Object.assign.js │ └── invariant.js ├── css │ ├── style │ │ ├── fixedDataTableColumnResizerLine.css │ │ ├── fixedDataTableCell.css │ │ ├── fixedDataTableRow.css │ │ ├── Scrollbar.css │ │ └── fixedDataTable.css │ └── layout │ │ ├── fixedDataTableCellGroupLayout.css │ │ ├── fixedDataTableRowLayout.css │ │ ├── fixedDataTableColumnResizerLineLayout.css │ │ ├── fixedDataTableLayout.css │ │ ├── fixedDataTableCellLayout.css │ │ └── ScrollbarLayout.css ├── vendor_upstream │ ├── core │ │ ├── nativeRequestAnimationFrame.js │ │ ├── clamp.js │ │ ├── camelize.js │ │ ├── Keys.js │ │ ├── cancelAnimationFramePolyfill.js │ │ ├── joinClasses.js │ │ ├── emptyFunction.js │ │ ├── requestAnimationFramePolyfill.js │ │ ├── ExecutionEnvironment.js │ │ ├── shallowEqual.js │ │ ├── getVendorPrefixedName.js │ │ └── debounceCore.js │ ├── dom │ │ ├── BrowserSupportCore.js │ │ ├── translateDOMPositionXY.js │ │ ├── ReactWheelHandler.js │ │ └── DOMMouseMoveTracker.js │ ├── stubs │ │ ├── cx.js │ │ └── EventListener.js │ ├── react │ │ └── renderers │ │ │ └── dom │ │ │ └── client │ │ │ └── utils │ │ │ └── isEventSupported.js │ └── struct │ │ └── Heap.js ├── FixedDataTableRoot.js ├── transition │ ├── FixedDataTableColumn.react.js │ └── FixedDataTableColumnGroup.react.js ├── FixedDataTableColumnGroupNew.react.js ├── FixedDataTableCellDefault.react.js ├── FixedDataTableHelper.js ├── FixedDataTableWidthHelper.js ├── FixedDataTableRowBuffer.js ├── FixedDataTableColumnResizeHandle.react.js └── FixedDataTableCell.react.js ├── docs └── api-v0.5 │ ├── ColumnGroupAPI.md │ └── ColumnAPI.md ├── LICENSE ├── PATENTS ├── package.json ├── CONTRIBUTING.md ├── examples ├── helpers │ ├── FakeObjectDataListStore.js │ └── ExampleImage.js ├── old │ ├── ColumnGroupsExample.js │ ├── FlexGrowExample.js │ ├── ResizeExample.js │ ├── ObjectDataExample.js │ ├── FilterExample.js │ └── SortExample.js ├── ColumnGroupsExample.js ├── FlexGrowExample.js ├── ResizeExample.js ├── ObjectDataExample.js └── FilterExample.js ├── dist ├── fixed-data-table-style.min.css ├── fixed-data-table-base.min.css └── fixed-data-table-style.css ├── webpack.config.js └── README.md /site/ZyngaScroller.js: -------------------------------------------------------------------------------- 1 | module.exports = global.Scroller 2 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./internal/FixedDataTableRoot'); 2 | -------------------------------------------------------------------------------- /site/variables.less: -------------------------------------------------------------------------------- 1 | @link-color: #4183C4; 2 | @header-color: #212325; 3 | @body-color: #626466; -------------------------------------------------------------------------------- /site/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sandbox/fixed-data-table/HEAD/site/images/favicon.png -------------------------------------------------------------------------------- /site/images/arrowBullet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sandbox/fixed-data-table/HEAD/site/images/arrowBullet.png -------------------------------------------------------------------------------- /site/images/arrowBullet-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sandbox/fixed-data-table/HEAD/site/images/arrowBullet-2x.png -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "stage": 1, 3 | "plugins": ["./build_helpers/objectAssignTransformer.js"], 4 | "blacklist": ["validation.react"] 5 | } 6 | -------------------------------------------------------------------------------- /site/images/fdt_logo_transparent_ondark_23px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sandbox/fixed-data-table/HEAD/site/images/fdt_logo_transparent_ondark_23px.png -------------------------------------------------------------------------------- /site/images/fdt_logo_transparent_onlight_50px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sandbox/fixed-data-table/HEAD/site/images/fdt_logo_transparent_onlight_50px.png -------------------------------------------------------------------------------- /site/images/fdt_logo_transparent_onlight_80px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sandbox/fixed-data-table/HEAD/site/images/fdt_logo_transparent_onlight_80px.png -------------------------------------------------------------------------------- /site/images/fdt_logo_transparent_ondark_23px-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sandbox/fixed-data-table/HEAD/site/images/fdt_logo_transparent_ondark_23px-2x.png -------------------------------------------------------------------------------- /site/images/fdt_logo_transparent_onlight_50px-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sandbox/fixed-data-table/HEAD/site/images/fdt_logo_transparent_onlight_50px-2x.png -------------------------------------------------------------------------------- /site/images/fdt_logo_transparent_onlight_80px-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sandbox/fixed-data-table/HEAD/site/images/fdt_logo_transparent_onlight_80px-2x.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_STORE 2 | node_modules 3 | *~ 4 | *.log* 5 | chrome-user-data 6 | __build__ 7 | __site__ 8 | __site_prerender__ 9 | internal 10 | docs/api 11 | dist 12 | *.swp 13 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | build_helpers 2 | site 3 | src 4 | __site__ 5 | __site_prerender__ 6 | .editorconfig 7 | .babelrc 8 | webpack.config.js 9 | CONTRIBUTING.md 10 | dist/fixed-data-table-base.*js 11 | dist/fixed-data-table-style.*js 12 | -------------------------------------------------------------------------------- /site/client.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var React = require('react'); 4 | var ReactDOM = require('react-dom'); 5 | var IndexPage = require('./IndexPage'); 6 | 7 | ReactDOM.render( 8 | , 11 | document 12 | ); 13 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 2 7 | insert_final_newline = true 8 | indent_style = space 9 | max_line_length = 80 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | -------------------------------------------------------------------------------- /site/renderPath.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var React = require('react'); 4 | var IndexPage = require('./IndexPage'); 5 | 6 | function renderPath(path, props, onRender) { 7 | onRender( 8 | IndexPage.renderToString(props) 9 | ); 10 | } 11 | 12 | module.exports = renderPath; 13 | -------------------------------------------------------------------------------- /src/stubs/react/React.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule React 10 | */ 11 | 12 | module.exports = require('react'); 13 | -------------------------------------------------------------------------------- /src/stubs/react/ReactDOM.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule ReactDOM 10 | */ 11 | 12 | module.exports = require('react-dom'); 13 | -------------------------------------------------------------------------------- /site/StaticHTMLBlock.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var React = require('react'); 4 | 5 | var StaticHTMLBlock = React.createClass({ 6 | propTypes: { 7 | html: React.PropTypes.string.isRequired 8 | }, 9 | 10 | shouldComponentUpdate() { 11 | return false; 12 | }, 13 | 14 | render() { 15 | var {html, ...props} = this.props; 16 | return ( 17 |
21 | ); 22 | }, 23 | }); 24 | 25 | module.exports = StaticHTMLBlock; 26 | -------------------------------------------------------------------------------- /src/stubs/Locale.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule Locale 10 | */ 11 | 12 | "use strict"; 13 | 14 | // Hard code this for now. 15 | var Locale = { 16 | isRTL: () => false, 17 | getDirection: () => 'LTR' 18 | }; 19 | 20 | module.exports = Locale; 21 | -------------------------------------------------------------------------------- /src/css/style/fixedDataTableColumnResizerLine.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule fixedDataTableColumnResizerLine 10 | * 11 | */ 12 | 13 | /** 14 | * Column resizer line. 15 | */ 16 | .public/fixedDataTableColumnResizerLine/main { 17 | border-color: #0284ff; 18 | } 19 | -------------------------------------------------------------------------------- /site/README.md: -------------------------------------------------------------------------------- 1 | # Run the server 2 | 3 | The first time, get all the dependencies loaded via 4 | 5 | ``` 6 | npm install 7 | ``` 8 | 9 | Then, run the server via 10 | 11 | ``` 12 | npm run site-dev-server 13 | Open http://localhost:8080/ 14 | ``` 15 | 16 | Anytime you change the contents, just refresh the page and it's going to be updated. 17 | 18 | # Publish the website 19 | 20 | Just run the publish script, this will setup your environment if it's not already then it'll automatically build a static version of the site and publish it to gh-pages. 21 | 22 | ``` 23 | npm run site-publish 24 | ``` 25 | -------------------------------------------------------------------------------- /site/home/HomePage.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | require('./homePageStyle.less'); 4 | 5 | var Header = require('./Header'); 6 | var React = require('react'); 7 | var ReadMeHTML = require('../../README.md'); 8 | var StaticHTMLBlock = require('../StaticHTMLBlock'); 9 | 10 | var HomePage = React.createClass({ 11 | render() { 12 | return ( 13 |
14 |
15 | 16 |
17 |
18 | 19 |
20 |
21 |
22 | ); 23 | } 24 | }); 25 | 26 | module.exports = HomePage; 27 | -------------------------------------------------------------------------------- /src/vendor_upstream/core/nativeRequestAnimationFrame.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule nativeRequestAnimationFrame 10 | */ 11 | 12 | var nativeRequestAnimationFrame = 13 | global.requestAnimationFrame || 14 | global.webkitRequestAnimationFrame || 15 | global.mozRequestAnimationFrame || 16 | global.oRequestAnimationFrame || 17 | global.msRequestAnimationFrame; 18 | 19 | module.exports = nativeRequestAnimationFrame; 20 | -------------------------------------------------------------------------------- /src/css/style/fixedDataTableCell.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule fixedDataTableCell 10 | */ 11 | 12 | /** 13 | * Table cell. 14 | */ 15 | .public/fixedDataTableCell/main { 16 | background-color: var(fbui-white); 17 | border-color: #d3d3d3; 18 | } 19 | 20 | .public/fixedDataTableCell/highlighted { 21 | background-color: #f4f4f4; 22 | } 23 | 24 | .public/fixedDataTableCell/cellContent { 25 | padding: 8px; 26 | } 27 | 28 | .public/fixedDataTableCell/columnResizerKnob { 29 | background-color: #0284ff; 30 | } 31 | -------------------------------------------------------------------------------- /src/vendor_upstream/core/clamp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule clamp 10 | * @typechecks 11 | */ 12 | 13 | /** 14 | * Clamps (or clips or confines) the value to be between min and max. 15 | * @param {number} value 16 | * @param {number} min 17 | * @param {number} max 18 | * @return {number} 19 | */ 20 | function clamp(value, min, max) { 21 | if (value < min) { 22 | return min; 23 | } 24 | if (value > max) { 25 | return max; 26 | } 27 | return value; 28 | } 29 | 30 | module.exports = clamp; 31 | -------------------------------------------------------------------------------- /src/vendor_upstream/core/camelize.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule camelize 10 | * @typechecks 11 | */ 12 | 13 | var _hyphenPattern = /-(.)/g; 14 | 15 | /** 16 | * Camelcases a hyphenated string, for example: 17 | * 18 | * > camelize('background-color') 19 | * < "backgroundColor" 20 | * 21 | * @param {string} string 22 | * @return {string} 23 | */ 24 | function camelize(string) { 25 | return string.replace(_hyphenPattern, function(_, character) { 26 | return character.toUpperCase(); 27 | }); 28 | } 29 | 30 | module.exports = camelize; 31 | -------------------------------------------------------------------------------- /src/vendor_upstream/core/Keys.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule Keys 10 | */ 11 | 12 | module.exports = { 13 | BACKSPACE: 8, 14 | TAB: 9, 15 | RETURN: 13, 16 | ALT: 18, 17 | ESC: 27, 18 | SPACE: 32, 19 | PAGE_UP: 33, 20 | PAGE_DOWN: 34, 21 | END: 35, 22 | HOME: 36, 23 | LEFT: 37, 24 | UP: 38, 25 | RIGHT: 39, 26 | DOWN: 40, 27 | DELETE: 46, 28 | COMMA: 188, 29 | PERIOD: 190, 30 | A: 65, 31 | Z: 90, 32 | ZERO: 48, 33 | NUMPAD_0: 96, 34 | NUMPAD_9: 105 35 | }; 36 | -------------------------------------------------------------------------------- /src/css/layout/fixedDataTableCellGroupLayout.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule fixedDataTableCellGroupLayout 10 | */ 11 | 12 | .fixedDataTableCellGroupLayout/cellGroup { 13 | backface-visibility: hidden; 14 | left: 0; 15 | overflow: hidden; 16 | position: absolute; 17 | top: 0; 18 | white-space: nowrap; 19 | } 20 | 21 | .fixedDataTableCellGroupLayout/cellGroup > .public/fixedDataTableCell/main { 22 | display: inline-block; 23 | vertical-align: top; 24 | white-space: normal; 25 | } 26 | 27 | .fixedDataTableCellGroupLayout/cellGroupWrapper { 28 | position: absolute; 29 | top: 0; 30 | } 31 | -------------------------------------------------------------------------------- /src/vendor_upstream/core/cancelAnimationFramePolyfill.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule cancelAnimationFramePolyfill 10 | */ 11 | 12 | /** 13 | * Here is the native and polyfill version of cancelAnimationFrame. 14 | * Please don't use it directly and use cancelAnimationFrame module instead. 15 | */ 16 | var cancelAnimationFrame = 17 | global.cancelAnimationFrame || 18 | global.webkitCancelAnimationFrame || 19 | global.mozCancelAnimationFrame || 20 | global.oCancelAnimationFrame || 21 | global.msCancelAnimationFrame || 22 | global.clearTimeout; 23 | 24 | module.exports = cancelAnimationFrame; 25 | -------------------------------------------------------------------------------- /src/FixedDataTableRoot.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule FixedDataTableRoot 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var FixedDataTable = require('FixedDataTable.react'); 15 | var FixedDataTableCellDefault = require('FixedDataTableCellDefault.react'); 16 | var FixedDataTableColumn = require('FixedDataTableColumn.react'); 17 | var FixedDataTableColumnGroup = require('FixedDataTableColumnGroup.react'); 18 | 19 | var FixedDataTableRoot = { 20 | Cell: FixedDataTableCellDefault, 21 | Column: FixedDataTableColumn, 22 | ColumnGroup: FixedDataTableColumnGroup, 23 | Table: FixedDataTable, 24 | }; 25 | 26 | FixedDataTableRoot.version = '0.6.0'; 27 | module.exports = FixedDataTableRoot; 28 | -------------------------------------------------------------------------------- /src/css/style/fixedDataTableRow.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule fixedDataTableRow 10 | */ 11 | 12 | /** 13 | * Table row. 14 | */ 15 | .public/fixedDataTableRow/main { 16 | background-color: var(fbui-white); 17 | } 18 | 19 | .public/fixedDataTableRow/highlighted, 20 | .public/fixedDataTableRow/highlighted .public/fixedDataTableCell/main { 21 | background-color: var(fbui-desktop-background-light); 22 | } 23 | 24 | .public/fixedDataTableRow/fixedColumnsDivider { 25 | border-color: #d3d3d3; 26 | } 27 | 28 | .public/fixedDataTableRow/columnsShadow { 29 | background: 0 0 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABCAYAAAD5PA/NAAAAFklEQVQIHWPSkNeSBmJhTQVtbiDNCgASagIIuJX8OgAAAABJRU5ErkJggg==) repeat-y; 30 | } 31 | -------------------------------------------------------------------------------- /src/transition/FixedDataTableColumn.react.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule FixedDataTableColumn.react 10 | */ 11 | 12 | /** 13 | * TRANSITION SHIM 14 | * This acts to provide an intermediate mapping from the old API to the new API. 15 | * 16 | * When ready, remove this file and rename the providesModule in 17 | * FixedDataTableColumnNew.react 18 | */ 19 | 20 | var React = require('React'); 21 | 22 | var TransitionColumn = React.createClass({ 23 | statics: { 24 | __TableColumn__: true 25 | }, 26 | 27 | render() { 28 | if (__DEV__) { 29 | throw new Error( 30 | 'Component should never render' 31 | ); 32 | } 33 | return null; 34 | } 35 | }); 36 | 37 | module.exports = TransitionColumn; 38 | -------------------------------------------------------------------------------- /site/MiniHeader.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var React = require('react'); 4 | var Constants = require('./Constants'); 5 | 6 | require('./miniHeader.less'); 7 | 8 | var GITHUB_URL = 'https://github.com/facebook/fixed-data-table'; 9 | var DOCS_DEFAULT_LOCATION = Constants.DOCS_DEFAULT.location; 10 | var EXAMPLES_DEFAULT_LOCATION = Constants.EXAMPLES_DEFAULT.location; 11 | 12 | var MiniHeader = React.createClass({ 13 | render() { 14 | return ( 15 |
16 |
17 |
18 | 19 | 20 | Home 21 | 22 | Docs 23 | Examples 24 | Github 25 |
26 |
27 |
28 | ); 29 | } 30 | }); 31 | 32 | module.exports = MiniHeader; 33 | -------------------------------------------------------------------------------- /src/css/layout/fixedDataTableRowLayout.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule fixedDataTableRowLayout 10 | */ 11 | 12 | .fixedDataTableRowLayout/main { 13 | box-sizing: border-box; 14 | overflow: hidden; 15 | position: absolute; 16 | top: 0; 17 | } 18 | 19 | .fixedDataTableRowLayout/body { 20 | left: 0; 21 | position: absolute; 22 | top: 0; 23 | } 24 | 25 | .fixedDataTableRowLayout/fixedColumnsDivider { 26 | backface-visibility: hidden; 27 | border-left-style: solid; 28 | border-left-width: 1px; 29 | left: 0; 30 | position: absolute; 31 | top: 0; 32 | width: 0; 33 | } 34 | 35 | .fixedDataTableRowLayout/columnsShadow { 36 | width: 4px; 37 | } 38 | 39 | .fixedDataTableRowLayout/rowWrapper { 40 | position: absolute; 41 | top: 0; 42 | } 43 | -------------------------------------------------------------------------------- /src/transition/FixedDataTableColumnGroup.react.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule FixedDataTableColumnGroup.react 10 | */ 11 | 12 | /** 13 | * TRANSITION SHIM 14 | * This provides an intermediate mapping from the old API to the new API. 15 | * 16 | * When ready, remove this file and rename the providesModule in 17 | * FixedDataTableColumnNew.react 18 | */ 19 | 20 | var React = require('React'); 21 | 22 | var TransitionColumnGroup = React.createClass({ 23 | statics: { 24 | __TableColumnGroup__: true, 25 | }, 26 | 27 | render() { 28 | if (__DEV__) { 29 | throw new Error( 30 | 'Component should never render' 31 | ); 32 | } 33 | return null; 34 | } 35 | }); 36 | 37 | module.exports = TransitionColumnGroup; 38 | -------------------------------------------------------------------------------- /src/vendor_upstream/core/joinClasses.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule joinClasses 10 | * @typechecks static-only 11 | */ 12 | 13 | 'use strict'; 14 | 15 | /** 16 | * Combines multiple className strings into one. 17 | * http://jsperf.com/joinclasses-args-vs-array 18 | * 19 | * @param {...?string} className 20 | * @return {string} 21 | */ 22 | function joinClasses(className/*, ... */) { 23 | if (!className) { 24 | className = ''; 25 | } 26 | var nextClass; 27 | var argLength = arguments.length; 28 | if (argLength > 1) { 29 | for (var ii = 1; ii < argLength; ii++) { 30 | nextClass = arguments[ii]; 31 | if (nextClass) { 32 | className = (className ? className + ' ' : '') + nextClass; 33 | } 34 | } 35 | } 36 | return className; 37 | } 38 | 39 | module.exports = joinClasses; 40 | -------------------------------------------------------------------------------- /src/stubs/cssVar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule cssVar 10 | * @typechecks 11 | */ 12 | 13 | "use strict"; 14 | 15 | var CSS_VARS = { 16 | 'scrollbar-face-active-color': '#7d7d7d', 17 | 'scrollbar-face-color': '#c2c2c2', 18 | 'scrollbar-face-margin': '4px', 19 | 'scrollbar-face-radius': '6px', 20 | 'scrollbar-size': '15px', 21 | 'scrollbar-size-large': '17px', 22 | 'scrollbar-track-color': 'rgba(255, 255, 255, 0.8)', 23 | 'fbui-white': '#fff', 24 | 'fbui-desktop-background-light': '#f6f7f8', 25 | }; 26 | 27 | /** 28 | * @param {string} name 29 | */ 30 | function cssVar(name) { 31 | if (CSS_VARS.hasOwnProperty(name)) { 32 | return CSS_VARS[name]; 33 | } 34 | 35 | throw new Error( 36 | 'cssVar' + '("' + name + '"): Unexpected class transformation.' 37 | ); 38 | } 39 | 40 | cssVar.CSS_VARS = CSS_VARS; 41 | 42 | module.exports = cssVar; 43 | -------------------------------------------------------------------------------- /src/css/style/Scrollbar.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule Scrollbar 10 | * 11 | */ 12 | 13 | /** 14 | * Scrollbars. 15 | */ 16 | 17 | /* Touching the scroll-track directly makes the scroll-track bolder */ 18 | .public/Scrollbar/main.public/Scrollbar/mainActive, 19 | .public/Scrollbar/main:hover { 20 | background-color: var(scrollbar-track-color); 21 | } 22 | 23 | .public/Scrollbar/mainOpaque, 24 | .public/Scrollbar/mainOpaque.public/Scrollbar/mainActive, 25 | .public/Scrollbar/mainOpaque:hover { 26 | background-color: var(fbui-white); 27 | } 28 | 29 | .public/Scrollbar/face:after { 30 | background-color: var(scrollbar-face-color); 31 | } 32 | 33 | .public/Scrollbar/main:hover .public/Scrollbar/face:after, 34 | .public/Scrollbar/mainActive .public/Scrollbar/face:after, 35 | .public/Scrollbar/faceActive:after { 36 | background-color: var(scrollbar-face-active-color); 37 | } 38 | -------------------------------------------------------------------------------- /src/vendor_upstream/core/emptyFunction.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule emptyFunction 10 | */ 11 | 12 | function makeEmptyFunction(arg) { 13 | return function() { 14 | return arg; 15 | }; 16 | } 17 | 18 | /** 19 | * This function accepts and discards inputs; it has no side effects. This is 20 | * primarily useful idiomatically for overridable function endpoints which 21 | * always need to be callable, since JS lacks a null-call idiom ala Cocoa. 22 | */ 23 | function emptyFunction() {} 24 | 25 | emptyFunction.thatReturns = makeEmptyFunction; 26 | emptyFunction.thatReturnsFalse = makeEmptyFunction(false); 27 | emptyFunction.thatReturnsTrue = makeEmptyFunction(true); 28 | emptyFunction.thatReturnsNull = makeEmptyFunction(null); 29 | emptyFunction.thatReturnsThis = function() { return this; }; 30 | emptyFunction.thatReturnsArgument = function(arg) { return arg; }; 31 | 32 | module.exports = emptyFunction; 33 | -------------------------------------------------------------------------------- /src/css/layout/fixedDataTableColumnResizerLineLayout.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule fixedDataTableColumnResizerLineLayout 10 | */ 11 | 12 | .fixedDataTableColumnResizerLineLayout/mouseArea { 13 | cursor: ew-resize; 14 | position: absolute; 15 | right: -5px; 16 | width: 12px; 17 | } 18 | 19 | .fixedDataTableColumnResizerLineLayout/main { 20 | border-right-style: solid; 21 | border-right-width: 1px; 22 | box-sizing: border-box; 23 | position: absolute; 24 | z-index: 10; 25 | } 26 | 27 | body[dir="rtl"] .fixedDataTableColumnResizerLineLayout/main { 28 | /* the resizer line is in the wrong position in RTL with no easy fix. 29 | * Disabling is more useful than displaying it. 30 | * #167 (github) should look into this and come up with a permanent fix. 31 | */ 32 | display: none !important; 33 | } 34 | 35 | .fixedDataTableColumnResizerLineLayout/hiddenElem { 36 | display: none !important; 37 | } 38 | -------------------------------------------------------------------------------- /docs/api-v0.5/ColumnGroupAPI.md: -------------------------------------------------------------------------------- 1 | 2 | `ColumnGroup` (component) 3 | ========================= 4 | 5 | Component that defines the attributes of a table column group. 6 | 7 | Props 8 | ----- 9 | 10 | ### `align` 11 | 12 | The horizontal alignment of the table cell content. 13 | 14 | type: `enum('left'|'center'|'right')` 15 | 16 | 17 | ### `fixed` 18 | 19 | Controls if the column group is fixed when scrolling in the X axis. 20 | 21 | type: `bool` 22 | defaultValue: `false` 23 | 24 | 25 | ### `columnGroupData` 26 | 27 | Bucket for any data to be passed into column group renderer functions. 28 | 29 | type: `object` 30 | 31 | 32 | ### `label` 33 | 34 | The column group's header label. 35 | 36 | type: `string` 37 | 38 | 39 | ### `groupHeaderRenderer` 40 | 41 | The cell renderer that returns React-renderable content for a table 42 | column group header. If it's not specified, the label from props will 43 | be rendered as header content. 44 | ``` 45 | function( 46 | label: ?string, 47 | cellDataKey: string, 48 | columnGroupData: any, 49 | rowData: array, // array of labels of all columnGroups 50 | width: number 51 | ): ?$jsx 52 | ``` 53 | 54 | type: `func` 55 | 56 | -------------------------------------------------------------------------------- /src/vendor_upstream/core/requestAnimationFramePolyfill.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule requestAnimationFramePolyfill 10 | */ 11 | 12 | var emptyFunction = require('emptyFunction'); 13 | var nativeRequestAnimationFrame = require('nativeRequestAnimationFrame'); 14 | 15 | var lastTime = 0; 16 | 17 | /** 18 | * Here is the native and polyfill version of requestAnimationFrame. 19 | * Please don't use it directly and use requestAnimationFrame module instead. 20 | */ 21 | var requestAnimationFrame = 22 | nativeRequestAnimationFrame || 23 | function(callback) { 24 | var currTime = Date.now(); 25 | var timeDelay = Math.max(0, 16 - (currTime - lastTime)); 26 | lastTime = currTime + timeDelay; 27 | return global.setTimeout(function() { 28 | callback(Date.now()); 29 | }, timeDelay); 30 | }; 31 | 32 | // Works around a rare bug in Safari 6 where the first request is never invoked. 33 | requestAnimationFrame(emptyFunction); 34 | 35 | module.exports = requestAnimationFrame; 36 | -------------------------------------------------------------------------------- /src/vendor_upstream/core/ExecutionEnvironment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule ExecutionEnvironment 10 | */ 11 | 12 | /*jslint evil: true */ 13 | 14 | 'use strict'; 15 | 16 | var canUseDOM = !!( 17 | typeof window !== 'undefined' && 18 | window.document && 19 | window.document.createElement 20 | ); 21 | 22 | /** 23 | * Simple, lightweight module assisting with the detection and context of 24 | * Worker. Helps avoid circular dependencies and allows code to reason about 25 | * whether or not they are in a Worker, even if they never include the main 26 | * `ReactWorker` dependency. 27 | */ 28 | var ExecutionEnvironment = { 29 | 30 | canUseDOM: canUseDOM, 31 | 32 | canUseWorkers: typeof Worker !== 'undefined', 33 | 34 | canUseEventListeners: 35 | canUseDOM && !!(window.addEventListener || window.attachEvent), 36 | 37 | canUseViewport: canUseDOM && !!window.screen, 38 | 39 | isInWorker: !canUseDOM // For now, this is true - might change in the future. 40 | 41 | }; 42 | 43 | module.exports = ExecutionEnvironment; 44 | -------------------------------------------------------------------------------- /src/vendor_upstream/dom/BrowserSupportCore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule BrowserSupportCore 10 | */ 11 | 12 | 13 | var getVendorPrefixedName = require('getVendorPrefixedName'); 14 | 15 | var BrowserSupportCore = { 16 | /** 17 | * @return {bool} True if browser supports css animations. 18 | */ 19 | hasCSSAnimations: function() { 20 | return !!getVendorPrefixedName('animationName'); 21 | }, 22 | 23 | /** 24 | * @return {bool} True if browser supports css transforms. 25 | */ 26 | hasCSSTransforms: function() { 27 | return !!getVendorPrefixedName('transform'); 28 | }, 29 | 30 | /** 31 | * @return {bool} True if browser supports css 3d transforms. 32 | */ 33 | hasCSS3DTransforms: function() { 34 | return !!getVendorPrefixedName('perspective'); 35 | }, 36 | 37 | /** 38 | * @return {bool} True if browser supports css transitions. 39 | */ 40 | hasCSSTransitions: function() { 41 | return !!getVendorPrefixedName('transition'); 42 | }, 43 | }; 44 | 45 | module.exports = BrowserSupportCore; 46 | -------------------------------------------------------------------------------- /src/css/layout/fixedDataTableLayout.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule fixedDataTableLayout 10 | */ 11 | 12 | .fixedDataTableLayout/main { 13 | border-style: solid; 14 | border-width: 1px; 15 | box-sizing: border-box; 16 | overflow: hidden; 17 | position: relative; 18 | } 19 | 20 | .fixedDataTableLayout/header, 21 | .fixedDataTableLayout/hasBottomBorder { 22 | border-bottom-style: solid; 23 | border-bottom-width: 1px; 24 | } 25 | 26 | .fixedDataTableLayout/footer .public/fixedDataTableCell/main { 27 | border-top-style: solid; 28 | border-top-width: 1px; 29 | } 30 | 31 | .fixedDataTableLayout/topShadow, 32 | .fixedDataTableLayout/bottomShadow { 33 | height: 4px; 34 | left: 0; 35 | position: absolute; 36 | right: 0; 37 | z-index: 1; 38 | } 39 | 40 | .fixedDataTableLayout/bottomShadow { 41 | margin-top: -4px; 42 | } 43 | 44 | .fixedDataTableLayout/rowsContainer { 45 | overflow: hidden; 46 | position: relative; 47 | } 48 | 49 | .fixedDataTableLayout/horizontalScrollbar { 50 | bottom: 0; 51 | position: absolute; 52 | } 53 | -------------------------------------------------------------------------------- /src/stubs/Object.assign.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule Object.assign 10 | */ 11 | 12 | // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign 13 | 14 | 'use strict'; 15 | 16 | function assign(target, sources) { 17 | if (target == null) { 18 | throw new TypeError('Object.assign target cannot be null or undefined'); 19 | } 20 | 21 | var to = Object(target); 22 | var hasOwnProperty = Object.prototype.hasOwnProperty; 23 | 24 | for (var nextIndex = 1; nextIndex < arguments.length; nextIndex++) { 25 | var nextSource = arguments[nextIndex]; 26 | if (nextSource == null) { 27 | continue; 28 | } 29 | 30 | var from = Object(nextSource); 31 | 32 | // We don't currently support accessors nor proxies. Therefore this 33 | // copy cannot throw. If we ever supported this then we must handle 34 | // exceptions and side-effects. We don't support symbols so they won't 35 | // be transferred. 36 | 37 | for (var key in from) { 38 | if (hasOwnProperty.call(from, key)) { 39 | to[key] = from[key]; 40 | } 41 | } 42 | } 43 | 44 | return to; 45 | } 46 | 47 | module.exports = assign; 48 | -------------------------------------------------------------------------------- /site/examples/ExampleHeader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file provided by Facebook is for non-commercial testing and evaluation 3 | * purposes only. Facebook reserves all rights not expressly granted. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 7 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8 | * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 9 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 10 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | "use strict"; 14 | 15 | var React = require('react'); 16 | var Constants = require('../Constants'); 17 | 18 | var ExampleHeader = React.createClass({ 19 | render() { 20 | return ( 21 |
22 |
23 |
24 |

25 | 26 | Example: 27 | 28 | {' '} 29 | {this.props.page.title} 30 |

31 |

32 | Example code 33 | {this.props.page.description} 34 |

35 |
36 | ); 37 | } 38 | }); 39 | 40 | module.exports = ExampleHeader; 41 | -------------------------------------------------------------------------------- /src/vendor_upstream/core/shallowEqual.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule shallowEqual 10 | * @typechecks 11 | * @flow 12 | */ 13 | 14 | 'use strict'; 15 | 16 | var hasOwnProperty = Object.prototype.hasOwnProperty; 17 | 18 | /** 19 | * Performs equality by iterating through keys on an object and returning false 20 | * when any key has values which are not strictly equal between the arguments. 21 | * Returns true when the values of all keys are strictly equal. 22 | */ 23 | function shallowEqual(objA: mixed, objB: mixed): boolean { 24 | if (objA === objB) { 25 | return true; 26 | } 27 | 28 | if (typeof objA !== 'object' || objA === null || 29 | typeof objB !== 'object' || objB === null) { 30 | return false; 31 | } 32 | 33 | var keysA = Object.keys(objA); 34 | var keysB = Object.keys(objB); 35 | 36 | if (keysA.length !== keysB.length) { 37 | return false; 38 | } 39 | 40 | // Test for A's keys different from B. 41 | var bHasOwnProperty = hasOwnProperty.bind(objB); 42 | for (var i = 0; i < keysA.length; i++) { 43 | if (!bHasOwnProperty(keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) { 44 | return false; 45 | } 46 | } 47 | 48 | return true; 49 | } 50 | 51 | module.exports = shallowEqual; 52 | -------------------------------------------------------------------------------- /site/miniHeader.less: -------------------------------------------------------------------------------- 1 | .miniHeader { 2 | background: #435052; 3 | position: fixed; 4 | width: 100%; 5 | z-index: 1; 6 | top: 0; 7 | 8 | .miniLogo { 9 | width: 169px; 10 | height: 23px; 11 | margin-top: 1px; 12 | background: url(./images/fdt_logo_transparent_ondark_23px.png) no-repeat scroll; 13 | 14 | @media only screen and (-webkit-min-device-pixel-ratio: 2), 15 | only screen and ( min-resolution: 192dpi), 16 | only screen and ( min-resolution: 2dppx) { 17 | background-image: url(./images/fdt_logo_transparent_ondark_23px-2x.png); 18 | background-size: contain; 19 | } 20 | } 21 | 22 | .lines:after { 23 | position: absolute; 24 | content: ''; 25 | border-left: 3px solid #450500; 26 | height: 12px; 27 | display: block; 28 | left: 4px; 29 | top: -7px; 30 | } 31 | 32 | .lines:before { 33 | position: absolute; 34 | content: ''; 35 | display: block; 36 | width: 19px; 37 | height: 0; 38 | border-top: 2px solid #ff0; 39 | top: -7px; 40 | } 41 | 42 | .lines { 43 | display: inline-block; 44 | position: relative; 45 | width: 19px; 46 | top: -1px; 47 | height: 3px; 48 | margin-right: 6px; 49 | border-bottom: 2px solid #fff; 50 | border-top: 2px solid #fff; 51 | } 52 | 53 | .homeLink { 54 | display: none; 55 | } 56 | 57 | @media only screen and (max-width: 680px) { 58 | .homeLink { 59 | display: inline; 60 | } 61 | 62 | .miniLogo { 63 | display: none; 64 | } 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /site/SideBar.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var React = require('react'); 4 | var Constants = require('./Constants'); 5 | 6 | var SideBar = React.createClass({ 7 | render() { 8 | return ( 9 |
10 |
11 | {this._renderSections(this.props.pages)} 12 |
13 |
14 | ); 15 | }, 16 | 17 | _renderSections(pages) { 18 | return Object.keys(pages).map(pageKey => { 19 | var page = pages[pageKey]; 20 | if (typeof page !== 'object') { 21 | return null; 22 | } 23 | 24 | if (page.groupTitle) { 25 | return [ 26 | this._renderGroupTitle(page.groupTitle), 27 | ...this._renderSections(page), 28 | ]; 29 | } 30 | 31 | return this._renderLink( 32 | page.title, 33 | page.location 34 | ); 35 | }); 36 | }, 37 | 38 | _renderGroupTitle(title) { 39 | return ( 40 |

{title}

41 | ); 42 | }, 43 | 44 | _renderLink(linkName, linkUrl) { 45 | var arrow = ; 46 | var linkClass = 'sideItem'; 47 | if (this.props.page.location === linkUrl) { 48 | linkClass += ' curSideItem'; 49 | } 50 | 51 | return ( 52 |

53 | 54 | {linkName} 55 | {arrow} 56 | 57 |

58 | ); 59 | }, 60 | }); 61 | 62 | module.exports = SideBar; 63 | -------------------------------------------------------------------------------- /site/examples/ExamplesWrapper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file provided by Facebook is for non-commercial testing and evaluation 3 | * purposes only. Facebook reserves all rights not expressly granted. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 7 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8 | * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 9 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 10 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | "use strict"; 14 | 15 | require('./examplesPageStyle.less'); 16 | 17 | var MiniHeader = require('../MiniHeader'); 18 | var SideBar = require('../SideBar'); 19 | var React = require('react'); 20 | var Constants = require('../Constants'); 21 | 22 | var ExamplesWrapper = React.createClass({ 23 | render() { 24 | return ( 25 |
26 | 27 | 28 |
29 |
30 | 35 |
36 | {this.props.children} 37 |
38 |
39 |
40 |
41 | ); 42 | } 43 | }); 44 | 45 | module.exports = ExamplesWrapper; 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD License 2 | 3 | For FixedDataTable software 4 | 5 | Copyright (c) 2015, Facebook, Inc. All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without modification, 8 | are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name Facebook nor the names of its contributors may be used to 18 | endorse or promote products derived from this software without specific 19 | prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 22 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 25 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 28 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /src/css/style/fixedDataTable.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule fixedDataTable 10 | * 11 | */ 12 | 13 | /** 14 | * Table. 15 | */ 16 | .public/fixedDataTable/main { 17 | border-color: #d3d3d3; 18 | } 19 | 20 | .public/fixedDataTable/header, 21 | .public/fixedDataTable/hasBottomBorder { 22 | border-color: #d3d3d3; 23 | } 24 | 25 | .public/fixedDataTable/header .public/fixedDataTableCell/main { 26 | font-weight: bold; 27 | } 28 | 29 | .public/fixedDataTable/header, 30 | .public/fixedDataTable/header .public/fixedDataTableCell/main { 31 | background-color: var(fbui-desktop-background-light); 32 | background-image: linear-gradient(#fff, #efefef); 33 | } 34 | 35 | .public/fixedDataTable/footer .public/fixedDataTableCell/main { 36 | background-color: var(fbui-desktop-background-light); 37 | border-color: #d3d3d3; 38 | } 39 | 40 | .public/fixedDataTable/topShadow { 41 | background: 0 0 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAECAYAAABP2FU6AAAAF0lEQVR4AWPUkNeSBhHCjJoK2twgFisAFagCCp3pJlAAAAAASUVORK5CYII=) repeat-x; 42 | } 43 | 44 | .public/fixedDataTable/bottomShadow { 45 | background: 0 0 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAECAYAAABP2FU6AAAAHElEQVQI12MwNjZmZdAT1+Nm0JDWEGZQk1GTBgAWkwIeAEp52AAAAABJRU5ErkJggg==) repeat-x; 46 | } 47 | 48 | .public/fixedDataTable/horizontalScrollbar .public/Scrollbar/mainHorizontal { 49 | background-color: var(fbui-white); 50 | } 51 | -------------------------------------------------------------------------------- /src/stubs/invariant.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule invariant 10 | */ 11 | 12 | "use strict"; 13 | 14 | /** 15 | * Use invariant() to assert state which your program assumes to be true. 16 | * 17 | * Provide sprintf-style format (only %s is supported) and arguments 18 | * to provide information about what broke and what you were 19 | * expecting. 20 | * 21 | * The invariant message will be stripped in production, but the invariant 22 | * will remain to ensure logic does not differ in production. 23 | */ 24 | 25 | var invariant = function(condition, format, a, b, c, d, e, f) { 26 | if (__DEV__) { 27 | if (format === undefined) { 28 | throw new Error('invariant requires an error message argument'); 29 | } 30 | } 31 | 32 | if (!condition) { 33 | var error; 34 | if (format === undefined) { 35 | error = new Error( 36 | 'Minified exception occurred; use the non-minified dev environment ' + 37 | 'for the full error message and additional helpful warnings.' 38 | ); 39 | } else { 40 | var args = [a, b, c, d, e, f]; 41 | var argIndex = 0; 42 | error = new Error( 43 | 'Invariant Violation: ' + 44 | format.replace(/%s/g, function() { return args[argIndex++]; }) 45 | ); 46 | } 47 | 48 | error.framesToPop = 1; // we don't care about invariant's own frame 49 | throw error; 50 | } 51 | }; 52 | 53 | module.exports = invariant; 54 | -------------------------------------------------------------------------------- /src/css/layout/fixedDataTableCellLayout.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule fixedDataTableCellLayout 10 | */ 11 | 12 | .fixedDataTableCellLayout/main { 13 | border-right-style: solid; 14 | border-right-width: 1px; 15 | border-width: 0 1px 0 0; 16 | box-sizing: border-box; 17 | display: block; 18 | overflow: hidden; 19 | position: absolute; 20 | white-space: normal; 21 | } 22 | 23 | .fixedDataTableCellLayout/lastChild { 24 | border-width: 0 1px 1px 0; 25 | } 26 | 27 | .fixedDataTableCellLayout/alignRight { 28 | text-align: right; 29 | } 30 | 31 | .fixedDataTableCellLayout/alignCenter { 32 | text-align: center; 33 | } 34 | 35 | .fixedDataTableCellLayout/wrap1 { 36 | display: table; 37 | } 38 | 39 | .fixedDataTableCellLayout/wrap2 { 40 | display: table-row; 41 | } 42 | 43 | .fixedDataTableCellLayout/wrap3 { 44 | display: table-cell; 45 | vertical-align: middle; 46 | } 47 | 48 | .fixedDataTableCellLayout/columnResizerContainer { 49 | position: absolute; 50 | right: 0px; 51 | width: 6px; 52 | z-index: 1; 53 | } 54 | 55 | .fixedDataTableCellLayout/columnResizerContainer:hover { 56 | cursor: ew-resize; 57 | } 58 | 59 | .fixedDataTableCellLayout/columnResizerContainer:hover .fixedDataTableCellLayout/columnResizerKnob { 60 | visibility: visible; 61 | } 62 | 63 | .fixedDataTableCellLayout/columnResizerKnob { 64 | position: absolute; 65 | right: 0px; 66 | visibility: hidden; 67 | width: 4px; 68 | } 69 | -------------------------------------------------------------------------------- /src/vendor_upstream/dom/translateDOMPositionXY.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule translateDOMPositionXY 10 | * @typechecks 11 | */ 12 | 13 | 'use strict'; 14 | 15 | var BrowserSupportCore = require('BrowserSupportCore'); 16 | 17 | var getVendorPrefixedName = require('getVendorPrefixedName'); 18 | 19 | var TRANSFORM = getVendorPrefixedName('transform'); 20 | var BACKFACE_VISIBILITY = getVendorPrefixedName('backfaceVisibility'); 21 | 22 | var translateDOMPositionXY = (function() { 23 | if (BrowserSupportCore.hasCSSTransforms()) { 24 | var ua = global.window ? global.window.navigator.userAgent : 'UNKNOWN'; 25 | var isSafari = (/Safari\//).test(ua) && !(/Chrome\//).test(ua); 26 | // It appears that Safari messes up the composition order 27 | // of GPU-accelerated layers 28 | // (see bug https://bugs.webkit.org/show_bug.cgi?id=61824). 29 | // Use 2D translation instead. 30 | if (!isSafari && BrowserSupportCore.hasCSS3DTransforms()) { 31 | return function(/*object*/ style, /*number*/ x, /*number*/ y) { 32 | style[TRANSFORM] ='translate3d(' + x + 'px,' + y + 'px,0)'; 33 | style[BACKFACE_VISIBILITY] = 'hidden'; 34 | }; 35 | } else { 36 | return function(/*object*/ style, /*number*/ x, /*number*/ y) { 37 | style[TRANSFORM] = 'translate(' + x + 'px,' + y + 'px)'; 38 | }; 39 | } 40 | } else { 41 | return function(/*object*/ style, /*number*/ x, /*number*/ y) { 42 | style.left = x + 'px'; 43 | style.top = y + 'px'; 44 | }; 45 | } 46 | })(); 47 | 48 | module.exports = translateDOMPositionXY; 49 | -------------------------------------------------------------------------------- /site/examples/TouchableArea.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file provided by Facebook is for non-commercial testing and evaluation 3 | * purposes only. Facebook reserves all rights not expressly granted. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 7 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8 | * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 9 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 10 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | var React = require('React'); 14 | 15 | var TouchableArea = React.createClass({ 16 | getDefaultProps() { 17 | return { 18 | touchable: true 19 | }; 20 | }, 21 | 22 | handleTouchStart(e) { 23 | if (!this.props.scroller || !this.props.touchable) { 24 | return; 25 | } 26 | 27 | this.props.scroller.doTouchStart(e.touches, e.timeStamp); 28 | e.preventDefault(); 29 | }, 30 | 31 | handleTouchMove(e) { 32 | if (!this.props.scroller || !this.props.touchable) { 33 | return; 34 | } 35 | 36 | this.props.scroller.doTouchMove(e.touches, e.timeStamp, e.scale); 37 | e.preventDefault(); 38 | }, 39 | 40 | handleTouchEnd(e) { 41 | if (!this.props.scroller || !this.props.touchable) { 42 | return; 43 | } 44 | 45 | this.props.scroller.doTouchEnd(e.timeStamp); 46 | e.preventDefault(); 47 | }, 48 | 49 | render() { 50 | return ( 51 |
56 | {this.props.children} 57 |
58 | ); 59 | } 60 | }); 61 | 62 | module.exports = TouchableArea; 63 | -------------------------------------------------------------------------------- /site/docs/DocsPage.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | require('./docsPageStyle.less'); 4 | 5 | var MiniHeader = require('../MiniHeader'); 6 | var SideBar = require('../SideBar'); 7 | var StaticHTMLBlock = require('../StaticHTMLBlock'); 8 | var React = require('react'); 9 | var Constants = require('../Constants'); 10 | 11 | var DocsPages = Constants.DocsPages; 12 | 13 | var DOCS_MARKDOWN_FILES = { 14 | [DocsPages.DOCS.GETTING_STARTED.location]: require('../../docs/README.md'), 15 | [DocsPages.DOCS.V6_MIGRATION.location]: require('../../docs/v6-migration.md'), 16 | 17 | // API 18 | [DocsPages.API.TABLE_API.location]: require('../../docs/api/TableAPI.md'), 19 | [DocsPages.API.COLUMN_API.location]: require('../../docs/api/ColumnAPI.md'), 20 | [DocsPages.API.COLUMNGROUP_API.location]: require('../../docs/api/ColumnGroupAPI.md'), 21 | [DocsPages.API.CELL_API.location]: require('../../docs/api/CellAPI.md'), 22 | 23 | // API - v0.5 24 | [DocsPages.API_V5.TABLE_API.location]: require('../../docs/api-v0.5/TableAPI.md'), 25 | [DocsPages.API_V5.COLUMN_API.location]: require('../../docs/api-v0.5/ColumnAPI.md'), 26 | [DocsPages.API_V5.COLUMNGROUP_API.location]: require('../../docs/api-v0.5/ColumnGroupAPI.md'), 27 | }; 28 | 29 | var DocsPage = React.createClass({ 30 | render() { 31 | var HTML = DOCS_MARKDOWN_FILES[this.props.page.location]; 32 | 33 | return ( 34 |
35 | 36 | 37 |
38 |
39 | 44 | 48 |
49 |
50 |
51 | ); 52 | }, 53 | }); 54 | 55 | module.exports = DocsPage; 56 | -------------------------------------------------------------------------------- /src/vendor_upstream/core/getVendorPrefixedName.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule getVendorPrefixedName 10 | * @typechecks 11 | */ 12 | 13 | var ExecutionEnvironment = require('ExecutionEnvironment'); 14 | 15 | var camelize = require('camelize'); 16 | var invariant = require('invariant'); 17 | 18 | var memoized = {}; 19 | var prefixes = ['Webkit', 'ms', 'Moz', 'O']; 20 | var prefixRegex = new RegExp('^(' + prefixes.join('|') + ')'); 21 | var testStyle = 22 | ExecutionEnvironment.canUseDOM ? document.createElement('div').style : {}; 23 | 24 | function getWithPrefix(name) { 25 | for (var i = 0; i < prefixes.length; i++) { 26 | var prefixedName = prefixes[i] + name; 27 | if (prefixedName in testStyle) { 28 | return prefixedName; 29 | } 30 | } 31 | return null; 32 | } 33 | 34 | /** 35 | * @param {string} property Name of a css property to check for. 36 | * @return {?string} property name supported in the browser, or null if not 37 | * supported. 38 | */ 39 | function getVendorPrefixedName(property) { 40 | var name = camelize(property); 41 | if (memoized[name] === undefined) { 42 | var capitalizedName = name.charAt(0).toUpperCase() + name.slice(1); 43 | if (prefixRegex.test(capitalizedName)) { 44 | invariant( 45 | false, 46 | 'getVendorPrefixedName must only be called with unprefixed' + 47 | 'CSS property names. It was called with %s', property 48 | ); 49 | } 50 | memoized[name] = 51 | (name in testStyle) ? name : getWithPrefix(capitalizedName); 52 | } 53 | return memoized[name]; 54 | } 55 | 56 | module.exports = getVendorPrefixedName; 57 | -------------------------------------------------------------------------------- /site/webpack-prerender.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | var resolvers = require('../build_helpers/resolvers'); 4 | 5 | var isDev = process.env.NODE_ENV !== 'production'; 6 | 7 | module.exports = { 8 | entry: path.join(__dirname, 'renderPath.js'), 9 | 10 | output: { 11 | path: '__site_prerender__/', 12 | filename: 'renderPath.js', 13 | libraryTarget: 'commonjs2', 14 | }, 15 | 16 | target: 'node', 17 | 18 | module: { 19 | loaders: [ 20 | { 21 | test: /\.md$/, 22 | loader: [ 23 | 'html?{"minimize":false}', 24 | path.join(__dirname, '../build_helpers/markdownLoader') 25 | ].join('!') 26 | }, 27 | { 28 | test: /\.js$/, 29 | exclude: /node_modules/, 30 | loader: 'babel-loader' 31 | }, 32 | { 33 | test: /\.css$/, 34 | loader: 'null-loader' 35 | }, 36 | { 37 | test: /\.less$/, 38 | loader: 'null-loader' 39 | }, 40 | { 41 | test: /\.png$/, 42 | loader: 'file-loader', 43 | query: { mimetype: 'image/png', name: 'images/[name]-[hash].[ext]' } 44 | } 45 | ] 46 | }, 47 | 48 | resolve: { 49 | alias: { 50 | 'fixed-data-table/css': path.join(__dirname, '../src/css'), 51 | 'fixed-data-table': path.join(__dirname, '../src/FixedDataTableRoot') 52 | } 53 | }, 54 | 55 | plugins: [ 56 | new webpack.optimize.OccurenceOrderPlugin(), 57 | new webpack.DefinePlugin({ 58 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), 59 | '__DEV__': JSON.stringify(isDev || true) 60 | }), 61 | resolvers.resolveHasteDefines 62 | ] 63 | }; 64 | 65 | if (process.env.NODE_ENV === 'production') { 66 | module.exports.plugins.push( 67 | new webpack.optimize.UglifyJsPlugin({ 68 | compressor: { 69 | warnings: false 70 | } 71 | }) 72 | ); 73 | } 74 | -------------------------------------------------------------------------------- /src/vendor_upstream/stubs/cx.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule cx 10 | */ 11 | 12 | var slashReplaceRegex = /\//g; 13 | var cache = {}; 14 | 15 | function getClassName(className) { 16 | if (cache[className]) { 17 | return cache[className]; 18 | } 19 | 20 | cache[className] = className.replace(slashReplaceRegex, '_'); 21 | return cache[className]; 22 | } 23 | 24 | /** 25 | * This function is used to mark string literals representing CSS class names 26 | * so that they can be transformed statically. This allows for modularization 27 | * and minification of CSS class names. 28 | * 29 | * In static_upstream, this function is actually implemented, but it should 30 | * eventually be replaced with something more descriptive, and the transform 31 | * that is used in the main stack should be ported for use elsewhere. 32 | * 33 | * @param string|object className to modularize, or an object of key/values. 34 | * In the object case, the values are conditions that 35 | * determine if the className keys should be included. 36 | * @param [string ...] Variable list of classNames in the string case. 37 | * @return string Renderable space-separated CSS className. 38 | */ 39 | function cx(classNames) { 40 | var classNamesArray; 41 | if (typeof classNames == 'object') { 42 | classNamesArray = Object.keys(classNames).filter(function(className) { 43 | return classNames[className]; 44 | }); 45 | } else { 46 | classNamesArray = Array.prototype.slice.call(arguments); 47 | } 48 | 49 | return classNamesArray.map(getClassName).join(' '); 50 | } 51 | 52 | module.exports = cx; 53 | -------------------------------------------------------------------------------- /PATENTS: -------------------------------------------------------------------------------- 1 | Additional Grant of Patent Rights Version 2 2 | 3 | "Software" means the FixedDataTable software distributed by Facebook, Inc. 4 | 5 | Facebook, Inc. ("Facebook") hereby grants to each recipient of the Software 6 | ("you") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable 7 | (subject to the termination provision below) license under any Necessary 8 | Claims, to make, have made, use, sell, offer to sell, import, and otherwise 9 | transfer the Software. For avoidance of doubt, no license is granted under 10 | Facebook’s rights in any patent claims that are infringed by (i) modifications 11 | to the Software made by you or any third party or (ii) the Software in 12 | combination with any software or other technology. 13 | 14 | The license granted hereunder will terminate, automatically and without notice, 15 | if you (or any of your subsidiaries, corporate affiliates or agents) initiate 16 | directly or indirectly, or take a direct financial interest in, any Patent 17 | Assertion: (i) against Facebook or any of its subsidiaries or corporate 18 | affiliates, (ii) against any party if such Patent Assertion arises in whole or 19 | in part from any software, technology, product or service of Facebook or any of 20 | its subsidiaries or corporate affiliates, or (iii) against any party relating 21 | to the Software. Notwithstanding the foregoing, if Facebook or any of its 22 | subsidiaries or corporate affiliates files a lawsuit alleging patent 23 | infringement against you in the first instance, and you respond by filing a 24 | patent infringement counterclaim in that lawsuit against that party that is 25 | unrelated to the Software, the license granted hereunder will not terminate 26 | under section (i) of this paragraph due to such counterclaim. 27 | 28 | A "Necessary Claim" is a claim of a patent owned by Facebook that is 29 | necessarily infringed by the Software standing alone. 30 | 31 | A "Patent Assertion" is any lawsuit or other action alleging direct, indirect, 32 | or contributory infringement or inducement to infringe any patent, including a 33 | cross-claim or counterclaim. 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fixed-data-table", 3 | "version": "0.6.0", 4 | "description": "A React table component designed to allow presenting thousands of rows of data.", 5 | "main": "main.js", 6 | "peerDependencies": { 7 | "react": ">=0.13.0 <0.15.0 || ^0.14.0-beta3", 8 | "react-dom": ">=0.14.0 <0.15.0 || ^0.14.0-beta3" 9 | }, 10 | "devDependencies": { 11 | "autoprefixer": "^5.0.0", 12 | "babel-core": "^5.4.7", 13 | "babel-loader": "^5.0.0", 14 | "bundle-loader": "^0.5.2", 15 | "css-loader": "^0.9.1", 16 | "extract-text-webpack-plugin": "^0.3.8", 17 | "faker": "^2.1.2", 18 | "file-loader": "^0.8.1", 19 | "glob": "^4.3.5", 20 | "html-loader": "^0.2.3", 21 | "less": "^2.2.0", 22 | "less-loader": "^2.0.0", 23 | "marked": "^0.3.2", 24 | "null-loader": "^0.1.0", 25 | "postcss": "^4.0.2", 26 | "postcss-custom-properties": "3.0.1", 27 | "react": "^0.14.0", 28 | "react-docgen": "^1.2.0", 29 | "react-tools": "^0.12.2", 30 | "style-loader": "^0.8.3", 31 | "url-loader": "^0.5.5", 32 | "webpack": "^1.8.3", 33 | "webpack-dev-server": "^1.8.0" 34 | }, 35 | "scripts": { 36 | "site-dev-server": "./build_helpers/startSiteDevServer.sh", 37 | "site-build": "./build_helpers/buildStaticSite.sh", 38 | "build-dist": "./build_helpers/buildDist.sh", 39 | "build-npm": "./build_helpers/buildNPMInternals.sh", 40 | "build-docs": "./build_helpers/buildAPIDocs.sh", 41 | "publish-site": "./build_helpers/publishStaticSite.sh", 42 | "publish-package": "./build_helpers/publishPackage.sh", 43 | "test": "echo \"Error: no test specified\" && exit 1" 44 | }, 45 | "repository": { 46 | "type": "git", 47 | "url": "https://github.com/facebook/fixed-data-table.git" 48 | }, 49 | "license": "BSD-3-Clause", 50 | "bugs": { 51 | "url": "https://github.com/facebook/fixed-data-table/issues" 52 | }, 53 | "homepage": "http://facebook.github.io/fixed-data-table", 54 | "tags": [ 55 | "react", 56 | "table" 57 | ], 58 | "keywords": [ 59 | "react", 60 | "react-component", 61 | "table", 62 | "data-table", 63 | "fixed-table" 64 | ] 65 | } 66 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to FixedDataTable 2 | We want to make contributing to this project as easy and transparent as possible. 3 | 4 | ## Our Development Process 5 | Some of the core team will be working directly on GitHub. These changes will be public from the beginning. Other changesets will come via a bridge with Facebook's internal source control. This is a necessity as it allows engineers at Facebook outside of the core team to move fast and contribute from an environment they are comfortable in. 6 | 7 | ## Pull Requests 8 | 9 | We actively welcome your pull requests - however, before you begin a pull request, please create an issue so we can determine whether or not the work that you are planning to do is either already being worked on or out of the scope of this project. 10 | 11 | 1. Fork the repo and create your branch from `master`. 12 | 13 | 2. If you've added code that should be tested, add tests (tests coming soon). 14 | 15 | 3. Ensure the test suite passes (coming soon). 16 | 17 | 4. Make sure your code lints (coming soon). 18 | 19 | 5. Do not commit anything to the `dist` folder. 20 | 21 | 6. If you haven't already, complete the Contributor License Agreement ("CLA"). 22 | 23 | ## Contributor License Agreement ("CLA") 24 | In order to accept your pull request, we need you to submit a CLA. You only need to do this once to work on any of Facebook's open source projects. 25 | 26 | Complete your CLA here: 27 | 28 | ## Issues 29 | We use GitHub issues to track public bugs. Please ensure your description is clear and has sufficient instructions to be able to reproduce the issue. 30 | 31 | Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe disclosure of security bugs. In those cases, please go through the process outlined on that page and do not file a public issue. 32 | 33 | ## Coding Style 34 | * Use semicolons; 35 | * Commas last, 36 | * 2 spaces for indentation (no tabs) 37 | * Prefer `'` over `"` 38 | * `"use strict";` 39 | * 80 character line length 40 | * "Attractive" 41 | * Do not use the optional parameters of `setTimeout` and `setInterval` 42 | 43 | ## License 44 | By contributing to FixedDataTable, you agree that your contributions will be licensed under its BSD license. 45 | -------------------------------------------------------------------------------- /src/vendor_upstream/core/debounceCore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule debounceCore 10 | * @typechecks 11 | */ 12 | 13 | /** 14 | * Invokes the given callback after a specified number of milliseconds have 15 | * elapsed, ignoring subsequent calls. 16 | * 17 | * For example, if you wanted to update a preview after the user stops typing 18 | * you could do the following: 19 | * 20 | * elem.addEventListener('keyup', debounce(this.updatePreview, 250), false); 21 | * 22 | * The returned function has a reset method which can be called to cancel a 23 | * pending invocation. 24 | * 25 | * var debouncedUpdatePreview = debounce(this.updatePreview, 250); 26 | * elem.addEventListener('keyup', debouncedUpdatePreview, false); 27 | * 28 | * // later, to cancel pending calls 29 | * debouncedUpdatePreview.reset(); 30 | * 31 | * @param {function} func - the function to debounce 32 | * @param {number} wait - how long to wait in milliseconds 33 | * @param {*} context - optional context to invoke the function in 34 | * @param {?function} setTimeoutFunc - an implementation of setTimeout 35 | * if nothing is passed in the default setTimeout function is used 36 | * @param {?function} clearTimeoutFunc - an implementation of clearTimeout 37 | * if nothing is passed in the default clearTimeout function is used 38 | */ 39 | function debounce(func, wait, context, setTimeoutFunc, clearTimeoutFunc) { 40 | setTimeoutFunc = setTimeoutFunc || setTimeout; 41 | clearTimeoutFunc = clearTimeoutFunc || clearTimeout; 42 | var timeout; 43 | 44 | function debouncer(...args) { 45 | debouncer.reset(); 46 | 47 | var callback = function() { 48 | func.apply(context, args); 49 | }; 50 | callback.__SMmeta = func.__SMmeta; 51 | timeout = setTimeoutFunc(callback, wait); 52 | } 53 | 54 | debouncer.reset = function() { 55 | clearTimeoutFunc(timeout); 56 | }; 57 | 58 | return debouncer; 59 | } 60 | 61 | module.exports = debounce; 62 | -------------------------------------------------------------------------------- /src/vendor_upstream/react/renderers/dom/client/utils/isEventSupported.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule isEventSupported 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var ExecutionEnvironment = require('ExecutionEnvironment'); 15 | 16 | var useHasFeature; 17 | if (ExecutionEnvironment.canUseDOM) { 18 | useHasFeature = 19 | document.implementation && 20 | document.implementation.hasFeature && 21 | // always returns true in newer browsers as per the standard. 22 | // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature 23 | document.implementation.hasFeature('', '') !== true; 24 | } 25 | 26 | /** 27 | * Checks if an event is supported in the current execution environment. 28 | * 29 | * NOTE: This will not work correctly for non-generic events such as `change`, 30 | * `reset`, `load`, `error`, and `select`. 31 | * 32 | * Borrows from Modernizr. 33 | * 34 | * @param {string} eventNameSuffix Event name, e.g. "click". 35 | * @param {?boolean} capture Check if the capture phase is supported. 36 | * @return {boolean} True if the event is supported. 37 | * @internal 38 | * @license Modernizr 3.0.0pre (Custom Build) | MIT 39 | */ 40 | function isEventSupported(eventNameSuffix, capture) { 41 | if (!ExecutionEnvironment.canUseDOM || 42 | capture && !('addEventListener' in document)) { 43 | return false; 44 | } 45 | 46 | var eventName = 'on' + eventNameSuffix; 47 | var isSupported = eventName in document; 48 | 49 | if (!isSupported) { 50 | var element = document.createElement('div'); 51 | element.setAttribute(eventName, 'return;'); 52 | isSupported = typeof element[eventName] === 'function'; 53 | } 54 | 55 | if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') { 56 | // This is the only way to test support for the `wheel` event in IE9+. 57 | isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); 58 | } 59 | 60 | return isSupported; 61 | } 62 | 63 | module.exports = isEventSupported; 64 | -------------------------------------------------------------------------------- /examples/helpers/FakeObjectDataListStore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file provided by Facebook is for non-commercial testing and evaluation 3 | * purposes only. Facebook reserves all rights not expressly granted. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 7 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8 | * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 9 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 10 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | var faker = require('faker'); 14 | 15 | class FakeObjectDataListStore { 16 | constructor(/*number*/ size){ 17 | this.size = size || 2000; 18 | this._cache = []; 19 | } 20 | 21 | createFakeRowObjectData(/*number*/ index) /*object*/ { 22 | return { 23 | id: index, 24 | avartar: faker.image.avatar(), 25 | city: faker.address.city(), 26 | email: faker.internet.email(), 27 | firstName: faker.name.firstName(), 28 | lastName: faker.name.lastName(), 29 | street: faker.address.streetName(), 30 | zipCode: faker.address.zipCode(), 31 | date: faker.date.past(), 32 | bs: faker.company.bs(), 33 | catchPhrase: faker.company.catchPhrase(), 34 | companyName: faker.company.companyName(), 35 | words: faker.lorem.words(), 36 | sentence: faker.lorem.sentence(), 37 | }; 38 | } 39 | 40 | getObjectAt(/*number*/ index) /*?object*/ { 41 | if (index < 0 || index > this.size){ 42 | return undefined; 43 | } 44 | if (this._cache[index] === undefined) { 45 | this._cache[index] = this.createFakeRowObjectData(index); 46 | } 47 | return this._cache[index]; 48 | } 49 | 50 | /** 51 | * Populates the entire cache with data. 52 | * Use with Caution! Behaves slowly for large sizes 53 | * ex. 100,000 rows 54 | */ 55 | getAll() { 56 | if (this._cache.length < this.size) { 57 | for (var i = 0; i < this.size; i++) { 58 | this.getObjectAt(i); 59 | } 60 | } 61 | return this._cache.slice(); 62 | } 63 | 64 | getSize() { 65 | return this.size; 66 | } 67 | } 68 | 69 | module.exports = FakeObjectDataListStore; 70 | -------------------------------------------------------------------------------- /examples/helpers/ExampleImage.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file provided by Facebook is for non-commercial testing and evaluation 3 | * purposes only. Facebook reserves all rights not expressly granted. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 7 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8 | * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 9 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 10 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | var React = require('react'); 14 | 15 | var PendingPool = {}; 16 | var ReadyPool = {}; 17 | 18 | var ExampleImage = React.createClass({ 19 | propTypes: { 20 | src: React.PropTypes.string.isRequired, 21 | }, 22 | 23 | getInitialState() { 24 | return { 25 | ready: false, 26 | }; 27 | }, 28 | 29 | componentWillMount() { 30 | this._load(this.props.src); 31 | }, 32 | 33 | componentWillReceiveProps(nextProps) { 34 | if (nextProps.src !== this.props.src) { 35 | this.setState({src: null}); 36 | this._load(nextProps.src); 37 | } 38 | }, 39 | 40 | render() { 41 | var style = this.state.src ? 42 | { backgroundImage : 'url(' + this.state.src + ')'} : 43 | undefined; 44 | 45 | return
; 46 | }, 47 | 48 | _load(/*string*/ src) { 49 | if (ReadyPool[src]) { 50 | this.setState({src: src}); 51 | return; 52 | } 53 | 54 | if (PendingPool[src]) { 55 | PendingPool[src].push(this._onLoad); 56 | return; 57 | } 58 | 59 | PendingPool[src] = [this._onLoad]; 60 | 61 | var img = new Image(); 62 | img.onload = () => { 63 | PendingPool[src].forEach(/*function*/ callback => { 64 | callback(src); 65 | }); 66 | delete PendingPool[src]; 67 | img.onload = null; 68 | src = undefined; 69 | }; 70 | img.src = src; 71 | }, 72 | 73 | _onLoad(/*string*/ src) { 74 | ReadyPool[src] = true; 75 | if (this.isMounted() && src === this.props.src) { 76 | this.setState({ 77 | src: src, 78 | }); 79 | } 80 | }, 81 | }); 82 | 83 | 84 | module.exports = ExampleImage; 85 | -------------------------------------------------------------------------------- /src/FixedDataTableColumnGroupNew.react.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule FixedDataTableColumnGroupNew.react 10 | * @typechecks 11 | */ 12 | 13 | var React = require('React'); 14 | 15 | var {PropTypes} = React; 16 | 17 | /** 18 | * Component that defines the attributes of a table column group. 19 | */ 20 | var FixedDataTableColumnGroup = React.createClass({ 21 | statics: { 22 | __TableColumnGroup__: true, 23 | }, 24 | 25 | propTypes: { 26 | /** 27 | * The horizontal alignment of the table cell content. 28 | */ 29 | align: PropTypes.oneOf(['left', 'center', 'right']), 30 | 31 | /** 32 | * Controls if the column group is fixed when scrolling in the X axis. 33 | */ 34 | fixed: PropTypes.bool, 35 | 36 | /** 37 | * This is the header cell for this column group. 38 | * This can either be a string or a React element. Passing in a string 39 | * will render a default footer cell with that string. By default, the React 40 | * element passed in can expect to receive the following props: 41 | * 42 | * ``` 43 | * props: { 44 | * height: number // (supplied from the groupHeaderHeight) 45 | * width: number // (supplied from the Column) 46 | * } 47 | * ``` 48 | * 49 | * Because you are passing in your own React element, you can feel free to 50 | * pass in whatever props you may want or need. 51 | * 52 | * You can also pass in a function that returns a react elemnt, with the 53 | * props object above passed in as the first parameter. 54 | */ 55 | header: PropTypes.oneOfType([ 56 | PropTypes.node, 57 | PropTypes.func, 58 | ]), 59 | 60 | }, 61 | 62 | getDefaultProps() /*object*/ { 63 | return { 64 | fixed: false, 65 | }; 66 | }, 67 | 68 | render() { 69 | if (__DEV__) { 70 | throw new Error( 71 | 'Component should never render' 72 | ); 73 | } 74 | return null; 75 | }, 76 | }); 77 | 78 | module.exports = FixedDataTableColumnGroup; 79 | -------------------------------------------------------------------------------- /site/webpack-client.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | var resolvers = require('../build_helpers/resolvers'); 4 | var ExtractTextPlugin = require('extract-text-webpack-plugin'); 5 | 6 | var isDev = process.env.NODE_ENV !== 'production'; 7 | 8 | module.exports = { 9 | 10 | devtool: 'source-map', 11 | 12 | entry: path.join(__dirname, 'client.js'), 13 | 14 | output: { 15 | path: '__site__/', 16 | filename: isDev ? '[name].js' : '[name]-[hash].js', 17 | publicPath: '', 18 | }, 19 | 20 | target: 'web', 21 | 22 | module: { 23 | loaders: [ 24 | { 25 | test: /\.md$/, 26 | loader: [ 27 | 'html?{"minimize":false}', 28 | path.join(__dirname, '../build_helpers/markdownLoader') 29 | ].join('!') 30 | }, 31 | { 32 | test: /\.js$/, 33 | exclude: /node_modules/, 34 | loader: 'babel-loader' 35 | }, 36 | { 37 | test: /\.css$/, 38 | loader: ExtractTextPlugin.extract( 39 | 'style-loader', 40 | [ 41 | 'css-loader', 42 | path.join(__dirname, '../build_helpers/cssTransformLoader') 43 | ].join('!') 44 | ) 45 | }, 46 | { 47 | test: /\.less$/, 48 | loader: ExtractTextPlugin.extract( 49 | 'style-loader', 50 | 'css-loader!less-loader' 51 | ) 52 | }, 53 | { 54 | test: /\.png$/, 55 | loader: 'file-loader', 56 | query: { mimetype: 'image/png', name: 'images/[name]-[hash].[ext]' } 57 | } 58 | ] 59 | }, 60 | 61 | resolve: { 62 | alias: { 63 | 'fixed-data-table/css': path.join(__dirname, '../src/css'), 64 | 'fixed-data-table': path.join(__dirname, '../src/FixedDataTableRoot') 65 | } 66 | }, 67 | 68 | plugins: [ 69 | new ExtractTextPlugin( 70 | isDev ? '[name].css' : '[name]-[hash].css' 71 | ), 72 | new webpack.optimize.OccurenceOrderPlugin(), 73 | new webpack.DefinePlugin({ 74 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), 75 | // 'process.env.NODE_ENV': JSON.stringify('production'), 76 | '__DEV__': JSON.stringify(isDev || true) 77 | }), 78 | resolvers.resolveHasteDefines, 79 | ] 80 | }; 81 | 82 | if (process.env.NODE_ENV === 'production') { 83 | module.exports.plugins.push( 84 | new webpack.optimize.UglifyJsPlugin({ 85 | compressor: { 86 | warnings: false 87 | } 88 | }) 89 | ); 90 | } 91 | -------------------------------------------------------------------------------- /src/css/layout/ScrollbarLayout.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule ScrollbarLayout 10 | */ 11 | 12 | .ScrollbarLayout/main { 13 | box-sizing: border-box; 14 | outline: none; 15 | overflow: hidden; 16 | position: absolute; 17 | transition-duration: 250ms; 18 | transition-timing-function: ease; 19 | user-select: none; 20 | } 21 | 22 | .ScrollbarLayout/mainVertical { 23 | bottom: 0; 24 | right: 0; 25 | top: 0; 26 | transition-property: background-color width; 27 | width: var(scrollbar-size); 28 | } 29 | 30 | .ScrollbarLayout/mainVertical.public/Scrollbar/mainActive, 31 | .ScrollbarLayout/mainVertical:hover { 32 | width: var(scrollbar-size-large); 33 | } 34 | 35 | .ScrollbarLayout/mainHorizontal { 36 | bottom: 0; 37 | height: var(scrollbar-size); 38 | left: 0; 39 | transition-property: background-color height; 40 | } 41 | 42 | /* Touching the scroll-track directly makes the scroll-track bolder */ 43 | .ScrollbarLayout/mainHorizontal.public/Scrollbar/mainActive, 44 | .ScrollbarLayout/mainHorizontal:hover { 45 | height: var(scrollbar-size-large); 46 | } 47 | 48 | .ScrollbarLayout/face { 49 | left: 0; 50 | overflow: hidden; 51 | position: absolute; 52 | z-index: 1; 53 | } 54 | 55 | /** 56 | * This selector renders the "nub" of the scrollface. The nub must 57 | * be rendered as pseudo-element so that it won't receive any UI events then 58 | * we can get the correct `event.offsetX` and `event.offsetY` from the 59 | * scrollface element while dragging it. 60 | */ 61 | .ScrollbarLayout/face:after { 62 | border-radius: var(scrollbar-face-radius); 63 | content: ''; 64 | display: block; 65 | position: absolute; 66 | transition: background-color 250ms ease; 67 | } 68 | 69 | .ScrollbarLayout/faceHorizontal { 70 | bottom: 0; 71 | left: 0; 72 | top: 0; 73 | } 74 | 75 | .ScrollbarLayout/faceHorizontal:after { 76 | bottom: var(scrollbar-face-margin); 77 | left: 0; 78 | top: var(scrollbar-face-margin); 79 | width: 100%; 80 | } 81 | 82 | .ScrollbarLayout/faceVertical { 83 | left: 0; 84 | right: 0; 85 | top: 0; 86 | } 87 | 88 | .ScrollbarLayout/faceVertical:after { 89 | height: 100%; 90 | left: var(scrollbar-face-margin); 91 | right: var(scrollbar-face-margin); 92 | top: 0; 93 | } 94 | -------------------------------------------------------------------------------- /src/stubs/react/ReactComponentWithPureRenderMixin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule ReactComponentWithPureRenderMixin 10 | */ 11 | 12 | 'use strict'; 13 | 14 | /** 15 | * Performs equality by iterating through keys on an object and returning 16 | * false when any key has values which are not strictly equal between 17 | * objA and objB. Returns true when the values of all keys are strictly equal. 18 | * 19 | * @return {boolean} 20 | */ 21 | function shallowEqual(objA, objB) { 22 | if (objA === objB) { 23 | return true; 24 | } 25 | var key; 26 | // Test for A's keys different from B. 27 | for (key in objA) { 28 | if (objA.hasOwnProperty(key) && 29 | (!objB.hasOwnProperty(key) || objA[key] !== objB[key])) { 30 | return false; 31 | } 32 | } 33 | // Test for B's keys missing from A. 34 | for (key in objB) { 35 | if (objB.hasOwnProperty(key) && !objA.hasOwnProperty(key)) { 36 | return false; 37 | } 38 | } 39 | return true; 40 | } 41 | 42 | /** 43 | * If your React component's render function is "pure", e.g. it will render the 44 | * same result given the same props and state, provide this Mixin for a 45 | * considerable performance boost. 46 | * 47 | * Most React components have pure render functions. 48 | * 49 | * Example: 50 | * 51 | * var ReactComponentWithPureRenderMixin = 52 | * require('ReactComponentWithPureRenderMixin'); 53 | * React.createClass({ 54 | * mixins: [ReactComponentWithPureRenderMixin], 55 | * 56 | * render: function() { 57 | * return
foo
; 58 | * } 59 | * }); 60 | * 61 | * Note: This only checks shallow equality for props and state. If these contain 62 | * complex data structures this mixin may have false-negatives for deeper 63 | * differences. Only mixin to components which have simple props and state, or 64 | * use `forceUpdate()` when you know deep data structures have changed. 65 | */ 66 | var ReactComponentWithPureRenderMixin = { 67 | shouldComponentUpdate: function(nextProps, nextState) { 68 | return !shallowEqual(this.props, nextProps) || 69 | !shallowEqual(this.state, nextState); 70 | } 71 | }; 72 | 73 | module.exports = ReactComponentWithPureRenderMixin; 74 | -------------------------------------------------------------------------------- /examples/old/ColumnGroupsExample.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file provided by Facebook is for non-commercial testing and evaluation 3 | * purposes only. Facebook reserves all rights not expressly granted. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 7 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8 | * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 9 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 10 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | "use strict"; 14 | 15 | var FakeObjectDataListStore = require('../helpers/FakeObjectDataListStore'); 16 | var FixedDataTable = require('fixed-data-table'); 17 | var React = require('react'); 18 | 19 | var Column = FixedDataTable.Column; 20 | var Table = FixedDataTable.Table; 21 | var ColumnGroup = FixedDataTable.ColumnGroup; 22 | 23 | var ROWS = 1000000; 24 | 25 | var ColumnGroupsExample = React.createClass({ 26 | getInitialState() { 27 | return { 28 | dataList: new FakeObjectDataListStore(ROWS) 29 | } 30 | }, 31 | 32 | _rowGetter(index){ 33 | return this.state.dataList.getObjectAt(index); 34 | }, 35 | 36 | render() { 37 | return ( 38 | 47 | 50 | 56 | 62 | 63 | 64 | 70 | 76 | 77 |
78 | ); 79 | } 80 | }); 81 | 82 | module.exports = ColumnGroupsExample; 83 | -------------------------------------------------------------------------------- /examples/old/FlexGrowExample.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file provided by Facebook is for non-commercial testing and evaluation 3 | * purposes only. Facebook reserves all rights not expressly granted. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 7 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8 | * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 9 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 10 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | "use strict"; 14 | 15 | var FakeObjectDataListStore = require('../helpers/FakeObjectDataListStore'); 16 | var FixedDataTable = require('fixed-data-table'); 17 | var React = require('react'); 18 | 19 | var Column = FixedDataTable.Column; 20 | var Table = FixedDataTable.Table; 21 | 22 | var ROWS = 1000000; 23 | 24 | function colorizeText(/*string*/ str, key, data, index) { 25 | var val, n = 0; 26 | return str.split('').map((letter) => { 27 | val = index * 70 + n++; 28 | var color = 'hsl(' + val + ', 100%, 50%)'; 29 | return {letter}; 30 | }); 31 | } 32 | 33 | var FlexGrowExample = React.createClass({ 34 | getInitialState() { 35 | return { 36 | dataList: new FakeObjectDataListStore(ROWS) 37 | }; 38 | }, 39 | 40 | _rowGetter(index) { 41 | return this.state.dataList.getObjectAt(index); 42 | }, 43 | 44 | render() { 45 | return ( 46 | 54 | 60 | 67 | 73 | 78 |
79 | ); 80 | } 81 | }); 82 | 83 | module.exports = FlexGrowExample; 84 | -------------------------------------------------------------------------------- /dist/fixed-data-table-style.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * FixedDataTable v0.6.0 3 | * 4 | * Copyright (c) 2015, Facebook, Inc. 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. An additional grant 9 | * of patent rights can be found in the PATENTS file in the same directory. 10 | */ 11 | 12 | .public_Scrollbar_main.public_Scrollbar_mainActive,.public_Scrollbar_main:hover{background-color:rgba(255,255,255,.8)}.public_Scrollbar_mainOpaque,.public_Scrollbar_mainOpaque.public_Scrollbar_mainActive,.public_Scrollbar_mainOpaque:hover{background-color:#fff}.public_Scrollbar_face:after{background-color:#c2c2c2}.public_Scrollbar_main:hover .public_Scrollbar_face:after,.public_Scrollbar_mainActive .public_Scrollbar_face:after,.public_Scrollbar_faceActive:after{background-color:#7d7d7d}.public_fixedDataTable_main,.public_fixedDataTable_header,.public_fixedDataTable_hasBottomBorder{border-color:#d3d3d3}.public_fixedDataTable_header .public_fixedDataTableCell_main{font-weight:700}.public_fixedDataTable_header,.public_fixedDataTable_header .public_fixedDataTableCell_main{background-color:#f6f7f8;background-image:-webkit-linear-gradient(#fff,#efefef);background-image:linear-gradient(#fff,#efefef)}.public_fixedDataTable_footer .public_fixedDataTableCell_main{background-color:#f6f7f8;border-color:#d3d3d3}.public_fixedDataTable_topShadow{background:0 0 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAECAYAAABP2FU6AAAAF0lEQVR4AWPUkNeSBhHCjJoK2twgFisAFagCCp3pJlAAAAAASUVORK5CYII=) repeat-x}.public_fixedDataTable_bottomShadow{background:0 0 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAECAYAAABP2FU6AAAAHElEQVQI12MwNjZmZdAT1+Nm0JDWEGZQk1GTBgAWkwIeAEp52AAAAABJRU5ErkJggg==) repeat-x}.public_fixedDataTable_horizontalScrollbar .public_Scrollbar_mainHorizontal{background-color:#fff}.public_fixedDataTableCell_main{background-color:#fff;border-color:#d3d3d3}.public_fixedDataTableCell_highlighted{background-color:#f4f4f4}.public_fixedDataTableCell_cellContent{padding:8px}.public_fixedDataTableCell_columnResizerKnob{background-color:#0284ff}.public_fixedDataTableColumnResizerLine_main{border-color:#0284ff}.public_fixedDataTableRow_main{background-color:#fff}.public_fixedDataTableRow_highlighted,.public_fixedDataTableRow_highlighted .public_fixedDataTableCell_main{background-color:#f6f7f8}.public_fixedDataTableRow_fixedColumnsDivider{border-color:#d3d3d3}.public_fixedDataTableRow_columnsShadow{background:0 0 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABCAYAAAD5PA/NAAAAFklEQVQIHWPSkNeSBmJhTQVtbiDNCgASagIIuJX8OgAAAABJRU5ErkJggg==) repeat-y} -------------------------------------------------------------------------------- /site/examples/TouchExampleWrapper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file provided by Facebook is for non-commercial testing and evaluation 3 | * purposes only. Facebook reserves all rights not expressly granted. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 7 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8 | * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 9 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 10 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | "use strict"; 14 | 15 | var React = require('react'); 16 | var ZyngaScroller = require('../ZyngaScroller'); 17 | var TouchableArea = require('./TouchableArea'); 18 | 19 | var PropTypes = React.PropTypes; 20 | 21 | function isTouchDevice() { 22 | return 'ontouchstart' in document.documentElement // works on most browsers 23 | || 'onmsgesturechange' in window; // works on ie10 24 | }; 25 | 26 | var ExampleTouchWrapper = React.createClass({ 27 | propTypes: { 28 | tableWidth: PropTypes.number.isRequired, 29 | tableHeight: PropTypes.number.isRequired, 30 | }, 31 | 32 | getInitialState() { 33 | return { 34 | left: 0, 35 | top: 0, 36 | contentHeight: 0, 37 | contentWidth: 0, 38 | }; 39 | }, 40 | 41 | componentWillMount() { 42 | this.scroller = new ZyngaScroller(this._handleScroll); 43 | }, 44 | 45 | render() { 46 | if (!isTouchDevice()) { 47 | return React.cloneElement(this.props.children, { 48 | height: this.props.tableHeight, 49 | width: this.props.tableWidth, 50 | }); 51 | } 52 | 53 | var example = React.cloneElement(this.props.children, { 54 | onContentHeightChange: this._onContentHeightChange, 55 | scrollLeft: this.state.left, 56 | scrollTop: this.state.top, 57 | height: this.props.tableHeight, 58 | width: this.props.tableWidth, 59 | overflowX: 'hidden', 60 | overflowY: 'hidden', 61 | }); 62 | 63 | return ( 64 | 65 | {example} 66 | 67 | ); 68 | }, 69 | 70 | _onContentHeightChange(contentHeight) { 71 | this.scroller.setDimensions( 72 | this.props.tableWidth, 73 | this.props.tableHeight, 74 | Math.max(600, this.props.tableWidth), 75 | contentHeight 76 | ); 77 | }, 78 | 79 | _handleScroll(left, top) { 80 | this.setState({ 81 | left: left, 82 | top: top 83 | }); 84 | } 85 | }); 86 | 87 | module.exports = ExampleTouchWrapper; 88 | -------------------------------------------------------------------------------- /src/vendor_upstream/stubs/EventListener.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule EventListener 10 | * @typechecks 11 | */ 12 | 13 | var emptyFunction = require('emptyFunction'); 14 | 15 | /** 16 | * Upstream version of event listener. Does not take into account specific 17 | * nature of platform. 18 | */ 19 | var EventListener = { 20 | /** 21 | * Listen to DOM events during the bubble phase. 22 | * 23 | * @param {DOMEventTarget} target DOM element to register listener on. 24 | * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. 25 | * @param {function} callback Callback function. 26 | * @return {object} Object with a `remove` method. 27 | */ 28 | listen: function(target, eventType, callback) { 29 | if (target.addEventListener) { 30 | target.addEventListener(eventType, callback, false); 31 | return { 32 | remove: function() { 33 | target.removeEventListener(eventType, callback, false); 34 | } 35 | }; 36 | } else if (target.attachEvent) { 37 | target.attachEvent('on' + eventType, callback); 38 | return { 39 | remove: function() { 40 | target.detachEvent('on' + eventType, callback); 41 | } 42 | }; 43 | } 44 | }, 45 | 46 | /** 47 | * Listen to DOM events during the capture phase. 48 | * 49 | * @param {DOMEventTarget} target DOM element to register listener on. 50 | * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. 51 | * @param {function} callback Callback function. 52 | * @return {object} Object with a `remove` method. 53 | */ 54 | capture: function(target, eventType, callback) { 55 | if (target.addEventListener) { 56 | target.addEventListener(eventType, callback, true); 57 | return { 58 | remove: function () { 59 | target.removeEventListener(eventType, callback, true); 60 | } 61 | }; 62 | } else { 63 | if (__DEV__) { 64 | console.error( 65 | 'Attempted to listen to events during the capture phase on a ' + 66 | 'browser that does not support the capture phase. Your application ' + 67 | 'will not receive some events.' 68 | ); 69 | } 70 | return { 71 | remove: emptyFunction 72 | }; 73 | } 74 | }, 75 | 76 | registerDefault: function() {} 77 | }; 78 | 79 | module.exports = EventListener; 80 | -------------------------------------------------------------------------------- /site/base.less: -------------------------------------------------------------------------------- 1 | @import 'variables.less'; 2 | 3 | html, body { 4 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 5 | -webkit-text-size-adjust: 100%; 6 | -ms-text-size-adjust: 100%; 7 | margin: 0; 8 | padding: 0; 9 | -webkit-font-smoothing: antialiased; 10 | color: @body-color; 11 | font-family: 'Fira Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; 12 | font-size: 16px; 13 | line-height: 1.625; 14 | } 15 | 16 | @media only screen and (max-width: 680px) { 17 | body { 18 | font-size: 14px; 19 | } 20 | } 21 | 22 | h1, h2, h3, h4, h5, h6 { 23 | color: @header-color; 24 | } 25 | 26 | a { 27 | color: @link-color; 28 | text-decoration: none; 29 | cursor: pointer; 30 | } 31 | 32 | pre, code { 33 | font-family: 'Fira Mono', Menlo, monospace; 34 | background: #F9F8F7; 35 | color: #484A4C; 36 | font-size: 0.9375em; 37 | letter-spacing: -0.015em; 38 | } 39 | 40 | code { 41 | margin: -0.05rem -0.15em; 42 | padding: 0.05rem 0.35em; 43 | } 44 | 45 | blockquote { 46 | margin: 1rem 0; 47 | padding: 0 1rem; 48 | color: #727476; 49 | border-left: solid 3px #DCDAD9; 50 | } 51 | 52 | blockquote > :first-child { 53 | margin-top: 0; 54 | } 55 | 56 | blockquote > :last-child { 57 | margin-bottom: 0; 58 | } 59 | 60 | 61 | // Markdown 62 | 63 | .codeBlock { 64 | -webkit-overflow-scrolling: touch; 65 | background: #FCFBFA; 66 | border-left: solid 3px #ECEAE9; 67 | box-sizing: border-box; 68 | display: block; 69 | font-size: 0.875em; 70 | margin: 0.5rem 0; 71 | overflow-y: scroll; 72 | padding: 0.5rem 8px 0.5rem 12px; 73 | white-space: pre; 74 | } 75 | 76 | .t.blockParams { 77 | padding-left: 2ch; 78 | } 79 | 80 | // TODO: not random colors 81 | 82 | .token.punctuation, 83 | .token.ignore, 84 | .t.interfaceDef, 85 | .t.member, 86 | .t.callSig { 87 | color: #808890; 88 | } 89 | 90 | .token.function, 91 | .token.class-name, 92 | .token.qualifier, 93 | .t.fnQualifier, 94 | .t.fnName { 95 | color: #32308E; 96 | } 97 | 98 | .token.primitive, 99 | .t.primitive { 100 | color: #922; 101 | } 102 | 103 | .token.number, 104 | .t.typeParam { 105 | color: #905; 106 | } 107 | 108 | .t.typeQualifier, 109 | .t.typeName { 110 | color: #013679; 111 | } 112 | 113 | .t.param { 114 | color: #945277; 115 | } 116 | 117 | .t.memberName { 118 | color: teal; 119 | } 120 | 121 | .token.block-keyword, 122 | .token.keyword, 123 | .t.keyword { 124 | color: #A51; 125 | } 126 | 127 | .token.string, 128 | .token.regex { 129 | color: #df5050; 130 | } 131 | 132 | .token.operator { 133 | color: #a67f59; 134 | } 135 | 136 | .token.comment { 137 | color: #998; 138 | font-style: italic; 139 | } 140 | -------------------------------------------------------------------------------- /examples/ColumnGroupsExample.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file provided by Facebook is for non-commercial testing and evaluation 3 | * purposes only. Facebook reserves all rights not expressly granted. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 7 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8 | * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 9 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 10 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | "use strict"; 14 | 15 | var ExampleImage = require('./helpers/ExampleImage'); 16 | var FakeObjectDataListStore = require('./helpers/FakeObjectDataListStore'); 17 | var FixedDataTable = require('fixed-data-table'); 18 | var React = require('react'); 19 | 20 | const {Table, Column, ColumnGroup, Cell} = FixedDataTable; 21 | 22 | const TextCell = ({rowIndex, data, col, ...props}) => ( 23 | 24 | {data.getObjectAt(rowIndex)[col]} 25 | 26 | ); 27 | 28 | class ColumnGroupsExample extends React.Component { 29 | constructor(props) { 30 | super(props); 31 | 32 | this.state = { 33 | dataList: new FakeObjectDataListStore(1000000), 34 | }; 35 | } 36 | 37 | render() { 38 | var {dataList} = this.state; 39 | 40 | return ( 41 | 49 | Name}> 52 | First Name} 55 | cell={} 56 | width={150} 57 | /> 58 | Last Name} 61 | cell={} 62 | width={150} 63 | /> 64 | 65 | About}> 67 | Company} 69 | cell={} 70 | flexGrow={1} 71 | width={150} 72 | /> 73 | Sentence} 75 | cell={} 76 | flexGrow={1} 77 | width={150} 78 | /> 79 | 80 |
81 | ); 82 | } 83 | } 84 | 85 | module.exports = ColumnGroupsExample; 86 | -------------------------------------------------------------------------------- /examples/FlexGrowExample.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file provided by Facebook is for non-commercial testing and evaluation 3 | * purposes only. Facebook reserves all rights not expressly granted. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 7 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8 | * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 9 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 10 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | "use strict"; 14 | 15 | var FakeObjectDataListStore = require('./helpers/FakeObjectDataListStore'); 16 | var FixedDataTable = require('fixed-data-table'); 17 | var React = require('react'); 18 | 19 | const {Table, Column, Cell} = FixedDataTable; 20 | 21 | function colorizeText(str, index) { 22 | var val, n = 0; 23 | return str.split('').map((letter) => { 24 | val = index * 70 + n++; 25 | var color = 'hsl(' + val + ', 100%, 50%)'; 26 | return {letter}; 27 | }); 28 | } 29 | 30 | 31 | const TextCell = ({rowIndex, data, col, ...props}) => ( 32 | 33 | {data.getObjectAt(rowIndex)[col]} 34 | 35 | ); 36 | 37 | const ColoredTextCell = ({rowIndex, data, col, ...props}) => ( 38 | 39 | {colorizeText(data.getObjectAt(rowIndex)[col], rowIndex)} 40 | 41 | ); 42 | 43 | class FlexGrowExample extends React.Component { 44 | constructor(props) { 45 | super(props); 46 | 47 | this.state = { 48 | dataList: new FakeObjectDataListStore(1000000), 49 | }; 50 | } 51 | 52 | render() { 53 | var {dataList} = this.state; 54 | return ( 55 | 62 | First Name} 64 | cell={} 65 | fixed={true} 66 | width={100} 67 | /> 68 | Sentence! (flexGrow greediness=2)} 70 | cell={} 71 | flexGrow={2} 72 | width={200} 73 | /> 74 | Company (flexGrow greediness=1)} 76 | cell={} 77 | flexGrow={1} 78 | width={200} 79 | /> 80 | Last Name} 83 | cell={} 84 | /> 85 |
86 | ); 87 | } 88 | } 89 | 90 | module.exports = FlexGrowExample; 91 | -------------------------------------------------------------------------------- /src/FixedDataTableCellDefault.react.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule FixedDataTableCellDefault.react 10 | * @typechecks 11 | */ 12 | 13 | var React = require('React'); 14 | 15 | var cx = require('cx'); 16 | var joinClasses = require('joinClasses'); 17 | 18 | var {PropTypes} = React; 19 | 20 | /** 21 | * Component that handles default cell layout and styling. 22 | * 23 | * All props unless specified below will be set onto the top level `div` 24 | * rendered by the cell. 25 | * 26 | * Example usage via from a `Column`: 27 | * ``` 28 | * const MyColumn = ( 29 | * ( 31 | * 35 | * Cell number: {rowIndex} 36 | * 37 | * )} 38 | * width={100} 39 | * /> 40 | * ); 41 | * ``` 42 | */ 43 | var FixedDataTableCellDefault = React.createClass({ 44 | propTypes: { 45 | 46 | /** 47 | * Outer height of the cell. 48 | */ 49 | height: PropTypes.number, 50 | 51 | /** 52 | * Outer width of the cell. 53 | */ 54 | width: PropTypes.number, 55 | 56 | /** 57 | * Optional prop that if specified on the `Column` will be passed to the 58 | * cell. It can be used to uniquely identify which column is the cell is in. 59 | */ 60 | columnKey: PropTypes.oneOfType([ 61 | PropTypes.string, 62 | PropTypes.number, 63 | ]), 64 | }, 65 | 66 | render() { 67 | var {height, width, style, className, children, ...props} = this.props; 68 | 69 | var innerStyle = { 70 | height, 71 | width, 72 | ...style, 73 | }; 74 | 75 | return ( 76 |
84 |
89 |
94 |
95 | {children} 96 |
97 |
98 |
99 |
100 | ); 101 | }, 102 | }); 103 | 104 | module.exports = FixedDataTableCellDefault; 105 | -------------------------------------------------------------------------------- /examples/old/ResizeExample.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file provided by Facebook is for non-commercial testing and evaluation 3 | * purposes only. Facebook reserves all rights not expressly granted. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 7 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8 | * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 9 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 10 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | "use strict"; 14 | 15 | var FakeObjectDataListStore = require('../helpers/FakeObjectDataListStore'); 16 | var FixedDataTable = require('fixed-data-table'); 17 | var React = require('react'); 18 | 19 | var Column = FixedDataTable.Column; 20 | var Table = FixedDataTable.Table; 21 | 22 | var ROWS = 1000000; 23 | 24 | var columnWidths = { 25 | firstName: 240, 26 | lastName: 150, 27 | sentence: 140, 28 | companyName: 60, 29 | }; 30 | var isColumnResizing; 31 | 32 | var ResizeExample = React.createClass({ 33 | getInitialState() { 34 | return { 35 | dataList: new FakeObjectDataListStore(ROWS), 36 | columnWidths: columnWidths 37 | } 38 | }, 39 | 40 | _rowGetter(index) { 41 | return this.state.dataList.getObjectAt(index); 42 | }, 43 | 44 | _onColumnResizeEndCallback(newColumnWidth, dataKey) { 45 | var columnWidths = this.state.columnWidths; 46 | columnWidths[dataKey] = newColumnWidth; 47 | isColumnResizing = false; 48 | this.setState({ 49 | columnWidths 50 | }) 51 | }, 52 | 53 | render() { 54 | return ( 55 | 65 | 72 | 80 | 86 | 92 |
93 | ); 94 | } 95 | }); 96 | 97 | module.exports = ResizeExample; 98 | -------------------------------------------------------------------------------- /site/Constants.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var EXAMPLES_LOCATION_BASE = 'https://github.com/facebook/fixed-data-table/blob/master/examples/'; 4 | 5 | exports.OtherPages = { 6 | HOME: {location: 'index.html', title: 'Home'}, 7 | }; 8 | 9 | exports.DocsPages = { 10 | DOCS: { 11 | groupTitle: 'Guides', 12 | GETTING_STARTED: {location: 'getting-started.html', title: 'Getting Started'}, 13 | V6_MIGRATION: {location: 'v6-migration.html', title: 'v0.6 API Migration'}, 14 | }, 15 | API: { 16 | groupTitle: 'API', 17 | TABLE_API: {location: 'api-table.html', title: 'Table'}, 18 | COLUMN_API: {location: 'api-column.html', title: 'Column'}, 19 | COLUMNGROUP_API: {location: 'api-columngroup.html', title: 'Column Group'}, 20 | CELL_API: {location: 'api-cell.html', title: 'Cell'}, 21 | }, 22 | API_V5: { 23 | groupTitle: 'API - v0.5', 24 | TABLE_API: {location: 'api-table-v0.5.html', title: 'Table'}, 25 | COLUMN_API: {location: 'api-column-v0.5.html', title: 'Column'}, 26 | COLUMNGROUP_API: {location: 'api-columngroup-v0.5.html', title: 'Column Group'}, 27 | } 28 | }; 29 | 30 | exports.ExamplePages = { 31 | OBJECT_DATA_EXAMPLE: { 32 | location: 'example-object-data.html', 33 | file: EXAMPLES_LOCATION_BASE + 'ObjectDataExample.js', 34 | title: 'With JSON Data', 35 | description: 'A basic table example with two fixed columns, fed in some JSON data.', 36 | }, 37 | FLEXGROW_EXAMPLE: { 38 | location: 'example-flexgrow.html', 39 | file: EXAMPLES_LOCATION_BASE + 'FlexGrowExample.js', 40 | title: 'Fluid column widths', 41 | description: 'An example of a table with flexible column widths. Here, the middle two columns stretch to fill all remaining space if the table is wider than the sum of all the columns\'s default widths. Note that one column grows twice as greedily as the other, as specified by the flexGrow param.', 42 | }, 43 | RESIZE_EXAMPLE: { 44 | location: 'example-resize.html', 45 | file: EXAMPLES_LOCATION_BASE + 'ResizeExample.js', 46 | title: 'Resizable columns', 47 | description: 'Table with drag and drop column resizing and a dummy "store" for persistence. The Last Name column demonstrates the ability to constrain to both a min- and max-width.', 48 | }, 49 | COLUMN_GROUPS_EXAMPLE: { 50 | location: 'example-column-groups.html', 51 | file: EXAMPLES_LOCATION_BASE + 'ColumnGroupsExample.js', 52 | title: 'Column Groups', 53 | description: 'Table with column groupings.', 54 | }, 55 | FILTER_EXAMPLE: { 56 | location: 'example-filter.html', 57 | file: EXAMPLES_LOCATION_BASE + 'FilterExample.js', 58 | title: 'Client-side Filter', 59 | description: 'A table example that is filterable by column. In this example, by first name.', 60 | }, 61 | SORT_EXAMPLE: { 62 | location: 'example-sort.html', 63 | file: EXAMPLES_LOCATION_BASE + 'SortExample.js', 64 | title: 'Client-side Sort', 65 | description: 'A table example that is sortable by column.' 66 | }, 67 | }; 68 | 69 | exports.DOCS_DEFAULT = exports.DocsPages.DOCS.GETTING_STARTED; 70 | exports.EXAMPLES_DEFAULT = exports.ExamplePages.OBJECT_DATA_EXAMPLE; 71 | exports.ALL_PAGES = [ 72 | exports.OtherPages, 73 | exports.DocsPages, 74 | exports.ExamplePages, 75 | ]; 76 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var resolvers = require('./build_helpers/resolvers'); 3 | var path = require('path'); 4 | var glob = require('glob'); 5 | var ExtractTextPlugin = require('extract-text-webpack-plugin'); 6 | var packageJSON = require('./package.json'); 7 | 8 | var banner = ( 9 | '/**\n' + 10 | ' * FixedDataTable v' + packageJSON.version + ' \n' + 11 | ' *\n' + 12 | ' * Copyright (c) 2015, Facebook, Inc.\n' + 13 | ' * All rights reserved.\n' + 14 | ' *\n' + 15 | ' * This source code is licensed under the BSD-style license found in the\n' + 16 | ' * LICENSE file in the root directory of this source tree. An additional grant\n' + 17 | ' * of patent rights can be found in the PATENTS file in the same directory.\n' + 18 | ' */\n' 19 | ); 20 | 21 | var plugins = [ 22 | new ExtractTextPlugin('[name].css'), 23 | new webpack.DefinePlugin({ 24 | '__DEV__': JSON.stringify(process.env.NODE_ENV !== 'production') 25 | }), 26 | resolvers.resolveHasteDefines, 27 | ]; 28 | 29 | var entry = {}; 30 | var baseEntryPoints = glob.sync( 31 | path.join(__dirname, './src/css/layout/*.css') 32 | ); 33 | 34 | var styleEntryPoints = glob.sync( 35 | path.join(__dirname, './src/css/style/*.css') 36 | ); 37 | 38 | var mainEntryPoints = glob.sync( 39 | path.join(__dirname, './src/**/*.css') 40 | ); 41 | mainEntryPoints.push('./src/FixedDataTableRoot.js'); 42 | 43 | if (process.env.COMPRESS) { 44 | plugins.push( 45 | new webpack.optimize.UglifyJsPlugin({ 46 | compressor: { 47 | warnings: false 48 | }, 49 | output: {comments: false} 50 | }) 51 | ); 52 | entry['fixed-data-table-base.min'] = baseEntryPoints; 53 | entry['fixed-data-table-style.min'] = styleEntryPoints; 54 | entry['fixed-data-table.min'] = mainEntryPoints; 55 | } else { 56 | entry['fixed-data-table-base'] = baseEntryPoints; 57 | entry['fixed-data-table-style'] = styleEntryPoints; 58 | entry['fixed-data-table'] = mainEntryPoints; 59 | } 60 | 61 | plugins.push( 62 | new webpack.BannerPlugin(banner, {raw: true}) 63 | ); 64 | 65 | module.exports = { 66 | module: { 67 | loaders: [ 68 | { 69 | test: /\.js$/, 70 | exclude: /node_modules/, 71 | loader: 'babel-loader' 72 | }, 73 | { 74 | test: /\.css$/, 75 | loader: ExtractTextPlugin.extract( 76 | 'style-loader', 77 | [ 78 | 'css-loader', 79 | path.join(__dirname, './build_helpers/cssTransformLoader.js') 80 | ].join('!') 81 | ) 82 | }, 83 | ], 84 | }, 85 | 86 | entry: entry, 87 | 88 | output: { 89 | library: 'FixedDataTable', 90 | libraryTarget: 'umd', 91 | path: 'dist', 92 | filename: '[name].js', 93 | }, 94 | 95 | externals: { 96 | react: { 97 | root: 'React', 98 | commonjs: 'react', 99 | commonjs2: 'react', 100 | amd: 'react', 101 | }, 102 | 'react-dom': { 103 | root: 'ReactDOM', 104 | commonjs: 'react-dom', 105 | commonjs2: 'react-dom', 106 | amd: 'react-dom', 107 | }, 108 | }, 109 | 110 | node: { 111 | Buffer: false 112 | }, 113 | 114 | plugins: plugins 115 | }; 116 | -------------------------------------------------------------------------------- /examples/old/ObjectDataExample.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file provided by Facebook is for non-commercial testing and evaluation 3 | * purposes only. Facebook reserves all rights not expressly granted. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 7 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8 | * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 9 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 10 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | "use strict"; 14 | 15 | var ExampleImage = require('../helpers/ExampleImage'); 16 | var FakeObjectDataListStore = require('../helpers/FakeObjectDataListStore'); 17 | var FixedDataTable = require('fixed-data-table'); 18 | var React = require('react'); 19 | 20 | var Column = FixedDataTable.Column; 21 | var PropTypes = React.PropTypes; 22 | var Table = FixedDataTable.Table; 23 | 24 | var ROWS = 1000000; 25 | 26 | function renderImage(/*string*/ cellData) { 27 | return ; 28 | } 29 | 30 | function renderLink(/*string*/ cellData) { 31 | return {cellData}; 32 | } 33 | 34 | function renderDate(/*object*/ cellData) { 35 | return {cellData.toLocaleString()}; 36 | } 37 | 38 | var ObjectDataExample = React.createClass({ 39 | getInitialState() { 40 | return { 41 | dataList: new FakeObjectDataListStore(ROWS) 42 | } 43 | }, 44 | 45 | _rowGetter(index){ 46 | return this.state.dataList.getObjectAt(index); 47 | }, 48 | 49 | render() { 50 | return ( 51 | 59 | 66 | 72 | 78 | 83 | 88 | 93 | 99 | 105 |
106 | ); 107 | }, 108 | }); 109 | 110 | module.exports = ObjectDataExample; 111 | -------------------------------------------------------------------------------- /examples/ResizeExample.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file provided by Facebook is for non-commercial testing and evaluation 3 | * purposes only. Facebook reserves all rights not expressly granted. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 7 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8 | * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 9 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 10 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | "use strict"; 14 | 15 | var FakeObjectDataListStore = require('./helpers/FakeObjectDataListStore'); 16 | var FixedDataTable = require('fixed-data-table'); 17 | var React = require('react'); 18 | 19 | const {Table, Column, Cell} = FixedDataTable; 20 | 21 | const TextCell = ({rowIndex, data, columnKey, ...props}) => ( 22 | 23 | {data.getObjectAt(rowIndex)[columnKey]} 24 | 25 | ); 26 | 27 | class ResizeExample extends React.Component { 28 | constructor(props) { 29 | super(props); 30 | 31 | this.state = { 32 | dataList: new FakeObjectDataListStore(1000000), 33 | columnWidths: { 34 | firstName: 240, 35 | lastName: 150, 36 | sentence: 140, 37 | companyName: 60, 38 | }, 39 | }; 40 | 41 | this._onColumnResizeEndCallback = this._onColumnResizeEndCallback.bind(this); 42 | } 43 | 44 | _onColumnResizeEndCallback(newColumnWidth, columnKey) { 45 | this.setState(({columnWidths}) => ({ 46 | columnWidths: { 47 | ...columnWidths, 48 | [columnKey]: newColumnWidth, 49 | } 50 | })); 51 | } 52 | 53 | render() { 54 | var {dataList, columnWidths} = this.state; 55 | return ( 56 | 65 | First Name} 68 | cell={} 69 | fixed={true} 70 | width={columnWidths.firstName} 71 | isResizable={true} 72 | /> 73 | Last Name (min/max constrained)} 76 | cell={} 77 | width={columnWidths.lastName} 78 | isResizable={true} 79 | minWidth={70} 80 | maxWidth={170} 81 | /> 82 | Company} 85 | cell={} 86 | width={columnWidths.companyName} 87 | isResizable={true} 88 | /> 89 | Sentence} 92 | cell={} 93 | width={columnWidths.sentence} 94 | isResizable={true} 95 | /> 96 |
97 | ); 98 | } 99 | } 100 | 101 | module.exports = ResizeExample; 102 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Fixed Data Tables for React 2 | ==================================== 3 | 4 | FixedDataTable is a React component for building and presenting data in a flexible, powerful way. It supports standard table features, like headers, columns, rows, header groupings, and both fixed-position and scrolling columns. 5 | 6 | The table was designed to handle thousands of rows of data without sacrificing performance. Scrolling smoothly is a first-class goal of FixedDataTable and it's architected in a way to allow for flexibility and extensibility. 7 | 8 | Features of FixedDataTable: 9 | * Fixed headers and footer 10 | * Both fixed and scrollable columns 11 | * Handling huge amounts of data 12 | * Variable row heights (with adaptive scroll positions) 13 | * Column resizing 14 | * Performant scrolling 15 | * Customizable styling 16 | * Jumping to a row or column 17 | * Controlled scroll API allows touch support 18 | 19 | Things the FixedDataTable **doesn't** do: 20 | * FixedDataTable does not provide a layout reflow mechanism or calculate content layout information such as width and height of the cell contents. The developer has to provide the layout information to the table instead. 21 | * FixedDataTable does not handle sorting of data. Instead it allows the developer to supply data getters that can be sort-, filter-, or tail-loading-aware. 22 | * FixedDataTable does not fetch the data (see above) 23 | 24 | Getting started 25 | --------------- 26 | 27 | Install `fixed-data-table` using npm. 28 | 29 | ```shell 30 | npm install fixed-data-table 31 | ``` 32 | Add the default stylesheet `dist/fixed-data-table.css`, then import it into any module. 33 | 34 | ### Basic Example 35 | 36 | ```javascript 37 | import React from 'react'; 38 | import ReactDOM from 'react-dom'; 39 | import {Table, Column, Cell} from 'fixed-data-table'; 40 | 41 | // Table data as a list of array. 42 | const rows = [ 43 | ['a1', 'b1', 'c1'], 44 | ['a2', 'b2', 'c2'], 45 | ['a3', 'b3', 'c3'], 46 | // .... and more 47 | ]; 48 | 49 | // Render your table 50 | ReactDOM.render( 51 | 57 | Col 1} 59 | cell={Column 1 static content} 60 | width={2000} 61 | /> 62 | Col 2} 64 | cell={} 65 | width={1000} 66 | /> 67 | Col 3} 69 | cell={({rowIndex, ...props}) => ( 70 | 71 | Data for column 3: {rows[rowIndex][2]} 72 | 73 | )} 74 | width={2000} 75 | /> 76 |
, 77 | document.getElementById('example') 78 | ); 79 | ``` 80 | 81 | Contributions 82 | ------------ 83 | 84 | Use [GitHub issues](https://github.com/facebook/fixed-data-table/issues) for requests. 85 | 86 | We actively welcome pull requests; learn how to [contribute](https://github.com/facebook/fixed-data-table/blob/master/CONTRIBUTING.md). 87 | 88 | 89 | Changelog 90 | --------- 91 | 92 | Changes are tracked as [GitHub releases](https://github.com/facebook/fixed-data-table/releases). 93 | 94 | 95 | License 96 | ------- 97 | 98 | `FixedDataTable` is [BSD-licensed](https://github.com/facebook/fixed-data-table/blob/master/LICENSE). We also provide an additional [patent grant](https://github.com/facebook/fixed-data-table/blob/master/PATENTS). 99 | -------------------------------------------------------------------------------- /src/vendor_upstream/dom/ReactWheelHandler.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * This is utility that hanlds onWheel events and calls provided wheel 10 | * callback with correct frame rate. 11 | * 12 | * @providesModule ReactWheelHandler 13 | * @typechecks 14 | */ 15 | 16 | 'use strict'; 17 | 18 | var emptyFunction = require('emptyFunction'); 19 | var normalizeWheel = require('normalizeWheel'); 20 | var requestAnimationFramePolyfill = require('requestAnimationFramePolyfill'); 21 | 22 | class ReactWheelHandler { 23 | /** 24 | * onWheel is the callback that will be called with right frame rate if 25 | * any wheel events happened 26 | * onWheel should is to be called with two arguments: deltaX and deltaY in 27 | * this order 28 | */ 29 | constructor( 30 | /*function*/ onWheel, 31 | /*boolean|function*/ handleScrollX, 32 | /*boolean|function*/ handleScrollY, 33 | /*?boolean|?function*/ stopPropagation 34 | ) { 35 | this._animationFrameID = null; 36 | this._deltaX = 0; 37 | this._deltaY = 0; 38 | this._didWheel = this._didWheel.bind(this); 39 | if (typeof handleScrollX !== 'function') { 40 | handleScrollX = handleScrollX ? 41 | emptyFunction.thatReturnsTrue : 42 | emptyFunction.thatReturnsFalse; 43 | } 44 | 45 | if (typeof handleScrollY !== 'function') { 46 | handleScrollY = handleScrollY ? 47 | emptyFunction.thatReturnsTrue : 48 | emptyFunction.thatReturnsFalse; 49 | } 50 | 51 | if (typeof stopPropagation !== 'function') { 52 | stopPropagation = stopPropagation ? 53 | emptyFunction.thatReturnsTrue : 54 | emptyFunction.thatReturnsFalse; 55 | } 56 | 57 | this._handleScrollX = handleScrollX; 58 | this._handleScrollY = handleScrollY; 59 | this._stopPropagation = stopPropagation; 60 | this._onWheelCallback = onWheel; 61 | this.onWheel = this.onWheel.bind(this); 62 | } 63 | 64 | onWheel(/*object*/ event) { 65 | var normalizedEvent = normalizeWheel(event); 66 | var deltaX = this._deltaX + normalizedEvent.pixelX; 67 | var deltaY = this._deltaY + normalizedEvent.pixelY; 68 | var handleScrollX = this._handleScrollX(deltaX, deltaY); 69 | var handleScrollY = this._handleScrollY(deltaY, deltaX); 70 | if (!handleScrollX && !handleScrollY) { 71 | return; 72 | } 73 | 74 | this._deltaX += handleScrollX ? normalizedEvent.pixelX : 0; 75 | this._deltaY += handleScrollY ? normalizedEvent.pixelY : 0; 76 | event.preventDefault(); 77 | 78 | var changed; 79 | if (this._deltaX !== 0 || this._deltaY !== 0) { 80 | if (this._stopPropagation()) { 81 | event.stopPropagation(); 82 | } 83 | changed = true; 84 | } 85 | 86 | if (changed === true && this._animationFrameID === null) { 87 | this._animationFrameID = requestAnimationFramePolyfill(this._didWheel); 88 | } 89 | } 90 | 91 | _didWheel() { 92 | this._animationFrameID = null; 93 | this._onWheelCallback(this._deltaX, this._deltaY); 94 | this._deltaX = 0; 95 | this._deltaY = 0; 96 | } 97 | } 98 | 99 | module.exports = ReactWheelHandler; 100 | -------------------------------------------------------------------------------- /examples/old/FilterExample.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file provided by Facebook is for non-commercial testing and evaluation 3 | * purposes only. Facebook reserves all rights not expressly granted. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 7 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8 | * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 9 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 10 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | "use strict"; 14 | 15 | var ExampleImage = require('../helpers/ExampleImage'); 16 | var FakeObjectDataListStore = require('../helpers/FakeObjectDataListStore'); 17 | var FixedDataTable = require('fixed-data-table'); 18 | var React = require('react'); 19 | 20 | var Column = FixedDataTable.Column; 21 | var Table = FixedDataTable.Table; 22 | 23 | var ROWS = 1000000; 24 | 25 | function renderImage(/*string*/ cellData) { 26 | return ; 27 | } 28 | 29 | var FilterExample = React.createClass({ 30 | getInitialState() { 31 | return { 32 | rows : new FakeObjectDataListStore().getAll(), 33 | filteredRows: null, 34 | filterBy: null 35 | }; 36 | }, 37 | 38 | componentWillMount() { 39 | this._filterRowsBy(this.state.filterBy); 40 | }, 41 | 42 | _filterRowsBy(filterBy) { 43 | var rows = this.state.rows.slice(); 44 | var filteredRows = filterBy ? rows.filter(function(row){ 45 | return row['firstName'].toLowerCase().indexOf(filterBy.toLowerCase()) >= 0 46 | }) : rows; 47 | 48 | this.setState({ 49 | filteredRows, 50 | filterBy, 51 | }); 52 | }, 53 | 54 | _rowGetter(rowIndex) { 55 | return this.state.filteredRows[rowIndex]; 56 | }, 57 | 58 | _onFilterChange(e) { 59 | this._filterRowsBy(e.target.value); 60 | }, 61 | 62 | render() { 63 | return ( 64 |
65 | 66 |
67 | 75 | 82 | 88 | 94 | 99 | 104 | 109 |
110 |
111 | ); 112 | }, 113 | }); 114 | 115 | module.exports = FilterExample; 116 | -------------------------------------------------------------------------------- /src/FixedDataTableHelper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule FixedDataTableHelper 10 | * @typechecks 11 | */ 12 | 13 | 'use strict'; 14 | 15 | var Locale = require('Locale'); 16 | var React = require('React'); 17 | var FixedDataTableColumnGroup = require('FixedDataTableColumnGroup.react'); 18 | var FixedDataTableColumn = require('FixedDataTableColumn.react'); 19 | 20 | var DIR_SIGN = (Locale.isRTL() ? -1 : +1); 21 | // A cell up to 5px outside of the visible area will still be considered visible 22 | var CELL_VISIBILITY_TOLERANCE = 5; // used for flyouts 23 | 24 | function renderToString(value) /*string*/ { 25 | if (value === null || value === undefined) { 26 | return ''; 27 | } else { 28 | return String(value); 29 | } 30 | } 31 | 32 | /** 33 | * Helper method to execute a callback against all columns given the children 34 | * of a table. 35 | * @param {?object|array} children 36 | * Children of a table. 37 | * @param {function} callback 38 | * Function to excecute for each column. It is passed the column. 39 | */ 40 | function forEachColumn(children, callback) { 41 | React.Children.forEach(children, (child) => { 42 | if (child.type === FixedDataTableColumnGroup) { 43 | forEachColumn(child.props.children, callback); 44 | } else if (child.type === FixedDataTableColumn) { 45 | callback(child); 46 | } 47 | }); 48 | } 49 | 50 | /** 51 | * Helper method to map columns to new columns. This takes into account column 52 | * groups and will generate a new column group if its columns change. 53 | * @param {?object|array} children 54 | * Children of a table. 55 | * @param {function} callback 56 | * Function to excecute for each column. It is passed the column and should 57 | * return a result column. 58 | */ 59 | function mapColumns(children, callback) { 60 | var newChildren = []; 61 | React.Children.forEach(children, originalChild => { 62 | var newChild = originalChild; 63 | 64 | // The child is either a column group or a column. If it is a column group 65 | // we need to iterate over its columns and then potentially generate a 66 | // new column group 67 | if (originalChild.type === FixedDataTableColumnGroup) { 68 | var haveColumnsChanged = false; 69 | var newColumns = []; 70 | 71 | forEachColumn(originalChild.props.children, originalcolumn => { 72 | var newColumn = callback(originalcolumn); 73 | if (newColumn !== originalcolumn) { 74 | haveColumnsChanged = true; 75 | } 76 | newColumns.push(newColumn); 77 | }); 78 | 79 | // If the column groups columns have changed clone the group and supply 80 | // new children 81 | if (haveColumnsChanged) { 82 | newChild = React.cloneElement(originalChild, { 83 | children: newColumns, 84 | }); 85 | } 86 | } else if (originalChild.type === FixedDataTableColumn) { 87 | newChild = callback(originalChild); 88 | } 89 | 90 | newChildren.push(newChild); 91 | }); 92 | 93 | return newChildren; 94 | } 95 | 96 | var FixedDataTableHelper = { 97 | DIR_SIGN, 98 | CELL_VISIBILITY_TOLERANCE, 99 | renderToString, 100 | forEachColumn, 101 | mapColumns, 102 | }; 103 | 104 | module.exports = FixedDataTableHelper; 105 | -------------------------------------------------------------------------------- /examples/ObjectDataExample.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file provided by Facebook is for non-commercial testing and evaluation 3 | * purposes only. Facebook reserves all rights not expressly granted. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 7 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8 | * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 9 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 10 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | "use strict"; 14 | 15 | var ExampleImage = require('./helpers/ExampleImage'); 16 | var FakeObjectDataListStore = require('./helpers/FakeObjectDataListStore'); 17 | var FixedDataTable = require('fixed-data-table'); 18 | var React = require('react'); 19 | 20 | const {Table, Column, Cell} = FixedDataTable; 21 | 22 | const DateCell = ({rowIndex, data, col, ...props}) => ( 23 | 24 | {data.getObjectAt(rowIndex)[col].toLocaleString()} 25 | 26 | ); 27 | 28 | const ImageCell = ({rowIndex, data, col, ...props}) => ( 29 | 32 | ); 33 | 34 | const LinkCell = ({rowIndex, data, col, ...props}) => ( 35 | 36 | {data.getObjectAt(rowIndex)[col]} 37 | 38 | ); 39 | 40 | const TextCell = ({rowIndex, data, col, ...props}) => ( 41 | 42 | {data.getObjectAt(rowIndex)[col]} 43 | 44 | ); 45 | 46 | class ObjectDataExample extends React.Component { 47 | constructor(props) { 48 | super(props); 49 | 50 | this.state = { 51 | dataList: new FakeObjectDataListStore(1000000), 52 | }; 53 | } 54 | 55 | render() { 56 | var {dataList} = this.state; 57 | return ( 58 | 65 | } 67 | fixed={true} 68 | width={50} 69 | /> 70 | First Name} 72 | cell={} 73 | fixed={true} 74 | width={100} 75 | /> 76 | Last Name} 78 | cell={} 79 | fixed={true} 80 | width={100} 81 | /> 82 | City} 84 | cell={} 85 | width={100} 86 | /> 87 | Street} 89 | cell={} 90 | width={200} 91 | /> 92 | Zip Code} 94 | cell={} 95 | width={200} 96 | /> 97 | Email} 99 | cell={} 100 | width={200} 101 | /> 102 | DOB} 104 | cell={} 105 | width={200} 106 | /> 107 |
108 | ); 109 | } 110 | } 111 | 112 | module.exports = ObjectDataExample; 113 | -------------------------------------------------------------------------------- /src/vendor_upstream/struct/Heap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule Heap 10 | * @typechecks 11 | * @preventMunge 12 | */ 13 | 14 | 'use strict'; 15 | 16 | /* 17 | * @param {*} a 18 | * @param {*} b 19 | * @return {boolean} 20 | */ 21 | function defaultComparator(a, b) { 22 | return a < b; 23 | } 24 | 25 | class Heap { 26 | constructor(items, comparator) { 27 | this._items = items || []; 28 | this._size = this._items.length; 29 | this._comparator = comparator || defaultComparator; 30 | this._heapify(); 31 | } 32 | 33 | /* 34 | * @return {boolean} 35 | */ 36 | empty() { 37 | return this._size === 0; 38 | } 39 | 40 | /* 41 | * @return {*} 42 | */ 43 | pop() { 44 | if (this._size === 0){ 45 | return; 46 | } 47 | 48 | var elt = this._items[0]; 49 | 50 | var lastElt = this._items.pop(); 51 | this._size--; 52 | 53 | if (this._size > 0) { 54 | this._items[0] = lastElt; 55 | this._sinkDown(0); 56 | } 57 | 58 | return elt; 59 | } 60 | 61 | /* 62 | * @param {*} item 63 | */ 64 | push(item) { 65 | this._items[this._size++] = item; 66 | this._bubbleUp(this._size - 1); 67 | } 68 | 69 | /* 70 | * @return {number} 71 | */ 72 | size() { 73 | return this._size; 74 | } 75 | 76 | /* 77 | * @return {*} 78 | */ 79 | peek() { 80 | if (this._size === 0) { 81 | return; 82 | } 83 | 84 | return this._items[0]; 85 | } 86 | 87 | _heapify() { 88 | for (var index = Math.floor((this._size + 1)/ 2); index >= 0; index--) { 89 | this._sinkDown(index); 90 | } 91 | } 92 | 93 | /* 94 | * @parent {number} index 95 | */ 96 | _bubbleUp(index) { 97 | var elt = this._items[index]; 98 | while (index > 0) { 99 | var parentIndex = Math.floor((index + 1) / 2) - 1; 100 | var parentElt = this._items[parentIndex]; 101 | 102 | // if parentElt < elt, stop 103 | if (this._comparator(parentElt, elt)) { 104 | return; 105 | } 106 | 107 | // swap 108 | this._items[parentIndex] = elt; 109 | this._items[index] = parentElt; 110 | index = parentIndex; 111 | } 112 | } 113 | 114 | /* 115 | * @parent {number} index 116 | */ 117 | _sinkDown(index) { 118 | var elt = this._items[index]; 119 | 120 | while (true) { 121 | var leftChildIndex = 2 * (index + 1) - 1; 122 | var rightChildIndex = 2 * (index + 1); 123 | var swapIndex = -1; 124 | 125 | if (leftChildIndex < this._size) { 126 | var leftChild = this._items[leftChildIndex]; 127 | if (this._comparator(leftChild, elt)) { 128 | swapIndex = leftChildIndex; 129 | } 130 | } 131 | 132 | if (rightChildIndex < this._size) { 133 | var rightChild = this._items[rightChildIndex]; 134 | if (this._comparator(rightChild, elt)) { 135 | if (swapIndex === -1 || 136 | this._comparator(rightChild, this._items[swapIndex])) { 137 | swapIndex = rightChildIndex; 138 | } 139 | } 140 | } 141 | 142 | // if we don't have a swap, stop 143 | if (swapIndex === -1) { 144 | return; 145 | } 146 | 147 | this._items[index] = this._items[swapIndex]; 148 | this._items[swapIndex] = elt; 149 | index = swapIndex; 150 | } 151 | } 152 | } 153 | 154 | module.exports = Heap; 155 | -------------------------------------------------------------------------------- /site/home/HeroTable.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var FakeObjectDataListStore = require('../../examples/helpers/FakeObjectDataListStore'); 4 | var FixedDataTable = require('fixed-data-table'); 5 | var React = require('react'); 6 | var Constants = require('../Constants'); 7 | 8 | var Table = FixedDataTable.Table; 9 | var Column = FixedDataTable.Column; 10 | var Cell = FixedDataTable.Cell; 11 | 12 | // Require common FixedDataTable CSS. 13 | require('fixed-data-table/css/layout/ScrollbarLayout.css'); 14 | require('fixed-data-table/css/layout/fixedDataTableLayout.css'); 15 | require('fixed-data-table/css/layout/fixedDataTableCellLayout.css'); 16 | require('fixed-data-table/css/layout/fixedDataTableCellGroupLayout.css'); 17 | require('fixed-data-table/css/layout/fixedDataTableColumnResizerLineLayout.css'); 18 | require('fixed-data-table/css/layout/fixedDataTableRowLayout.css'); 19 | 20 | require('fixed-data-table/css/style/fixedDataTable.css'); 21 | require('fixed-data-table/css/style/fixedDataTableCell.css'); 22 | require('fixed-data-table/css/style/fixedDataTableColumnResizerLine.css'); 23 | require('fixed-data-table/css/style/fixedDataTableRow.css'); 24 | require('fixed-data-table/css/style/Scrollbar.css'); 25 | 26 | var dataList = new FakeObjectDataListStore(); 27 | var FakeTextCell = ({rowIndex, field, ...props}) => ( 28 | 29 | {dataList.getObjectAt(rowIndex)[field].toString()} 30 | 31 | ); 32 | 33 | class HeroTable extends React.Component { 34 | render() { 35 | return ( 36 | 46 | First Name} 51 | cell={} 52 | /> 53 | Last Name} 58 | cell={} 59 | /> 60 | City} 64 | cell={} 65 | /> 66 | Street} 69 | cell={} 70 | /> 71 | Zip Code} 74 | cell={} 75 | /> 76 | Email} 79 | cell={} 80 | /> 81 | DOB} 84 | cell={} 85 | /> 86 | City} 90 | cell={} 91 | /> 92 | BS!} 95 | cell={} 96 | /> 97 | Catch Phrase} 100 | cell={} 101 | /> 102 | Company Name} 105 | cell={} 106 | /> 107 |
108 | ); 109 | } 110 | } 111 | 112 | module.exports = HeroTable; 113 | -------------------------------------------------------------------------------- /site/IndexPage.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | require('./base.less'); 4 | 5 | var Constants = require('./Constants'); 6 | var HomePage = require('./home/HomePage'); 7 | var DocsPage = require('./docs/DocsPage'); 8 | var ExamplesPage = require('./examples/ExamplesPage'); 9 | var React = require('react'); 10 | var ReactDOMServer = require('react-dom/server'); 11 | 12 | var faviconURL = require('./images/favicon.png'); 13 | 14 | var DocsPages = Constants.DocsPages; 15 | var ExamplePages = Constants.ExamplePages; 16 | var OtherPages = Constants.OtherPages; 17 | 18 | function getPageForLocation(pages, location) { 19 | for (var key in pages) { 20 | if (!pages.hasOwnProperty(key) || typeof pages[key] !== 'object') { 21 | continue; 22 | } 23 | 24 | if (pages[key].groupTitle) { 25 | var nestedPage = getPageForLocation(pages[key], location); 26 | if (nestedPage) { 27 | return nestedPage; 28 | } 29 | } 30 | 31 | if (pages[key].location === location) { 32 | return {pageType: key, page: pages[key]}; 33 | } 34 | } 35 | 36 | return null; 37 | } 38 | 39 | var IndexPage = React.createClass({ 40 | statics: { 41 | getDoctype() { 42 | return ''; 43 | }, 44 | 45 | renderToString(props) { 46 | return IndexPage.getDoctype() + 47 | ReactDOMServer.renderToString(); 48 | }, 49 | }, 50 | 51 | getInitialState() { 52 | return { 53 | renderPage: !this.props.devMode 54 | }; 55 | }, 56 | 57 | render() { 58 | // Dump out our current props to a global object via a script tag so 59 | // when initialising the browser environment we can bootstrap from the 60 | // same props as what each page was rendered with. 61 | var browserInitScriptObj = { 62 | __html: 'window.INITIAL_PROPS = ' + JSON.stringify(this.props) + ';\n' 63 | }; 64 | 65 | return ( 66 | 67 | 68 | 69 | FixedDataTable 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | {this.state.renderPage && this._renderPage()} 78 | 79 | 81 | 82 | 83 | 84 | 85 | ); 86 | }, 87 | 88 | _renderPage() { 89 | switch (this.props.location) { 90 | case OtherPages.HOME.location: 91 | return ; 92 | } 93 | 94 | var activeDocsPage = getPageForLocation(DocsPages, this.props.location); 95 | if (activeDocsPage) { 96 | return ( 97 | 101 | ); 102 | } 103 | 104 | var activeExamplePage = getPageForLocation(ExamplePages, this.props.location); 105 | if (activeExamplePage) { 106 | return ( 107 | 111 | ); 112 | } 113 | 114 | throw new Error( 115 | 'Page of location ' + 116 | JSON.stringify(this.props.location) + 117 | ' not found.' 118 | ); 119 | }, 120 | 121 | componentDidMount() { 122 | if (!this.state.renderPage) { 123 | this.setState({ 124 | renderPage: true 125 | }); 126 | } 127 | } 128 | }); 129 | 130 | module.exports = IndexPage; 131 | -------------------------------------------------------------------------------- /examples/old/SortExample.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file provided by Facebook is for non-commercial testing and evaluation 3 | * purposes only. Facebook reserves all rights not expressly granted. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 7 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8 | * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 9 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 10 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | "use strict"; 14 | 15 | var FakeObjectDataListStore = require('../helpers/FakeObjectDataListStore'); 16 | var FixedDataTable = require('fixed-data-table'); 17 | var React = require('react'); 18 | 19 | var Column = FixedDataTable.Column; 20 | var Table = FixedDataTable.Table; 21 | 22 | var SortTypes = { 23 | ASC: 'ASC', 24 | DESC: 'DESC', 25 | }; 26 | 27 | function renderDate(/*object*/ cellData) { 28 | return {cellData.toLocaleString()}; 29 | } 30 | 31 | var SortExample = React.createClass({ 32 | getInitialState() { 33 | return { 34 | rows: new FakeObjectDataListStore().getAll(), 35 | sortBy: 'id', 36 | sortDir: null, 37 | }; 38 | }, 39 | 40 | _rowGetter(rowIndex) { 41 | return this.state.rows[rowIndex]; 42 | }, 43 | 44 | _sortRowsBy(cellDataKey) { 45 | var sortDir = this.state.sortDir; 46 | var sortBy = cellDataKey; 47 | if (sortBy === this.state.sortBy) { 48 | sortDir = this.state.sortDir === SortTypes.ASC ? SortTypes.DESC : SortTypes.ASC; 49 | } else { 50 | sortDir = SortTypes.DESC; 51 | } 52 | 53 | var rows = this.state.rows.slice(); 54 | rows.sort((a, b) => { 55 | var sortVal = 0; 56 | if (a[sortBy] > b[sortBy]) { 57 | sortVal = 1; 58 | } 59 | if (a[sortBy] < b[sortBy]) { 60 | sortVal = -1; 61 | } 62 | 63 | if (sortDir === SortTypes.DESC) { 64 | sortVal = sortVal * -1; 65 | } 66 | 67 | return sortVal; 68 | }); 69 | 70 | this.setState({ 71 | rows, 72 | sortBy, 73 | sortDir, 74 | }); 75 | }, 76 | 77 | _renderHeader(label, cellDataKey) { 78 | return ( 79 | {label} 80 | ); 81 | }, 82 | 83 | render() { 84 | var sortDirArrow = ''; 85 | 86 | if (this.state.sortDir !== null){ 87 | sortDirArrow = this.state.sortDir === SortTypes.DESC ? ' ↓' : ' ↑'; 88 | } 89 | 90 | return ( 91 | 99 | 105 | 111 | 117 | 123 | 129 |
130 | ); 131 | }, 132 | }); 133 | 134 | module.exports = SortExample; 135 | -------------------------------------------------------------------------------- /site/home/Header.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var React = require('react'); 4 | var ReactDOM = require('react-dom'); 5 | var Constants = require('../Constants'); 6 | 7 | var FIXED_THRESHOLD = 680; 8 | var MAX_HEIGHT = 800; 9 | var HEADER_HEIGHT = 50; 10 | var EMPTY_OBJECT = {}; 11 | var GITHUB_URL = 'https://github.com/facebook/fixed-data-table'; 12 | var DOCS_DEFAULT_LOCATION = Constants.DOCS_DEFAULT.location; 13 | var EXAMPLES_DEFAULT_LOCATION = Constants.EXAMPLES_DEFAULT.location; 14 | 15 | var Header = React.createClass({ 16 | getInitialState() { 17 | return { 18 | scroll: 0, 19 | fixed: false, 20 | renderHero: false, 21 | }; 22 | }, 23 | 24 | componentDidMount() { 25 | this.offsetWidth = this._getWindowWidth(); 26 | this.offsetHeight = ReactDOM.findDOMNode(this).offsetHeight; 27 | window.addEventListener('scroll', this.handleScroll); 28 | window.addEventListener('resize', this.handleResize); 29 | 30 | this.setState({ 31 | renderHero: true, 32 | fixed: this.offsetWidth <= FIXED_THRESHOLD, 33 | }); 34 | }, 35 | 36 | componentWillUnmount() { 37 | window.removeEventListener('scroll', this.handleScroll); 38 | window.removeEventListener('resize', this.handleResize); 39 | }, 40 | 41 | handleResize(event) { 42 | this.offsetWidth = this._getWindowWidth(); 43 | this.offsetHeight = ReactDOM.findDOMNode(this).offsetHeight; 44 | this.setState({ 45 | fixed: this.offsetWidth <= FIXED_THRESHOLD, 46 | }); 47 | this.forceUpdate(); 48 | }, 49 | 50 | handleScroll(event) { 51 | var scrollPos = window.scrollY; 52 | scrollPos = scrollPos < this.offsetHeight ? scrollPos : this.offsetHeight; 53 | this.setState({ scroll: Math.max(scrollPos, 0) }); 54 | }, 55 | 56 | _getWindowWidth() { 57 | return Math.max(document.documentElement.clientWidth, window.innerWidth || 0); 58 | }, 59 | 60 | _renderHero() { 61 | var HeroTable = require('./HeroTable'); 62 | 63 | return ( 64 |
65 | 71 |
72 | ); 73 | }, 74 | 75 | render() { 76 | var coverHeight = this.offsetHeight - this.state.scroll; 77 | var topClip = coverHeight < 0 ? 0 : coverHeight; 78 | topClip = coverHeight > HEADER_HEIGHT ? HEADER_HEIGHT : coverHeight; 79 | 80 | var clipStyles = { 81 | clip: 'rect(' + topClip + 'px, 5000px, ' + HEADER_HEIGHT + 'px, 0)', 82 | }; 83 | 84 | var miniHeaderClasses = 'miniHeader'; 85 | if (!this.state.renderHero) { 86 | miniHeaderClasses += ' notLoaded'; 87 | } 88 | 89 | return ( 90 |
91 |
94 |
95 | 96 | Docs 97 | Examples 98 | Github 99 |
100 |
101 |
102 | {this.state.renderHero && this._renderHero()} 103 |
104 |
105 | FixedDataTable 106 |
107 |
108 | A fast and flexible lazily rendered table for React.js 109 |
110 | View on GitHub 111 |
112 | Docs 113 | • 114 | Examples 115 |
116 |
117 |
118 |
119 | ); 120 | }, 121 | 122 | }); 123 | 124 | module.exports = Header; 125 | -------------------------------------------------------------------------------- /dist/fixed-data-table-base.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * FixedDataTable v0.6.0 3 | * 4 | * Copyright (c) 2015, Facebook, Inc. 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. An additional grant 9 | * of patent rights can be found in the PATENTS file in the same directory. 10 | */ 11 | 12 | .ScrollbarLayout_main{box-sizing:border-box;outline:none;overflow:hidden;position:absolute;-webkit-transition-duration:250ms;transition-duration:250ms;-webkit-transition-timing-function:ease;transition-timing-function:ease;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ScrollbarLayout_mainVertical{bottom:0;right:0;top:0;-webkit-transition-property:background-color width;transition-property:background-color width;width:15px}.ScrollbarLayout_mainVertical.public_Scrollbar_mainActive,.ScrollbarLayout_mainVertical:hover{width:17px}.ScrollbarLayout_mainHorizontal{bottom:0;height:15px;left:0;-webkit-transition-property:background-color height;transition-property:background-color height}.ScrollbarLayout_mainHorizontal.public_Scrollbar_mainActive,.ScrollbarLayout_mainHorizontal:hover{height:17px}.ScrollbarLayout_face{left:0;overflow:hidden;position:absolute;z-index:1}.ScrollbarLayout_face:after{border-radius:6px;content:'';display:block;position:absolute;-webkit-transition:background-color 250ms ease;transition:background-color 250ms ease}.ScrollbarLayout_faceHorizontal{bottom:0;left:0;top:0}.ScrollbarLayout_faceHorizontal:after{bottom:4px;left:0;top:4px;width:100%}.ScrollbarLayout_faceVertical{left:0;right:0;top:0}.ScrollbarLayout_faceVertical:after{height:100%;left:4px;right:4px;top:0}.fixedDataTableCellGroupLayout_cellGroup{-webkit-backface-visibility:hidden;backface-visibility:hidden;left:0;overflow:hidden;position:absolute;top:0;white-space:nowrap}.fixedDataTableCellGroupLayout_cellGroup>.public_fixedDataTableCell_main{display:inline-block;vertical-align:top;white-space:normal}.fixedDataTableCellGroupLayout_cellGroupWrapper{position:absolute;top:0}.fixedDataTableCellLayout_main{border-right-style:solid;border-width:0 1px 0 0;box-sizing:border-box;display:block;overflow:hidden;position:absolute;white-space:normal}.fixedDataTableCellLayout_lastChild{border-width:0 1px 1px 0}.fixedDataTableCellLayout_alignRight{text-align:right}.fixedDataTableCellLayout_alignCenter{text-align:center}.fixedDataTableCellLayout_wrap1{display:table}.fixedDataTableCellLayout_wrap2{display:table-row}.fixedDataTableCellLayout_wrap3{display:table-cell;vertical-align:middle}.fixedDataTableCellLayout_columnResizerContainer{position:absolute;right:0;width:6px;z-index:1}.fixedDataTableCellLayout_columnResizerContainer:hover{cursor:ew-resize}.fixedDataTableCellLayout_columnResizerContainer:hover .fixedDataTableCellLayout_columnResizerKnob{visibility:visible}.fixedDataTableCellLayout_columnResizerKnob{position:absolute;right:0;visibility:hidden;width:4px}.fixedDataTableColumnResizerLineLayout_mouseArea{cursor:ew-resize;position:absolute;right:-5px;width:12px}.fixedDataTableColumnResizerLineLayout_main{border-right-style:solid;border-right-width:1px;box-sizing:border-box;position:absolute;z-index:10}body[dir="rtl"] .fixedDataTableColumnResizerLineLayout_main,.fixedDataTableColumnResizerLineLayout_hiddenElem{display:none!important}.fixedDataTableLayout_main{border-style:solid;border-width:1px;box-sizing:border-box;overflow:hidden;position:relative}.fixedDataTableLayout_header,.fixedDataTableLayout_hasBottomBorder{border-bottom-style:solid;border-bottom-width:1px}.fixedDataTableLayout_footer .public_fixedDataTableCell_main{border-top-style:solid;border-top-width:1px}.fixedDataTableLayout_topShadow,.fixedDataTableLayout_bottomShadow{height:4px;left:0;position:absolute;right:0;z-index:1}.fixedDataTableLayout_bottomShadow{margin-top:-4px}.fixedDataTableLayout_rowsContainer{overflow:hidden;position:relative}.fixedDataTableLayout_horizontalScrollbar{bottom:0;position:absolute}.fixedDataTableRowLayout_main{box-sizing:border-box;overflow:hidden;position:absolute;top:0}.fixedDataTableRowLayout_body{left:0;position:absolute;top:0}.fixedDataTableRowLayout_fixedColumnsDivider{-webkit-backface-visibility:hidden;backface-visibility:hidden;border-left-style:solid;border-left-width:1px;left:0;position:absolute;top:0;width:0}.fixedDataTableRowLayout_columnsShadow{width:4px}.fixedDataTableRowLayout_rowWrapper{position:absolute;top:0} -------------------------------------------------------------------------------- /examples/FilterExample.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file provided by Facebook is for non-commercial testing and evaluation 3 | * purposes only. Facebook reserves all rights not expressly granted. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 7 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8 | * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 9 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 10 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | "use strict"; 14 | 15 | var ExampleImage = require('./helpers/ExampleImage'); 16 | var FakeObjectDataListStore = require('./helpers/FakeObjectDataListStore'); 17 | var FixedDataTable = require('fixed-data-table'); 18 | var React = require('react'); 19 | 20 | const {Table, Column, Cell} = FixedDataTable; 21 | 22 | const ImageCell = ({rowIndex, data, col, ...props}) => ( 23 | 26 | ); 27 | 28 | const TextCell = ({rowIndex, data, col, ...props}) => ( 29 | 30 | {data.getObjectAt(rowIndex)[col]} 31 | 32 | ); 33 | 34 | class DataListWrapper { 35 | constructor(indexMap, data) { 36 | this._indexMap = indexMap; 37 | this._data = data; 38 | } 39 | 40 | getSize() { 41 | return this._indexMap.length; 42 | } 43 | 44 | getObjectAt(index) { 45 | return this._data.getObjectAt( 46 | this._indexMap[index], 47 | ); 48 | } 49 | } 50 | 51 | class FilterExample extends React.Component { 52 | constructor(props) { 53 | super(props); 54 | 55 | this._dataList = new FakeObjectDataListStore(2000); 56 | this.state = { 57 | filteredDataList: this._dataList, 58 | }; 59 | 60 | this._onFilterChange = this._onFilterChange.bind(this); 61 | } 62 | 63 | _onFilterChange(e) { 64 | if (!e.target.value) { 65 | this.setState({ 66 | filteredDataList: this._dataList, 67 | }); 68 | } 69 | 70 | var filterBy = e.target.value.toLowerCase(); 71 | var size = this._dataList.getSize(); 72 | var filteredIndexes = []; 73 | for (var index = 0; index < size; index++) { 74 | var {firstName} = this._dataList.getObjectAt(index); 75 | if (firstName.toLowerCase().indexOf(filterBy) !== -1) { 76 | filteredIndexes.push(index); 77 | } 78 | } 79 | 80 | this.setState({ 81 | filteredDataList: new DataListWrapper(filteredIndexes, this._dataList), 82 | }); 83 | } 84 | 85 | render() { 86 | var {filteredDataList} = this.state; 87 | return ( 88 |
89 | 93 |
94 | 101 | } 103 | fixed={true} 104 | width={50} 105 | /> 106 | First Name} 108 | cell={} 109 | fixed={true} 110 | width={100} 111 | /> 112 | Last Name} 114 | cell={} 115 | fixed={true} 116 | width={100} 117 | /> 118 | City} 120 | cell={} 121 | width={100} 122 | /> 123 | Street} 125 | cell={} 126 | width={200} 127 | /> 128 | Zip Code} 130 | cell={} 131 | width={200} 132 | /> 133 |
134 |
135 | ); 136 | } 137 | } 138 | 139 | module.exports = FilterExample; 140 | -------------------------------------------------------------------------------- /site/examples/ExamplesPage.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file provided by Facebook is for non-commercial testing and evaluation 3 | * purposes only. Facebook reserves all rights not expressly granted. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 7 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 8 | * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 9 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 10 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | */ 12 | 13 | "use strict"; 14 | 15 | // Require common FixedDataTable CSS. 16 | require('fixed-data-table/css/layout/ScrollbarLayout.css'); 17 | require('fixed-data-table/css/layout/fixedDataTableLayout.css'); 18 | require('fixed-data-table/css/layout/fixedDataTableCellLayout.css'); 19 | require('fixed-data-table/css/layout/fixedDataTableCellGroupLayout.css'); 20 | require('fixed-data-table/css/layout/fixedDataTableColumnResizerLineLayout.css'); 21 | require('fixed-data-table/css/layout/fixedDataTableRowLayout.css'); 22 | require('fixed-data-table/css/style/fixedDataTable.css'); 23 | require('fixed-data-table/css/style/fixedDataTableCell.css'); 24 | require('fixed-data-table/css/style/fixedDataTableColumnResizerLine.css'); 25 | require('fixed-data-table/css/style/fixedDataTableRow.css'); 26 | require('fixed-data-table/css/style/Scrollbar.css'); 27 | 28 | var ExampleHeader = require('./ExampleHeader'); 29 | var ExamplesWrapper = require('./ExamplesWrapper'); 30 | var TouchExampleWrapper = require('./TouchExampleWrapper'); 31 | var React = require('react'); 32 | var Constants = require('../Constants'); 33 | 34 | var ExamplePages = Constants.ExamplePages; 35 | 36 | var EXAMPLE_COMPONENTS = { 37 | [ExamplePages.OBJECT_DATA_EXAMPLE.location]: require('../../examples/ObjectDataExample'), 38 | [ExamplePages.RESIZE_EXAMPLE.location]: require('../../examples/ResizeExample'), 39 | [ExamplePages.FLEXGROW_EXAMPLE.location]: require('../../examples/FlexGrowExample'), 40 | [ExamplePages.COLUMN_GROUPS_EXAMPLE.location]: require('../../examples/ColumnGroupsExample'), 41 | [ExamplePages.FILTER_EXAMPLE.location]: require('../../examples/FilterExample'), 42 | [ExamplePages.SORT_EXAMPLE.location]: require('../../examples/SortExample'), 43 | }; 44 | 45 | // Render old examples 46 | // var EXAMPLE_COMPONENTS_OLD = { 47 | // [ExamplePages.OBJECT_DATA_EXAMPLE.location]: require('../../examples/old/ObjectDataExample'), 48 | // [ExamplePages.RESIZE_EXAMPLE.location]: require('../../examples/old/ResizeExample'), 49 | // [ExamplePages.FLEXGROW_EXAMPLE.location]: require('../../examples/old/FlexGrowExample'), 50 | // [ExamplePages.COLUMN_GROUPS_EXAMPLE.location]: require('../../examples/old/ColumnGroupsExample'), 51 | // [ExamplePages.FILTER_EXAMPLE.location]: require('../../examples/old/FilterExample'), 52 | // [ExamplePages.SORT_EXAMPLE.location]: require('../../examples/old/SortExample'), 53 | // }; 54 | 55 | var ExamplesPage = React.createClass({ 56 | getInitialState() { 57 | return { 58 | renderPage: false 59 | }; 60 | }, 61 | 62 | render() { 63 | return ( 64 | 65 | 66 | {this.state.renderPage && this._renderPage()} 67 | 68 | ); 69 | }, 70 | 71 | _renderPage() { 72 | var Example = EXAMPLE_COMPONENTS[this.props.page.location]; 73 | 74 | return ( 75 | 76 | 77 | 78 | ); 79 | }, 80 | 81 | componentDidMount() { 82 | this._update(); 83 | var win = window; 84 | if (win.addEventListener) { 85 | win.addEventListener('resize', this._onResize, false); 86 | } else if (win.attachEvent) { 87 | win.attachEvent('onresize', this._onResize); 88 | } else { 89 | win.onresize = this._onResize; 90 | } 91 | }, 92 | 93 | _onResize() { 94 | clearTimeout(this._updateTimer); 95 | this._updateTimer = setTimeout(this._update, 16); 96 | }, 97 | 98 | _update() { 99 | var win = window; 100 | 101 | var widthOffset = win.innerWidth < 680 ? 0 : 240; 102 | 103 | this.setState({ 104 | renderPage: true, 105 | tableWidth: win.innerWidth - widthOffset, 106 | tableHeight: win.innerHeight - 200, 107 | }); 108 | } 109 | }); 110 | 111 | module.exports = ExamplesPage; 112 | -------------------------------------------------------------------------------- /site/home/homePageStyle.less: -------------------------------------------------------------------------------- 1 | @import '../variables.less'; 2 | 3 | .homePage { 4 | .header { 5 | -khtml-user-select: none; 6 | -moz-user-select: none; 7 | -ms-user-select: none; 8 | -webkit-touch-callout: none; 9 | -webkit-user-select: none; 10 | user-select: none; 11 | } 12 | 13 | .pageBody { 14 | background-color: #fff; 15 | padding: 0 36px; 16 | position: relative; 17 | z-index: 1; 18 | } 19 | 20 | .contents { 21 | margin: 0 auto; 22 | max-width: 740px; 23 | padding: 64px 0; 24 | } 25 | 26 | .contents h2 { 27 | margin: 4rem 0 1rem; 28 | } 29 | 30 | .contents h3 { 31 | margin: 2rem 0 1rem; 32 | } 33 | 34 | .miniHeader { 35 | background: #435052; 36 | position: fixed; 37 | width: 100%; 38 | z-index: 2; 39 | } 40 | 41 | .notLoaded { 42 | visibility: hidden; 43 | } 44 | 45 | .miniHeaderContents { 46 | margin: 0 auto; 47 | max-width: 880px; 48 | padding: 12px 36px; 49 | text-align: right; 50 | } 51 | 52 | @media only screen and (max-width: 680px) { 53 | .miniHeaderContents { 54 | text-align: left; 55 | } 56 | } 57 | 58 | .miniLogo { 59 | float: left; 60 | left: -140px; 61 | top: 12px; 62 | } 63 | 64 | @media only screen and (max-width: 680px) { 65 | .miniLogo { 66 | display: none; 67 | } 68 | } 69 | 70 | .miniLogo { 71 | margin: 0; 72 | line-height: 28px; 73 | color: #000; 74 | } 75 | 76 | .miniHeaderContents a { 77 | color: #fff; 78 | margin-right: 1em; 79 | text-decoration: none; 80 | text-shadow: 0 1px rgba(0, 0, 0, 0.15); 81 | } 82 | 83 | .cover .miniHeaderContents a { 84 | color: #435052; 85 | text-shadow: 0 1px rgba(255, 255, 255, 0.15); 86 | } 87 | 88 | .miniHeaderContents a:last-child { 89 | margin-right: 0; 90 | } 91 | 92 | .cover { 93 | background-color: #bdbdbd; 94 | border-bottom: 1px solid #ddd; 95 | height: 70vh; 96 | max-height: 800px; 97 | min-height: 260px; 98 | overflow: hidden; 99 | position: relative; 100 | width: 100%; 101 | z-index: 1; 102 | } 103 | 104 | .filler { 105 | position: fixed; 106 | top: 0; 107 | width: 100%; 108 | z-index: 1001; 109 | } 110 | 111 | .miniHeader .miniLogo .logoPic { 112 | width: 169px; 113 | height: 23px; 114 | margin-top: 1px; 115 | background: url(../images/fdt_logo_transparent_ondark_23px.png) no-repeat scroll; 116 | 117 | @media only screen and (-webkit-min-device-pixel-ratio: 2), 118 | only screen and ( min-resolution: 192dpi), 119 | only screen and ( min-resolution: 2dppx) { 120 | background-image: url(../images/fdt_logo_transparent_ondark_23px-2x.png); 121 | background-size: contain; 122 | } 123 | } 124 | 125 | .logo { 126 | bottom: 0; 127 | left: 0; 128 | right: 0; 129 | position: fixed; 130 | top: 25vh; 131 | text-align: center; 132 | z-index: 1000; 133 | 134 | @media only screen and (max-width: 680px) { 135 | top: 70px; 136 | } 137 | 138 | .title { 139 | font-size: 2.9em; 140 | font-weight: 800; 141 | } 142 | 143 | .subtitle { 144 | font-size: 1.2em; 145 | margin-bottom: 18px; 146 | } 147 | 148 | .button { 149 | background: none; 150 | border: 2px solid @link-color; 151 | border-radius: 4px; 152 | padding: 8px 16px; 153 | transition-duration: .3s; 154 | text-transform: uppercase; 155 | font-weight: 600; 156 | 157 | &:hover { 158 | background: @link-color; 159 | color: white; 160 | } 161 | } 162 | 163 | .links { 164 | margin-top: 16px; 165 | a { 166 | margin: 4px; 167 | } 168 | } 169 | } 170 | 171 | .heroContainer { 172 | position: absolute; 173 | } 174 | 175 | .heroContainer:after { 176 | content: ''; 177 | position: absolute; 178 | left: 0; 179 | right: 0; 180 | top: 0; 181 | bottom: 0; 182 | background: rgba(255, 255, 255, 0.8); 183 | z-index: 1000; 184 | } 185 | 186 | @media only screen and (max-width: 680px) { 187 | 188 | .cover { 189 | max-height: 260px; 190 | } 191 | 192 | .miniHeader { 193 | } 194 | 195 | .miniHeaderContents { 196 | padding: 12px; 197 | text-align: center; 198 | } 199 | 200 | .synopsis { 201 | max-width: 540px; 202 | } 203 | 204 | .pageBody { 205 | padding: 0 12px; 206 | } 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /src/FixedDataTableWidthHelper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule FixedDataTableWidthHelper 10 | * @typechecks 11 | */ 12 | 13 | 'use strict'; 14 | 15 | var React = require('React'); 16 | 17 | function getTotalWidth(/*array*/ columns) /*number*/ { 18 | var totalWidth = 0; 19 | for (var i = 0; i < columns.length; ++i) { 20 | totalWidth += columns[i].props.width; 21 | } 22 | return totalWidth; 23 | } 24 | 25 | function getTotalFlexGrow(/*array*/ columns) /*number*/ { 26 | var totalFlexGrow = 0; 27 | for (var i = 0; i < columns.length; ++i) { 28 | totalFlexGrow += columns[i].props.flexGrow || 0; 29 | } 30 | return totalFlexGrow; 31 | } 32 | 33 | function distributeFlexWidth( 34 | /*array*/ columns, 35 | /*number*/ flexWidth 36 | ) /*object*/ { 37 | if (flexWidth <= 0) { 38 | return { 39 | columns: columns, 40 | width: getTotalWidth(columns), 41 | }; 42 | } 43 | var remainingFlexGrow = getTotalFlexGrow(columns); 44 | var remainingFlexWidth = flexWidth; 45 | var newColumns = []; 46 | var totalWidth = 0; 47 | for (var i = 0; i < columns.length; ++i) { 48 | var column = columns[i]; 49 | if (!column.props.flexGrow) { 50 | totalWidth += column.props.width; 51 | newColumns.push(column); 52 | continue; 53 | } 54 | var columnFlexWidth = Math.floor( 55 | column.props.flexGrow / remainingFlexGrow * remainingFlexWidth 56 | ); 57 | var newColumnWidth = Math.floor(column.props.width + columnFlexWidth); 58 | totalWidth += newColumnWidth; 59 | 60 | remainingFlexGrow -= column.props.flexGrow; 61 | remainingFlexWidth -= columnFlexWidth; 62 | 63 | newColumns.push(React.cloneElement( 64 | column, 65 | {width: newColumnWidth} 66 | )); 67 | } 68 | 69 | return { 70 | columns: newColumns, 71 | width: totalWidth, 72 | }; 73 | } 74 | 75 | function adjustColumnGroupWidths( 76 | /*array*/ columnGroups, 77 | /*number*/ expectedWidth 78 | ) /*object*/ { 79 | var allColumns = []; 80 | var i; 81 | for (i = 0; i < columnGroups.length; ++i) { 82 | React.Children.forEach( 83 | columnGroups[i].props.children, 84 | (column) => { 85 | allColumns.push(column); 86 | } 87 | ); 88 | } 89 | var columnsWidth = getTotalWidth(allColumns); 90 | var remainingFlexGrow = getTotalFlexGrow(allColumns); 91 | var remainingFlexWidth = Math.max(expectedWidth - columnsWidth, 0); 92 | 93 | var newAllColumns = []; 94 | var newColumnGroups = []; 95 | 96 | for (i = 0; i < columnGroups.length; ++i) { 97 | var columnGroup = columnGroups[i]; 98 | var currentColumns = []; 99 | 100 | React.Children.forEach( 101 | columnGroup.props.children, 102 | (column) => { 103 | currentColumns.push(column); 104 | } 105 | ); 106 | 107 | var columnGroupFlexGrow = getTotalFlexGrow(currentColumns); 108 | var columnGroupFlexWidth = Math.floor( 109 | columnGroupFlexGrow / remainingFlexGrow * remainingFlexWidth 110 | ); 111 | 112 | var newColumnSettings = distributeFlexWidth( 113 | currentColumns, 114 | columnGroupFlexWidth 115 | ); 116 | 117 | remainingFlexGrow -= columnGroupFlexGrow; 118 | remainingFlexWidth -= columnGroupFlexWidth; 119 | 120 | for (var j = 0; j < newColumnSettings.columns.length; ++j) { 121 | newAllColumns.push(newColumnSettings.columns[j]); 122 | } 123 | 124 | newColumnGroups.push(React.cloneElement( 125 | columnGroup, 126 | {width: newColumnSettings.width} 127 | )); 128 | } 129 | 130 | return { 131 | columns: newAllColumns, 132 | columnGroups: newColumnGroups, 133 | }; 134 | } 135 | 136 | function adjustColumnWidths( 137 | /*array*/ columns, 138 | /*number*/ expectedWidth 139 | ) /*array*/ { 140 | var columnsWidth = getTotalWidth(columns); 141 | if (columnsWidth < expectedWidth) { 142 | return distributeFlexWidth(columns, expectedWidth - columnsWidth).columns; 143 | } 144 | return columns; 145 | } 146 | 147 | var FixedDataTableWidthHelper = { 148 | getTotalWidth, 149 | getTotalFlexGrow, 150 | distributeFlexWidth, 151 | adjustColumnWidths, 152 | adjustColumnGroupWidths, 153 | }; 154 | 155 | module.exports = FixedDataTableWidthHelper; 156 | -------------------------------------------------------------------------------- /docs/api-v0.5/ColumnAPI.md: -------------------------------------------------------------------------------- 1 | 2 | `Column` (component) 3 | ==================== 4 | 5 | Component that defines the attributes of table column. 6 | 7 | Props 8 | ----- 9 | 10 | ### `align` 11 | 12 | The horizontal alignment of the table cell content. 13 | 14 | type: `enum('left'|'center'|'right')` 15 | 16 | 17 | ### `headerClassName` 18 | 19 | className for this column's header cell. 20 | 21 | type: `string` 22 | 23 | 24 | ### `footerClassName` 25 | 26 | className for this column's footer cell. 27 | 28 | type: `string` 29 | 30 | 31 | ### `cellClassName` 32 | 33 | className for each of this column's data cells. 34 | 35 | type: `string` 36 | 37 | 38 | ### `cellRenderer` 39 | 40 | The cell renderer that returns React-renderable content for table cell. 41 | ``` 42 | function( 43 | cellData: any, 44 | cellDataKey: string, 45 | rowData: object, 46 | rowIndex: number, 47 | columnData: any, 48 | width: number 49 | ): ?$jsx 50 | ``` 51 | 52 | type: `func` 53 | 54 | 55 | ### `cellDataGetter` 56 | 57 | The getter `function(string_cellDataKey, object_rowData)` that returns 58 | the cell data for the `cellRenderer`. 59 | If not provided, the cell data will be collected from 60 | `rowData[cellDataKey]` instead. The value that `cellDataGetter` returns 61 | will be used to determine whether the cell should re-render. 62 | 63 | type: `func` 64 | 65 | 66 | ### `dataKey` (required) 67 | 68 | The key to retrieve the cell data from the data row. Provided key type 69 | must be either `string` or `number`. Since we use this 70 | for keys, it must be specified for each column. 71 | 72 | type: `union(string|number)` 73 | 74 | 75 | ### `fixed` 76 | 77 | Controls if the column is fixed when scrolling in the X axis. 78 | 79 | type: `bool` 80 | defaultValue: `false` 81 | 82 | 83 | ### `headerRenderer` 84 | 85 | The cell renderer that returns React-renderable content for table column 86 | header. 87 | ``` 88 | function( 89 | label: ?string, 90 | cellDataKey: string, 91 | columnData: any, 92 | rowData: array, 93 | width: number 94 | ): ?$jsx 95 | ``` 96 | 97 | type: `func` 98 | 99 | 100 | ### `footerRenderer` 101 | 102 | The cell renderer that returns React-renderable content for table column 103 | footer. 104 | ``` 105 | function( 106 | label: ?string, 107 | cellDataKey: string, 108 | columnData: any, 109 | rowData: array, 110 | width: number 111 | ): ?$jsx 112 | ``` 113 | 114 | type: `func` 115 | 116 | 117 | ### `columnData` 118 | 119 | Bucket for any data to be passed into column renderer functions. 120 | 121 | type: `object` 122 | 123 | 124 | ### `label` 125 | 126 | The column's header label. 127 | 128 | type: `string` 129 | 130 | 131 | ### `width` (required) 132 | 133 | The pixel width of the column. 134 | 135 | type: `number` 136 | 137 | 138 | ### `minWidth` 139 | 140 | If this is a resizable column this is its minimum pixel width. 141 | 142 | type: `number` 143 | 144 | 145 | ### `maxWidth` 146 | 147 | If this is a resizable column this is its maximum pixel width. 148 | 149 | type: `number` 150 | 151 | 152 | ### `flexGrow` 153 | 154 | The grow factor relative to other columns. Same as the flex-grow API 155 | from http://www.w3.org/TR/css3-flexbox/. Basically, take any available 156 | extra width and distribute it proportionally according to all columns' 157 | flexGrow values. Defaults to zero (no-flexing). 158 | 159 | type: `number` 160 | 161 | 162 | ### `isResizable` 163 | 164 | Whether the column can be resized with the 165 | FixedDataTableColumnResizeHandle. Please note that if a column 166 | has a flex grow, once you resize the column this will be set to 0. 167 | 168 | This property only provides the UI for the column resizing. If this 169 | is set to true, you will need ot se the onColumnResizeEndCallback table 170 | property and render your columns appropriately. 171 | 172 | type: `bool` 173 | 174 | 175 | ### `allowCellsRecycling` 176 | 177 | Experimental feature 178 | Whether cells in this column can be removed from document when outside 179 | of viewport as a result of horizontal scrolling. 180 | Setting this property to true allows the table to not render cells in 181 | particular column that are outside of viewport for visible rows. This 182 | allows to create table with many columns and not have vertical scrolling 183 | performance drop. 184 | Setting the property to false will keep previous behaviour and keep 185 | cell rendered if the row it belongs to is visible. 186 | 187 | type: `bool` 188 | defaultValue: `false` 189 | 190 | -------------------------------------------------------------------------------- /src/vendor_upstream/dom/DOMMouseMoveTracker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * This class listens to events on the document and then updates a react 10 | * component through callbacks. 11 | * Please note that captureMouseMove must be called in 12 | * order to initialize listeners on mousemove and mouseup. 13 | * releaseMouseMove must be called to remove them. It is important to 14 | * call releaseMouseMoves since mousemove is expensive to listen to. 15 | * 16 | * @providesModule DOMMouseMoveTracker 17 | * @typechecks 18 | */ 19 | 20 | 'use strict'; 21 | 22 | var EventListener = require('EventListener'); 23 | 24 | var cancelAnimationFramePolyfill = require('cancelAnimationFramePolyfill'); 25 | var requestAnimationFramePolyfill = require('requestAnimationFramePolyfill'); 26 | 27 | class DOMMouseMoveTracker { 28 | /** 29 | * onMove is the callback that will be called on every mouse move. 30 | * onMoveEnd is called on mouse up when movement has ended. 31 | */ 32 | constructor( 33 | /*function*/ onMove, 34 | /*function*/ onMoveEnd, 35 | /*DOMElement*/ domNode) { 36 | this._isDragging = false; 37 | this._animationFrameID = null; 38 | this._domNode = domNode; 39 | this._onMove = onMove; 40 | this._onMoveEnd = onMoveEnd; 41 | this._onMouseMove = this._onMouseMove.bind(this); 42 | this._onMouseUp = this._onMouseUp.bind(this); 43 | this._didMouseMove = this._didMouseMove.bind(this); 44 | } 45 | 46 | /** 47 | * This is to set up the listeners for listening to mouse move 48 | * and mouse up signaling the movement has ended. Please note that these 49 | * listeners are added at the document.body level. It takes in an event 50 | * in order to grab inital state. 51 | */ 52 | captureMouseMoves(/*object*/ event) { 53 | if (!this._eventMoveToken && !this._eventUpToken) { 54 | this._eventMoveToken = EventListener.listen( 55 | this._domNode, 56 | 'mousemove', 57 | this._onMouseMove 58 | ); 59 | this._eventUpToken = EventListener.listen( 60 | this._domNode, 61 | 'mouseup', 62 | this._onMouseUp 63 | ); 64 | } 65 | 66 | if (!this._isDragging) { 67 | this._deltaX = 0; 68 | this._deltaY = 0; 69 | this._isDragging = true; 70 | this._x = event.clientX; 71 | this._y = event.clientY; 72 | } 73 | event.preventDefault(); 74 | } 75 | 76 | /** 77 | * These releases all of the listeners on document.body. 78 | */ 79 | releaseMouseMoves() { 80 | if (this._eventMoveToken && this._eventUpToken) { 81 | this._eventMoveToken.remove(); 82 | this._eventMoveToken = null; 83 | this._eventUpToken.remove(); 84 | this._eventUpToken = null; 85 | } 86 | 87 | if (this._animationFrameID !== null) { 88 | cancelAnimationFramePolyfill(this._animationFrameID); 89 | this._animationFrameID = null; 90 | } 91 | 92 | if (this._isDragging) { 93 | this._isDragging = false; 94 | this._x = null; 95 | this._y = null; 96 | } 97 | } 98 | 99 | /** 100 | * Returns whether or not if the mouse movement is being tracked. 101 | */ 102 | isDragging() /*boolean*/{ 103 | return this._isDragging; 104 | } 105 | 106 | /** 107 | * Calls onMove passed into constructor and updates internal state. 108 | */ 109 | _onMouseMove(/*object*/ event) { 110 | var x = event.clientX; 111 | var y = event.clientY; 112 | 113 | this._deltaX += (x - this._x); 114 | this._deltaY += (y - this._y); 115 | 116 | if (this._animationFrameID === null) { 117 | // The mouse may move faster then the animation frame does. 118 | // Use `requestAnimationFramePolyfill` to avoid over-updating. 119 | this._animationFrameID = 120 | requestAnimationFramePolyfill(this._didMouseMove); 121 | } 122 | 123 | this._x = x; 124 | this._y = y; 125 | event.preventDefault(); 126 | } 127 | 128 | _didMouseMove() { 129 | this._animationFrameID = null; 130 | this._onMove(this._deltaX, this._deltaY); 131 | this._deltaX = 0; 132 | this._deltaY = 0; 133 | } 134 | 135 | /** 136 | * Calls onMoveEnd passed into constructor and updates internal state. 137 | */ 138 | _onMouseUp() { 139 | if (this._animationFrameID) { 140 | this._didMouseMove(); 141 | } 142 | this._onMoveEnd(); 143 | } 144 | } 145 | 146 | module.exports = DOMMouseMoveTracker; 147 | -------------------------------------------------------------------------------- /src/FixedDataTableRowBuffer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule FixedDataTableRowBuffer 10 | * @typechecks 11 | */ 12 | 13 | 'use strict'; 14 | 15 | var IntegerBufferSet = require('IntegerBufferSet'); 16 | 17 | var clamp = require('clamp'); 18 | var invariant = require('invariant'); 19 | var MIN_BUFFER_ROWS = 3; 20 | var MAX_BUFFER_ROWS = 6; 21 | 22 | // FixedDataTableRowBuffer is a helper class that executes row buffering 23 | // logic for FixedDataTable. It figures out which rows should be rendered 24 | // and in which positions. 25 | class FixedDataTableRowBuffer { 26 | constructor( 27 | /*number*/ rowsCount, 28 | /*number*/ defaultRowHeight, 29 | /*number*/ viewportHeight, 30 | /*?function*/ rowHeightGetter 31 | ) { 32 | invariant( 33 | defaultRowHeight !== 0, 34 | "defaultRowHeight musn't be equal 0 in FixedDataTableRowBuffer" 35 | ); 36 | 37 | this._bufferSet = new IntegerBufferSet(); 38 | this._defaultRowHeight = defaultRowHeight; 39 | this._viewportRowsBegin = 0; 40 | this._viewportRowsEnd = 0; 41 | this._maxVisibleRowCount = Math.ceil(viewportHeight / defaultRowHeight) + 1; 42 | this._bufferRowsCount = clamp( 43 | Math.floor(this._maxVisibleRowCount/2), 44 | MIN_BUFFER_ROWS, 45 | MAX_BUFFER_ROWS 46 | ); 47 | this._rowsCount = rowsCount; 48 | this._rowHeightGetter = rowHeightGetter; 49 | this._rows = []; 50 | this._viewportHeight = viewportHeight; 51 | 52 | this.getRows = this.getRows.bind(this); 53 | this.getRowsWithUpdatedBuffer = this.getRowsWithUpdatedBuffer.bind(this); 54 | } 55 | 56 | getRowsWithUpdatedBuffer() /*array*/ { 57 | var remainingBufferRows = 2 * this._bufferRowsCount; 58 | var bufferRowIndex = 59 | Math.max(this._viewportRowsBegin - this._bufferRowsCount, 0); 60 | while (bufferRowIndex < this._viewportRowsBegin) { 61 | this._addRowToBuffer( 62 | bufferRowIndex, 63 | this._viewportRowsBegin, 64 | this._viewportRowsEnd - 1 65 | ); 66 | bufferRowIndex++; 67 | remainingBufferRows--; 68 | } 69 | bufferRowIndex = this._viewportRowsEnd; 70 | while (bufferRowIndex < this._rowsCount && remainingBufferRows > 0) { 71 | this._addRowToBuffer( 72 | bufferRowIndex, 73 | this._viewportRowsBegin, 74 | this._viewportRowsEnd - 1 75 | ); 76 | bufferRowIndex++; 77 | remainingBufferRows--; 78 | } 79 | return this._rows; 80 | } 81 | 82 | getRows( 83 | /*number*/ firstRowIndex, 84 | /*number*/ firstRowOffset 85 | ) /*array*/ { 86 | var top = firstRowOffset; 87 | var totalHeight = top; 88 | var rowIndex = firstRowIndex; 89 | var endIndex = 90 | Math.min(firstRowIndex + this._maxVisibleRowCount, this._rowsCount); 91 | 92 | this._viewportRowsBegin = firstRowIndex; 93 | while (rowIndex < endIndex || 94 | (totalHeight < this._viewportHeight && rowIndex < this._rowsCount)) { 95 | this._addRowToBuffer( 96 | rowIndex, 97 | firstRowIndex, 98 | endIndex - 1 99 | ); 100 | totalHeight += this._rowHeightGetter(rowIndex); 101 | ++rowIndex; 102 | // Store index after the last viewport row as end, to be able to 103 | // distinguish when there are no rows rendered in viewport 104 | this._viewportRowsEnd = rowIndex; 105 | } 106 | 107 | return this._rows; 108 | } 109 | 110 | _addRowToBuffer( 111 | /*number*/ rowIndex, 112 | /*number*/ firstViewportRowIndex, 113 | /*number*/ lastViewportRowIndex 114 | ) { 115 | var rowPosition = this._bufferSet.getValuePosition(rowIndex); 116 | var viewportRowsCount = lastViewportRowIndex - firstViewportRowIndex + 1; 117 | var allowedRowsCount = viewportRowsCount + this._bufferRowsCount * 2; 118 | if (rowPosition === null && 119 | this._bufferSet.getSize() >= allowedRowsCount) { 120 | rowPosition = 121 | this._bufferSet.replaceFurthestValuePosition( 122 | firstViewportRowIndex, 123 | lastViewportRowIndex, 124 | rowIndex 125 | ); 126 | } 127 | if (rowPosition === null) { 128 | // We can't reuse any of existing positions for this row. We have to 129 | // create new position 130 | rowPosition = this._bufferSet.getNewPositionForValue(rowIndex); 131 | this._rows[rowPosition] = rowIndex; 132 | } else { 133 | // This row already is in the table with rowPosition position or it 134 | // can replace row that is in that position 135 | this._rows[rowPosition] = rowIndex; 136 | } 137 | } 138 | } 139 | 140 | module.exports = FixedDataTableRowBuffer; 141 | -------------------------------------------------------------------------------- /src/FixedDataTableColumnResizeHandle.react.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * This is to be used with the FixedDataTable. It is a read line 10 | * that when you click on a column that is resizable appears and allows 11 | * you to resize the corresponding column. 12 | * 13 | * @providesModule FixedDataTableColumnResizeHandle.react 14 | * @typechecks 15 | */ 16 | 17 | var DOMMouseMoveTracker = require('DOMMouseMoveTracker'); 18 | var Locale = require('Locale'); 19 | var React = require('React'); 20 | var ReactComponentWithPureRenderMixin = require('ReactComponentWithPureRenderMixin'); 21 | 22 | var clamp = require('clamp'); 23 | var cx = require('cx'); 24 | 25 | var {PropTypes} = React; 26 | 27 | var FixedDataTableColumnResizeHandle = React.createClass({ 28 | mixins: [ReactComponentWithPureRenderMixin], 29 | 30 | propTypes: { 31 | visible: PropTypes.bool.isRequired, 32 | 33 | /** 34 | * This is the height of the line 35 | */ 36 | height: PropTypes.number.isRequired, 37 | 38 | /** 39 | * Offset from left border of the table, please note 40 | * that the line is a border on diff. So this is really the 41 | * offset of the column itself. 42 | */ 43 | leftOffset: PropTypes.number.isRequired, 44 | 45 | /** 46 | * Height of the clickable region of the line. 47 | * This is assumed to be at the top of the line. 48 | */ 49 | knobHeight: PropTypes.number.isRequired, 50 | 51 | /** 52 | * The line is a border on a diff, so this is essentially 53 | * the width of column. 54 | */ 55 | initialWidth: PropTypes.number, 56 | 57 | /** 58 | * The minimum width this dragger will collapse to 59 | */ 60 | minWidth: PropTypes.number, 61 | 62 | /** 63 | * The maximum width this dragger will collapse to 64 | */ 65 | maxWidth: PropTypes.number, 66 | 67 | /** 68 | * Initial click event on the header cell. 69 | */ 70 | initialEvent: PropTypes.object, 71 | 72 | /** 73 | * When resizing is complete this is called. 74 | */ 75 | onColumnResizeEnd: PropTypes.func, 76 | 77 | /** 78 | * Column key for the column being resized. 79 | */ 80 | columnKey: PropTypes.oneOfType([ 81 | PropTypes.string, 82 | PropTypes.number 83 | ]), 84 | }, 85 | 86 | getInitialState() /*object*/ { 87 | return { 88 | width: 0, 89 | cursorDelta: 0 90 | }; 91 | }, 92 | 93 | componentWillReceiveProps(/*object*/ newProps) { 94 | if (newProps.initialEvent && !this._mouseMoveTracker.isDragging()) { 95 | this._mouseMoveTracker.captureMouseMoves(newProps.initialEvent); 96 | this.setState({ 97 | width: newProps.initialWidth, 98 | cursorDelta: newProps.initialWidth 99 | }); 100 | } 101 | }, 102 | 103 | componentDidMount() { 104 | this._mouseMoveTracker = new DOMMouseMoveTracker( 105 | this._onMove, 106 | this._onColumnResizeEnd, 107 | document.body 108 | ); 109 | }, 110 | 111 | componentWillUnmount() { 112 | this._mouseMoveTracker.releaseMouseMoves(); 113 | this._mouseMoveTracker = null; 114 | }, 115 | 116 | render() /*object*/ { 117 | var style = { 118 | width: this.state.width, 119 | height: this.props.height, 120 | }; 121 | if (Locale.isRTL()) { 122 | style.right = this.props.leftOffset; 123 | } else { 124 | style.left = this.props.leftOffset; 125 | } 126 | return ( 127 |
134 |
138 |
139 | ); 140 | }, 141 | 142 | _onMove(/*number*/ deltaX) { 143 | if (Locale.isRTL()) { 144 | deltaX = -deltaX; 145 | } 146 | var newWidth = this.state.cursorDelta + deltaX; 147 | var newColumnWidth = 148 | clamp(newWidth, this.props.minWidth, this.props.maxWidth); 149 | 150 | // Please note cursor delta is the different between the currently width 151 | // and the new width. 152 | this.setState({ 153 | width: newColumnWidth, 154 | cursorDelta: newWidth 155 | }); 156 | }, 157 | 158 | _onColumnResizeEnd() { 159 | this._mouseMoveTracker.releaseMouseMoves(); 160 | this.props.onColumnResizeEnd( 161 | this.state.width, 162 | this.props.columnKey 163 | ); 164 | }, 165 | }); 166 | 167 | module.exports = FixedDataTableColumnResizeHandle; 168 | -------------------------------------------------------------------------------- /dist/fixed-data-table-style.css: -------------------------------------------------------------------------------- 1 | /** 2 | * FixedDataTable v0.6.0 3 | * 4 | * Copyright (c) 2015, Facebook, Inc. 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. An additional grant 9 | * of patent rights can be found in the PATENTS file in the same directory. 10 | */ 11 | 12 | /** 13 | * Copyright (c) 2015, Facebook, Inc. 14 | * All rights reserved. 15 | * 16 | * This source code is licensed under the BSD-style license found in the 17 | * LICENSE file in the root directory of this source tree. An additional grant 18 | * of patent rights can be found in the PATENTS file in the same directory. 19 | * 20 | * @providesModule Scrollbar 21 | * 22 | */ 23 | 24 | /** 25 | * Scrollbars. 26 | */ 27 | 28 | /* Touching the scroll-track directly makes the scroll-track bolder */ 29 | .public_Scrollbar_main.public_Scrollbar_mainActive, 30 | .public_Scrollbar_main:hover { 31 | background-color: rgba(255, 255, 255, 0.8); 32 | } 33 | 34 | .public_Scrollbar_mainOpaque, 35 | .public_Scrollbar_mainOpaque.public_Scrollbar_mainActive, 36 | .public_Scrollbar_mainOpaque:hover { 37 | background-color: #fff; 38 | } 39 | 40 | .public_Scrollbar_face:after { 41 | background-color: #c2c2c2; 42 | } 43 | 44 | .public_Scrollbar_main:hover .public_Scrollbar_face:after, 45 | .public_Scrollbar_mainActive .public_Scrollbar_face:after, 46 | .public_Scrollbar_faceActive:after { 47 | background-color: #7d7d7d; 48 | } 49 | /** 50 | * Copyright (c) 2015, Facebook, Inc. 51 | * All rights reserved. 52 | * 53 | * This source code is licensed under the BSD-style license found in the 54 | * LICENSE file in the root directory of this source tree. An additional grant 55 | * of patent rights can be found in the PATENTS file in the same directory. 56 | * 57 | * @providesModule fixedDataTable 58 | * 59 | */ 60 | 61 | /** 62 | * Table. 63 | */ 64 | .public_fixedDataTable_main { 65 | border-color: #d3d3d3; 66 | } 67 | 68 | .public_fixedDataTable_header, 69 | .public_fixedDataTable_hasBottomBorder { 70 | border-color: #d3d3d3; 71 | } 72 | 73 | .public_fixedDataTable_header .public_fixedDataTableCell_main { 74 | font-weight: bold; 75 | } 76 | 77 | .public_fixedDataTable_header, 78 | .public_fixedDataTable_header .public_fixedDataTableCell_main { 79 | background-color: #f6f7f8; 80 | background-image: -webkit-linear-gradient(#fff, #efefef); 81 | background-image: linear-gradient(#fff, #efefef); 82 | } 83 | 84 | .public_fixedDataTable_footer .public_fixedDataTableCell_main { 85 | background-color: #f6f7f8; 86 | border-color: #d3d3d3; 87 | } 88 | 89 | .public_fixedDataTable_topShadow { 90 | background: 0 0 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAECAYAAABP2FU6AAAAF0lEQVR4AWPUkNeSBhHCjJoK2twgFisAFagCCp3pJlAAAAAASUVORK5CYII=) repeat-x; 91 | } 92 | 93 | .public_fixedDataTable_bottomShadow { 94 | background: 0 0 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAECAYAAABP2FU6AAAAHElEQVQI12MwNjZmZdAT1+Nm0JDWEGZQk1GTBgAWkwIeAEp52AAAAABJRU5ErkJggg==) repeat-x; 95 | } 96 | 97 | .public_fixedDataTable_horizontalScrollbar .public_Scrollbar_mainHorizontal { 98 | background-color: #fff; 99 | } 100 | /** 101 | * Copyright (c) 2015, Facebook, Inc. 102 | * All rights reserved. 103 | * 104 | * This source code is licensed under the BSD-style license found in the 105 | * LICENSE file in the root directory of this source tree. An additional grant 106 | * of patent rights can be found in the PATENTS file in the same directory. 107 | * 108 | * @providesModule fixedDataTableCell 109 | */ 110 | 111 | /** 112 | * Table cell. 113 | */ 114 | .public_fixedDataTableCell_main { 115 | background-color: #fff; 116 | border-color: #d3d3d3; 117 | } 118 | 119 | .public_fixedDataTableCell_highlighted { 120 | background-color: #f4f4f4; 121 | } 122 | 123 | .public_fixedDataTableCell_cellContent { 124 | padding: 8px; 125 | } 126 | 127 | .public_fixedDataTableCell_columnResizerKnob { 128 | background-color: #0284ff; 129 | } 130 | /** 131 | * Copyright (c) 2015, Facebook, Inc. 132 | * All rights reserved. 133 | * 134 | * This source code is licensed under the BSD-style license found in the 135 | * LICENSE file in the root directory of this source tree. An additional grant 136 | * of patent rights can be found in the PATENTS file in the same directory. 137 | * 138 | * @providesModule fixedDataTableColumnResizerLine 139 | * 140 | */ 141 | 142 | /** 143 | * Column resizer line. 144 | */ 145 | .public_fixedDataTableColumnResizerLine_main { 146 | border-color: #0284ff; 147 | } 148 | /** 149 | * Copyright (c) 2015, Facebook, Inc. 150 | * All rights reserved. 151 | * 152 | * This source code is licensed under the BSD-style license found in the 153 | * LICENSE file in the root directory of this source tree. An additional grant 154 | * of patent rights can be found in the PATENTS file in the same directory. 155 | * 156 | * @providesModule fixedDataTableRow 157 | */ 158 | 159 | /** 160 | * Table row. 161 | */ 162 | .public_fixedDataTableRow_main { 163 | background-color: #fff; 164 | } 165 | 166 | .public_fixedDataTableRow_highlighted, 167 | .public_fixedDataTableRow_highlighted .public_fixedDataTableCell_main { 168 | background-color: #f6f7f8; 169 | } 170 | 171 | .public_fixedDataTableRow_fixedColumnsDivider { 172 | border-color: #d3d3d3; 173 | } 174 | 175 | .public_fixedDataTableRow_columnsShadow { 176 | background: 0 0 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABCAYAAAD5PA/NAAAAFklEQVQIHWPSkNeSBmJhTQVtbiDNCgASagIIuJX8OgAAAABJRU5ErkJggg==) repeat-y; 177 | } 178 | -------------------------------------------------------------------------------- /src/FixedDataTableCell.react.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * @providesModule FixedDataTableCell.react 10 | * @typechecks 11 | */ 12 | 13 | var FixedDataTableCellDefault = require('FixedDataTableCellDefault.react'); 14 | var FixedDataTableHelper = require('FixedDataTableHelper'); 15 | var React = require('React'); 16 | var cx = require('cx'); 17 | var joinClasses = require('joinClasses'); 18 | 19 | var DIR_SIGN = FixedDataTableHelper.DIR_SIGN; 20 | 21 | var {PropTypes} = React; 22 | 23 | var DEFAULT_PROPS = { 24 | align: 'left', 25 | highlighted: false, 26 | }; 27 | 28 | var FixedDataTableCell = React.createClass({ 29 | 30 | /** 31 | * PropTypes are disabled in this component, because having them on slows 32 | * down the FixedDataTable hugely in DEV mode. You can enable them back for 33 | * development, but please don't commit this component with enabled propTypes. 34 | */ 35 | propTypes_DISABLED_FOR_PERFORMANCE: { 36 | isScrolling: PropTypes.bool, 37 | align: PropTypes.oneOf(['left', 'center', 'right']), 38 | className: PropTypes.string, 39 | highlighted: PropTypes.bool, 40 | width: PropTypes.number.isRequired, 41 | minWidth: PropTypes.number, 42 | maxWidth: PropTypes.number, 43 | height: PropTypes.number.isRequired, 44 | 45 | cell: PropTypes.oneOfType([ 46 | PropTypes.string, 47 | PropTypes.element, 48 | PropTypes.func, 49 | ]), 50 | 51 | columnKey: PropTypes.oneOfType([ 52 | PropTypes.string, 53 | PropTypes.number, 54 | ]), 55 | 56 | /** 57 | * The row index that will be passed to `cellRenderer` to render. 58 | */ 59 | rowIndex: PropTypes.number.isRequired, 60 | 61 | /** 62 | * Callback for when resizer knob (in FixedDataTableCell) is clicked 63 | * to initialize resizing. Please note this is only on the cells 64 | * in the header. 65 | * @param number combinedWidth 66 | * @param number left 67 | * @param number width 68 | * @param number minWidth 69 | * @param number maxWidth 70 | * @param number|string columnKey 71 | * @param object event 72 | */ 73 | onColumnResize: PropTypes.func, 74 | 75 | /** 76 | * The left offset in pixels of the cell. 77 | */ 78 | left: PropTypes.number, 79 | }, 80 | 81 | shouldComponentUpdate(nextProps) { 82 | return ( 83 | !nextProps.isScrolling || 84 | this.props.rowIndex !== nextProps.rowIndex 85 | ); 86 | }, 87 | 88 | getDefaultProps() /*object*/ { 89 | return DEFAULT_PROPS; 90 | }, 91 | 92 | render() /*object*/ { 93 | 94 | var {height, width, columnKey, ...props} = this.props; 95 | 96 | var style = { 97 | height, 98 | width, 99 | }; 100 | 101 | if (DIR_SIGN === 1) { 102 | style.left = props.left; 103 | } else { 104 | style.right = props.left; 105 | } 106 | 107 | var className = joinClasses( 108 | cx({ 109 | 'fixedDataTableCellLayout/main': true, 110 | 'fixedDataTableCellLayout/lastChild': props.lastChild, 111 | 'fixedDataTableCellLayout/alignRight': props.align === 'right', 112 | 'fixedDataTableCellLayout/alignCenter': props.align === 'center', 113 | 'public/fixedDataTableCell/alignRight': props.align === 'right', 114 | 'public/fixedDataTableCell/highlighted': props.highlighted, 115 | 'public/fixedDataTableCell/main': true, 116 | }), 117 | props.className, 118 | ); 119 | 120 | var columnResizerComponent; 121 | if (props.onColumnResize) { 122 | var columnResizerStyle = { 123 | height 124 | }; 125 | columnResizerComponent = ( 126 |
130 |
137 |
138 | ); 139 | } 140 | 141 | var cellProps = { 142 | columnKey, 143 | height, 144 | width 145 | }; 146 | 147 | if (props.rowIndex >= 0) { 148 | cellProps.rowIndex = props.rowIndex; 149 | } 150 | 151 | var content; 152 | if (React.isValidElement(props.cell)) { 153 | content = React.cloneElement(props.cell, cellProps); 154 | } else if (typeof props.cell === 'function') { 155 | content = props.cell(cellProps); 156 | } else { 157 | content = ( 158 | 160 | {props.cell} 161 | 162 | ); 163 | } 164 | 165 | return ( 166 |
167 | {columnResizerComponent} 168 | {content} 169 |
170 | ); 171 | }, 172 | 173 | _onColumnResizerMouseDown(/*object*/ event) { 174 | this.props.onColumnResize( 175 | this.props.left, 176 | this.props.width, 177 | this.props.minWidth, 178 | this.props.maxWidth, 179 | this.props.columnKey, 180 | event 181 | ); 182 | }, 183 | }); 184 | 185 | module.exports = FixedDataTableCell; 186 | --------------------------------------------------------------------------------