Socket
Socket
Sign inDemoInstall

nuclide-commons-ui

Package Overview
Dependencies
79
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.2.0 to 0.4.0

observable-dom.js

126

addTooltip.js

@@ -12,2 +12,8 @@ 'use strict';

var _shallowequal;
function _load_shallowequal() {
return _shallowequal = _interopRequireDefault(require('shallowequal'));
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -17,2 +23,19 @@

const REREGISTER_DELAY = 100; /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
const _tooltipRequests = new Map();
const _createdTooltips = new Map();
const _toDispose = new Set();
let _timeoutHandle;
/**

@@ -26,58 +49,69 @@ * Adds a self-disposing Atom's tooltip to a react element.

* addTooltip({title: 'My awesome tooltip', delay: 100, placement: 'top'})(c);
* this._myDiv = c;
* _myDiv = c;
* }} />
*/
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
function addTooltip(options) {
let prevRefDisposable;
let node;
let immediate = null;
return elementRef => {
clearImmediate(immediate);
if (prevRefDisposable != null) {
prevRefDisposable.dispose();
prevRefDisposable = null;
_scheduleTooltipMaintenance();
if (elementRef == null) {
if (node != null) {
_toDispose.add(node);
}
return;
}
if (elementRef != null) {
const node = _reactDom.default.findDOMNode(elementRef);
node = _reactDom.default.findDOMNode(elementRef);
_tooltipRequests.set(node, options);
};
}
const initializeTooltip = () => {
prevRefDisposable = atom.tooltips.add(
// $FlowFixMe
node,
// $FlowFixMe
Object.assign({
keyBindingTarget: node
}, options));
};
function _registrationUndoesDisposal(node, options) {
const created = _createdTooltips.get(node);
if (created == null) {
return false;
}
if (options.keyBindingTarget) {
// If the user has supplied their own `keyBindingTarget`, we must ensure
// the CSS slectors are evaluated _before_ the next event loop, since
// the DOM state may change between now and then.
initializeTooltip();
} else {
// Sooooo... Atom tooltip does the keybinding lookup at creation time
// instead of display time. And, it uses a CSS selector to figure out
// if the current element matches the selector. The problem is that at
// this point, the element is created but not yet mounted in the DOM,
// so it's not going to match the selector and will not return a
// keybinding. By deferring it to the end of the event loop, it is now
// in the DOM and has the proper keybinding.
immediate = setImmediate(initializeTooltip);
}
return (0, (_shallowequal || _load_shallowequal()).default)(options, created.options);
}
function _scheduleTooltipMaintenance() {
if (_timeoutHandle != null) {
return;
}
_timeoutHandle = setTimeout(() => _performMaintenance(), REREGISTER_DELAY);
}
function _performMaintenance() {
_timeoutHandle = null;
for (const [node, options] of _tooltipRequests.entries()) {
if (_registrationUndoesDisposal(node, options)) {
_toDispose.delete(node);
_tooltipRequests.delete(node);
}
};
}
_toDispose.forEach(node => {
const created = _createdTooltips.get(node);
if (created != null) {
created.disposable.dispose();
_createdTooltips.delete(node);
}
});
_toDispose.clear();
for (const [node, options] of _tooltipRequests.entries()) {
// $FlowIgnore
const disposable = atom.tooltips.add(node, Object.assign({
keyBindingTarget: node
}, options));
_createdTooltips.set(node, { disposable, options });
}
_tooltipRequests.clear();
}

@@ -18,4 +18,2 @@ 'use strict';

var _reactDom = _interopRequireDefault(require('react-dom'));
var _string;

@@ -34,2 +32,14 @@

*/
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
class AtomInput extends _react.Component {

@@ -157,2 +167,3 @@

mini: true,
ref: rootNode => this._rootNode = rootNode,
onClick: this.props.onClick,

@@ -183,4 +194,9 @@ onFocus: this.props.onFocus,

getTextEditorElement() {
if (!(this._rootNode != null)) {
throw new Error('Invariant violation: "this._rootNode != null"');
}
// $FlowFixMe
return _reactDom.default.findDOMNode(this);
return this._rootNode;
}

@@ -200,14 +216,3 @@

}
exports.AtomInput = AtomInput; /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
exports.AtomInput = AtomInput;
AtomInput.defaultProps = {

@@ -214,0 +219,0 @@ disabled: false,

@@ -16,4 +16,2 @@ 'use strict';

var _reactDom = _interopRequireDefault(require('react-dom'));
var _atom = require('atom');

@@ -37,14 +35,16 @@

const doNothing = () => {}; /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
const doNothing = () => {};
function setupTextEditor(props) {

@@ -82,3 +82,3 @@ const textBuffer = props.textBuffer || new _atom.TextBuffer();

if (props.readOnly) {
(0, (_textEditor || _load_textEditor()).enforceReadOnly)(textEditor);
(0, (_textEditor || _load_textEditor()).enforceReadOnlyEditor)(textEditor);

@@ -109,2 +109,7 @@ // Remove the cursor line decorations because that's distracting in read-only mode.

_updateTextEditor(setup) {
const container = this._rootElement;
if (container == null) {
return;
}
this._editorDisposables.dispose();

@@ -115,3 +120,2 @@ const { textEditor, disposables } = setup;

const container = _reactDom.default.findDOMNode(this);
const textEditorElement = this._textEditorElement = document.createElement('atom-text-editor');

@@ -130,14 +134,7 @@ textEditorElement.setModel(textEditor);

this._editorDisposables.add(textEditorElement.onDidAttach(() => {
const correctlySizedElement = textEditorElement.querySelector('* /deep/ .lines > :first-child');
const correctlySizedElement = textEditorElement.querySelector('.lines > :first-child');
if (correctlySizedElement == null) {
return;
}
let { width } = correctlySizedElement.style;
// For compatibility with Atom < 1.19.
// TODO(#19829039): Remove this after upgrading.
if (!width && correctlySizedElement.children.length > 0) {
width = correctlySizedElement.children[0].style.width;
}
// $FlowFixMe
container.style.width = width;
container.style.width = correctlySizedElement.style.width;
}));

@@ -147,6 +144,16 @@ }

// Attach to DOM.
// $FlowFixMe
container.innerHTML = '';
// $FlowFixMe
container.appendChild(textEditorElement);
if (this.props.onConfirm != null) {
this._editorDisposables.add(atom.commands.add(textEditorElement, {
'core:confirm': () => {
if (!(this.props.onConfirm != null)) {
throw new Error('Invariant violation: "this.props.onConfirm != null"');
}
this.props.onConfirm();
}
}));
}
}

@@ -237,3 +244,6 @@

});
return _react.createElement('div', { className: className });
return _react.createElement('div', {
className: className,
ref: rootElement => this._rootElement = rootElement
});
}

@@ -240,0 +250,0 @@

@@ -13,5 +13,5 @@ "use strict";

/** A Block. */
const Block = exports.Block = (props
const Block = exports.Block = props =>
// $FlowFixMe(>=0.53.0) Flow suppress
) => _react.createElement(
_react.createElement(
"div",

@@ -18,0 +18,0 @@ { className: "block" },

@@ -10,4 +10,2 @@ 'use strict';

var _reactDom = _interopRequireDefault(require('react-dom'));
var _classnames;

@@ -39,2 +37,14 @@

*/
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
class Checkbox extends _react.PureComponent {

@@ -67,4 +77,3 @@

_setIndeterminate() {
// $FlowFixMe
_reactDom.default.findDOMNode(this.refs.input).indeterminate = this.props.indeterminate;
this.refs.input.indeterminate = this.props.indeterminate;
}

@@ -115,14 +124,3 @@

}
exports.Checkbox = Checkbox; /**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
* @format
*/
exports.Checkbox = Checkbox;
Checkbox.defaultProps = {

@@ -129,0 +127,0 @@ disabled: false,

@@ -62,3 +62,3 @@ 'use strict';

// any particular event ordering between synthentic events and native
// events, and we requrie that the internal event fire before the global event.
// events, and we require that the internal event fire before the global event.
// https://discuss.reactjs.org/t/ordering-of-native-and-react-events/829/2

@@ -65,0 +65,0 @@ node.addEventListener('click', this._handleInternalClick);

{
"name": "nuclide-commons-ui",
"version": "0.2.0",
"version": "0.4.0",
"description": "Common Nuclide UI components.",

@@ -17,11 +17,12 @@ "license": "BSD-3-Clause",

"escape-string-regexp": "1.0.5",
"nuclide-commons": "0.2.0",
"nuclide-commons-atom": "0.2.0",
"react": "15.3.1",
"react-dom": "15.3.1",
"rxjs": "5.3.1"
},
"devDependencies": {
"react-addons-test-utils": "15.3.1"
"idx": "1.2.0",
"invariant": "2.2.2",
"nuclide-commons": "0.4.0",
"nuclide-commons-atom": "0.4.0",
"nullthrows": "1.0.0",
"react": "16.0.0",
"react-dom": "16.0.0",
"rxjs": "5.3.1",
"shallowequal": "0.2.2"
}
}

@@ -138,2 +138,3 @@ 'use strict';

default:
size;
throw new Error(`Invalid size: ${size}`);

@@ -140,0 +141,0 @@ }

@@ -8,2 +8,8 @@ 'use strict';

var _nullthrows;
function _load_nullthrows() {
return _nullthrows = _interopRequireDefault(require('nullthrows'));
}
var _classnames;

@@ -15,8 +21,12 @@

var _idx;
function _load_idx() {
return _idx = _interopRequireDefault(require('idx'));
}
var _react = _interopRequireWildcard(require('react'));
var _reactDom = _interopRequireDefault(require('react-dom'));
var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');
var _atom = require('atom');
var _Icon;

@@ -34,2 +44,14 @@

var _observableDom;
function _load_observableDom() {
return _observableDom = require('./observable-dom');
}
var _scrollIntoView;
function _load_scrollIntoView() {
return _scrollIntoView = require('./scrollIntoView');
}
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

@@ -51,2 +73,4 @@

const DEFAULT_MIN_COLUMN_WIDTH = 40;
const DefaultEmptyComponent = () => _react.createElement(

@@ -58,73 +82,81 @@ 'div',

/**
* Design concerns:
*
* 1. Because of how it's used throughout the codebase, this Table needs to do all of the folowing:
* * Fill the available width of its parent
* * Automatically be tall enough to accommodate its contents
* * Have a vertically scrollable body if its parent is too small to accommodate the contents
* 2. We need to support min widths for columns. Resizing the window or one of the component's
* containers should not cause a column to dip below its min width.
*
* This ends up being a surprisingly constraining set of concerns!
*
* * We must guarantee that the contents of the table do not define the container's size.
* Otherwise, this we would be unable to determine the "available area" without hiding the
* contents, measuring, and then showing the contents again. Likewise, we could get stuck in
* a loop where we set the contents' size, which triggers the resize observer, which causes
* us to remeasure the container size and adjust the contents, which triggers the resize
* observer...
* * We can't use CSS for min width. Resizing one column affects the width of another; if we
* make column A smaller, column B needs to get wider to fill the extra space. But using CSS
* for min-width means we wouldn't know the true size, and therefore how to adjust B
* appropriately.
*
* To address these, we define our columns using percentage widths. Unfortunately, this means that
* our table may behave a little strangely when the available area is less than the sum of the
* minimum widths of the columns. (Ideally, the table would scroll horizontally in this case.)
*/
class Table extends _react.Component {
// Active while resizing.
constructor(props) {
super(props);
this._globalEventsDisposable = null;
this._resizeStartX = null;
this._tableWidth = null;
this._columnBeingResized = null;
this._handleResizerGlobalMouseUp = this._handleResizerGlobalMouseUp.bind(this);
this._handleResizerGlobalMouseMove = this._handleResizerGlobalMouseMove.bind(this);
this.state = {
columnWidthRatios: this._getInitialWidthsForColumns(this.props.columns)
};
this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(() => {
this._unsubscribeFromGlobalEvents();
});
}
_getInitialWidthsForColumns(columns) {
const columnWidthRatios = {};
let assignedWidth = 0;
const unresolvedColumns = [];
columns.forEach(column => {
const { key, width } = column;
if (width != null) {
columnWidthRatios[key] = width;
assignedWidth += width;
this._handleResizerGlobalMouseMove = (event, startX, startWidths, location, tableWidth) => {
const pxToRatio = px => px / tableWidth;
const delta = pxToRatio(event.pageX - startX);
const { leftColumnKey, rightColumnKey } = location;
// Determine which column is shrinking and which is growing. This will allow us to apply the min
// width limitations correctly.
let shrinkingColumnKey;
let growingColumnKey;
if (delta < 0) {
[shrinkingColumnKey, growingColumnKey] = [leftColumnKey, rightColumnKey];
} else {
unresolvedColumns.push(column);
[shrinkingColumnKey, growingColumnKey] = [rightColumnKey, leftColumnKey];
}
});
const residualColumnWidth = (1 - assignedWidth) / unresolvedColumns.length;
unresolvedColumns.forEach(column => {
columnWidthRatios[column.key] = residualColumnWidth;
});
return columnWidthRatios;
}
/* Applies sizing constraints, and returns whether the column width actually changed. */
_updateWidths(resizedColumn, newColumnSize) {
const { columnWidthRatios } = this.state;
const { columns } = this.props;
const originalColumnSize = columnWidthRatios[resizedColumn];
const columnAfterResizedColumn = columns[columns.findIndex(column => column.key === resizedColumn) + 1].key;
const followingColumnSize = columnWidthRatios[columnAfterResizedColumn];
const constrainedNewColumnSize = Math.max(0, Math.min(newColumnSize, followingColumnSize + originalColumnSize));
if (Math.abs(newColumnSize - constrainedNewColumnSize) > Number.EPSILON) {
return false;
}
const updatedColumnWidths = {};
columns.forEach(column => {
const { key } = column;
let width;
if (column.key === resizedColumn) {
width = constrainedNewColumnSize;
} else if (column.key === columnAfterResizedColumn) {
width = columnWidthRatios[resizedColumn] - constrainedNewColumnSize + columnWidthRatios[key];
} else {
width = columnWidthRatios[key];
const prevShrinkingColumnWidth = startWidths[shrinkingColumnKey];
const prevGrowingColumnWidth = startWidths[growingColumnKey];
const shrinkingColumn = this.props.columns.find(column => column.key === shrinkingColumnKey);
if (!(shrinkingColumn != null)) {
throw new Error('Invariant violation: "shrinkingColumn != null"');
}
updatedColumnWidths[key] = width;
});
this.setState({
columnWidthRatios: updatedColumnWidths
});
return true;
const shrinkingColumnMinWidth = pxToRatio(shrinkingColumn.minWidth == null ? DEFAULT_MIN_COLUMN_WIDTH : shrinkingColumn.minWidth);
const nextShrinkingColumnWidth = Math.max(shrinkingColumnMinWidth, prevShrinkingColumnWidth - Math.abs(delta));
const actualChange = nextShrinkingColumnWidth - prevShrinkingColumnWidth;
const nextGrowingColumnWidth = prevGrowingColumnWidth - actualChange;
this.setState({
columnWidths: Object.assign({}, this.state.columnWidths, {
[shrinkingColumnKey]: nextShrinkingColumnWidth,
[growingColumnKey]: nextGrowingColumnWidth
})
});
};
this._resizingDisposable = null;
this.state = {
columnWidths: null,
usingKeyboard: false
};
}
_handleResizerMouseDown(key, event) {
if (this._globalEventsDisposable != null) {
this._unsubscribeFromGlobalEvents();
_handleResizerMouseDown(event, resizerLocation) {
if (this._resizingDisposable != null) {
this._stopResizing();
}

@@ -136,55 +168,129 @@ // Prevent browser from initiating drag events on accidentally selected elements.

}
document.addEventListener('mousemove', this._handleResizerGlobalMouseMove);
document.addEventListener('mouseup', this._handleResizerGlobalMouseUp);
this._resizeStartX = event.pageX;
// $FlowFixMe
this._tableWidth = _reactDom.default.findDOMNode(this.refs.table).getBoundingClientRect().width;
this._columnBeingResized = key;
this._globalEventsDisposable = new _atom.Disposable(() => {
document.removeEventListener('mousemove', this._handleResizerGlobalMouseMove);
document.removeEventListener('mouseup', this._handleResizerGlobalMouseUp);
this._resizeStartX = null;
this._tableWidth = null;
this._columnBeingResized = null;
});
const tableWidth = this.refs.table.getBoundingClientRect().width;
const startX = event.pageX;
const startWidths = this.state.columnWidths;
if (!(startWidths != null)) {
throw new Error('Invariant violation: "startWidths != null"');
}
this._resizingDisposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(_rxjsBundlesRxMinJs.Observable.fromEvent(document, 'mousemove').subscribe(evt => {
this._handleResizerGlobalMouseMove(evt, startX, startWidths, resizerLocation, tableWidth);
}), _rxjsBundlesRxMinJs.Observable.fromEvent(document, 'mouseup').subscribe(() => {
this._stopResizing();
}));
}
_unsubscribeFromGlobalEvents() {
if (this._globalEventsDisposable == null) {
_stopResizing() {
if (this._resizingDisposable == null) {
return;
}
this._globalEventsDisposable.dispose();
this._globalEventsDisposable = null;
this._resizingDisposable.dispose();
this._resizingDisposable = null;
}
_handleResizerGlobalMouseUp(event) {
this._unsubscribeFromGlobalEvents();
componentDidMount() {
const el = (0, (_nullthrows || _load_nullthrows()).default)(this._rootNode);
this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(new (_observableDom || _load_observableDom()).ResizeObservable(el).startWith(null).map(() => el.offsetWidth).filter(tableWidth => tableWidth > 0).subscribe(tableWidth => {
// Update the column widths to account for minimum widths. This logic could definitely be
// improved. As it is now, if you resize the table to be very small and then make it large
// again, the proportions from when it was at its smallest will be preserved. If no
// columns have min widths, then this is what you want. But if a minimum width prevented
// one or more of the columns from shrinking, you'll probably consider them too wide when
// the table's expanded.
const preferredColumnWidths = this.state.columnWidths || getInitialPercentageWidths(this.props.columns);
this.setState({
columnWidths: ensureMinWidths(preferredColumnWidths, this._getMinWidths(), tableWidth, this.props.columns.map(c => c.key))
});
}), () => {
this._stopResizing();
}, atom.commands.add(el, {
'core:move-up': event => {
this.setState({ usingKeyboard: true });
this._moveSelection(-1, event);
},
'core:move-down': event => {
this.setState({ usingKeyboard: true });
this._moveSelection(1, event);
},
'core:confirm': event => {
this.setState({ usingKeyboard: true });
const { rows, selectedIndex, onConfirm } = this.props;
if (onConfirm == null || selectedIndex == null) {
return;
}
const selectedRow = rows[selectedIndex];
const selectedItem = selectedRow && selectedRow.data;
if (selectedItem != null) {
onConfirm(selectedItem, selectedIndex);
}
}
}), () => {
if (this._mouseMoveDisposable != null) {
this._mouseMoveDisposable.dispose();
}
});
}
_handleResizerGlobalMouseMove(event) {
if (this._resizeStartX == null || this._tableWidth == null || this._columnBeingResized == null) {
return;
componentWillUnmount() {
this._disposables.dispose();
}
_getMinWidths() {
const minWidths = {};
this.props.columns.forEach(column => {
minWidths[column.key] = column.minWidth;
});
return minWidths;
}
componentDidUpdate(prevProps, prevState) {
if (this._tableBody != null && this.props.selectedIndex != null && this.props.selectedIndex !== prevProps.selectedIndex) {
const selectedRow = this._tableBody.children[this.props.selectedIndex];
if (selectedRow != null) {
(0, (_scrollIntoView || _load_scrollIntoView()).scrollIntoViewIfNeeded)(selectedRow);
}
}
const { pageX } = event;
const deltaX = pageX - this._resizeStartX;
const currentColumnSize = this.state.columnWidthRatios[this._columnBeingResized];
const didUpdate = this._updateWidths(this._columnBeingResized, (this._tableWidth * currentColumnSize + deltaX) / this._tableWidth);
if (didUpdate) {
this._resizeStartX = pageX;
if (this.state.usingKeyboard !== prevState.usingKeyboard) {
if (this._mouseMoveDisposable != null) {
this._mouseMoveDisposable.dispose();
}
if (this.state.usingKeyboard) {
this._mouseMoveDisposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(_rxjsBundlesRxMinJs.Observable.fromEvent(document, 'mousemove').take(1).subscribe(() => {
this.setState({ usingKeyboard: false });
}));
}
}
}
componentWillUnmount() {
this._disposables.dispose();
focus() {
if (this._tableBody == null) {
return;
}
let el = document.activeElement;
while (el != null) {
if (el === this._tableBody) {
// Already focused!
return;
}
el = el.parentNode;
}
this._tableBody.focus();
}
_handleSortByColumn(sortedBy) {
const { onSort, sortDescending, sortedColumn } = this.props;
if (onSort == null) {
_moveSelection(offset, event) {
const { selectedIndex } = this.props;
if (selectedIndex == null) {
return;
}
onSort(sortedBy, sortDescending == null || sortedBy !== sortedColumn ? false : !sortDescending);
const nextSelectedIndex = selectedIndex + offset;
if (nextSelectedIndex < 0 || nextSelectedIndex >= this.props.rows.length || nextSelectedIndex === selectedIndex) {
return;
}
this._selectRow({ index: nextSelectedIndex, event });
}
_handleRowClick(selectedIndex, event) {
_selectRow(options) {
const { index: selectedIndex, event, confirm } = options;
const { onSelect, onWillSelect, rows } = this.props;

@@ -194,3 +300,4 @@ if (onSelect == null) {

}
const selectedItem = rows[selectedIndex];
const selectedRow = rows[selectedIndex];
const selectedItem = selectedRow.data;
if (onWillSelect != null) {

@@ -201,5 +308,16 @@ if (onWillSelect(selectedItem, selectedIndex, event) === false) {

}
onSelect(selectedItem.data, selectedIndex);
onSelect(selectedItem, selectedIndex, event);
if (confirm && this.props.onConfirm != null) {
this.props.onConfirm(selectedItem, selectedIndex);
}
}
_handleSortByColumn(sortedBy) {
const { onSort, sortDescending, sortedColumn } = this.props;
if (onSort == null) {
return;
}
onSort(sortedBy, sortDescending == null || sortedBy !== sortedColumn ? false : !sortDescending);
}
_renderEmptyCellContent() {

@@ -210,5 +328,20 @@ return _react.createElement('div', null);

render() {
return _react.createElement(
'div',
{
className: this.props.className,
ref: rootNode => this._rootNode = rootNode },
this._renderContents()
);
}
_renderContents() {
const { columnWidths } = this.state;
if (columnWidths == null) {
// We don't have the table width yet so we can't render the columns.
return null;
}
const {
alternateBackground,
className,
columns,

@@ -229,17 +362,27 @@ headerTitle,

) : columns.map((column, i) => {
var _ref;
const { title, key, shouldRightAlign, cellClassName } = column;
const resizeHandle = i === columns.length - 1 ? null : _react.createElement('div', {
className: 'nuclide-ui-table-header-resize-handle',
onMouseDown: this._handleResizerMouseDown.bind(this, key),
onClick: e => {
// Prevent sortable column header click event from firing.
e.stopPropagation();
}
});
const width = this.state.columnWidthRatios[key];
const leftColumnKey = column.key;
const rightColumnKey = (_ref = columns[i + 1]) != null ? _ref.key : _ref;
let resizer;
if (leftColumnKey != null && rightColumnKey != null) {
resizer = _react.createElement('div', {
className: 'nuclide-ui-table-header-resize-handle',
onMouseDown: event => {
this._handleResizerMouseDown(event, {
leftColumnKey,
rightColumnKey
});
},
onClick: e => {
// Prevent sortable column header click event from firing.
e.stopPropagation();
}
});
}
const width = columnWidths[key];
const optionalHeaderCellProps = {};
if (width != null) {
optionalHeaderCellProps.style = {
width: width * 100 + '%'
};
optionalHeaderCellProps.style = { width: `${width * 100}%` };
}

@@ -249,3 +392,5 @@ let sortIndicator;

if (sortable) {
optionalHeaderCellProps.onClick = this._handleSortByColumn.bind(this, key);
optionalHeaderCellProps.onClick = () => {
this._handleSortByColumn(key);
};
titleOverlay += ' – click to sort';

@@ -275,3 +420,3 @@ if (sortedColumn === key) {

sortIndicator,
resizeHandle
resizer
);

@@ -295,5 +440,5 @@ });

const cellStyle = {};
const width = this.state.columnWidthRatios[key];
const width = columnWidths[key];
if (width != null) {
cellStyle.width = width * 100 + '%';
cellStyle.width = `${width * 100}%`;
}

@@ -313,6 +458,10 @@ return _react.createElement(

});
const rowProps = {};
if (selectable) {
rowProps.onClick = this._handleRowClick.bind(this, i);
}
const rowProps = selectable ? {
onClick: event => {
this._selectRow({ index: i, event });
},
onDoubleClick: event => {
this._selectRow({ index: i, event, confirm: true });
}
} : {};
const isSelectedRow = selectedIndex != null && i === selectedIndex;

@@ -325,2 +474,3 @@ return _react.createElement(

'nuclide-ui-table-row-selectable': selectable,
'nuclide-ui-table-row-using-keyboard-nav': this.state.usingKeyboard,
'nuclide-ui-table-row-selected': isSelectedRow,

@@ -344,28 +494,69 @@ 'nuclide-ui-table-row-alternate': alternateBackground !== false && i % 2 === 1,

}
return _react.createElement(
const bodyClassNames = (0, (_classnames || _load_classnames()).default)('nuclide-ui-table', 'nuclide-ui-table-body',
// Using native-key-bindings prevents the up and down arrows from being captured.
{ 'native-key-bindings': !this.props.enableKeyboardNavigation });
return [_react.createElement(
'div',
{ className: className },
{ key: 'header', className: 'nuclide-ui-table', ref: 'table' },
_react.createElement(
'div',
{ className: 'nuclide-ui-table', ref: 'table' },
_react.createElement(
'div',
{ className: 'nuclide-ui-table-header' },
header
)
),
{ className: 'nuclide-ui-table-header' },
header
)
), _react.createElement(
'div',
{ key: 'body', style: scrollableBodyStyle },
_react.createElement(
'div',
{ style: scrollableBodyStyle },
_react.createElement(
'div',
{
className: 'nuclide-ui-table nuclide-ui-table-body native-key-bindings',
tabIndex: '-1' },
body
)
{
ref: el => {
this._tableBody = el;
},
className: bodyClassNames,
tabIndex: '-1' },
body
)
);
)];
}
}
exports.Table = Table;
exports.Table = Table; /**
* Get the initial size of each column as a percentage of the total.
*/
function getInitialPercentageWidths(columns) {
const columnWidthRatios = {};
let assignedWidth = 0;
const unresolvedColumns = [];
columns.forEach(column => {
const { key, width } = column;
if (width != null) {
columnWidthRatios[key] = width;
assignedWidth += width;
} else {
unresolvedColumns.push(column);
}
});
const residualColumnWidth = (1 - assignedWidth) / unresolvedColumns.length;
unresolvedColumns.forEach(column => {
columnWidthRatios[column.key] = residualColumnWidth;
});
return columnWidthRatios;
}
/**
* Convert percentage widths into actual pixel widths, taking into account minimum widths.
*/
function ensureMinWidths(preferredWidths, minWidths, tableWidth, columnOrder) {
const adjusted = {};
let remainingWidth = 1;
columnOrder.forEach(columnName => {
const minWidth = minWidths[columnName] || DEFAULT_MIN_COLUMN_WIDTH;
const minWidthRatio = minWidth / tableWidth;
const preferredWidth = preferredWidths[columnName];
const width = Math.min(remainingWidth, Math.max(minWidthRatio, preferredWidth));
adjusted[columnName] = width;
remainingWidth -= width;
});
return adjusted;
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc