UNPKG

office-ui-fabric-react

Version:

Reusable React components for building experiences for Microsoft 365.

264 lines (263 loc) • 13.5 kB
define(["require", "exports", "tslib", "react", "../../Utilities", "../../utilities/ButtonGrid/ButtonGrid", "./ColorPickerGridCell", "@uifabric/utilities"], function (require, exports, tslib_1, React, Utilities_1, ButtonGrid_1, ColorPickerGridCell_1, utilities_1) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var getClassNames = Utilities_1.classNamesFunction(); var COMPONENT_NAME = 'SwatchColorPicker'; var SwatchColorPickerBase = /** @class */ (function (_super) { tslib_1.__extends(SwatchColorPickerBase, _super); function SwatchColorPickerBase(props) { var _this = _super.call(this, props) || this; _this.navigationIdleDelay = 250 /* ms */; // Add an index to each color cells. Memoizes this so that color cells do not re-render on every update. _this._getItemsWithIndex = utilities_1.memoizeFunction(function (items) { return items.map(function (item, index) { return tslib_1.__assign(tslib_1.__assign({}, item), { index: index }); }); }); _this._onRenderItem = function (item, index) { var _a = _this.props.onRenderColorCell, onRenderColorCell = _a === void 0 ? _this._renderOption : _a; return onRenderColorCell(item, _this._renderOption); }; /** * When the whole swatchColorPicker is blurred, * make sure to clear the pending focused stated */ _this._onSwatchColorPickerBlur = function () { if (_this.props.onCellFocused) { _this._cellFocused = false; _this.props.onCellFocused(); } }; /** * Render a color cell * @param item - The item to render * @returns - Element representing the item */ _this._renderOption = function (item) { var props = _this.props; var id = _this._id; return (React.createElement(ColorPickerGridCell_1.ColorPickerGridCell, { item: item, idPrefix: id, color: item.color, styles: props.getColorGridCellStyles, disabled: props.disabled, onClick: _this._onCellClick, onHover: _this._onGridCellHovered, onFocus: _this._onGridCellFocused, selected: _this.state.selectedIndex !== undefined && _this.state.selectedIndex === item.index, circle: props.cellShape === 'circle', label: item.label, onMouseEnter: _this._onMouseEnter, onMouseMove: _this._onMouseMove, onMouseLeave: _this._onMouseLeave, onWheel: _this._onWheel, onKeyDown: _this._onKeyDown, height: props.cellHeight, width: props.cellWidth, borderWidth: props.cellBorderWidth })); }; /** * Callback passed to the GridCell that will manage triggering the onCellHovered callback for mouseEnter */ _this._onMouseEnter = function (ev) { if (!_this.props.focusOnHover) { return !_this.isNavigationIdle || !!_this.props.disabled; } if (_this.isNavigationIdle && !_this.props.disabled) { ev.currentTarget.focus(); } return true; }; /** * Callback passed to the GridCell that will manage Hover/Focus updates */ _this._onMouseMove = function (ev) { if (!_this.props.focusOnHover) { return !_this.isNavigationIdle || !!_this.props.disabled; } var targetElement = ev.currentTarget; // If navigation is idle and the targetElement is the focused element bail out // if (!this.isNavigationIdle || (document && targetElement === (document.activeElement as HTMLElement))) { if (_this.isNavigationIdle && !(document && targetElement === document.activeElement)) { targetElement.focus(); } return true; }; /** * Callback passed to the GridCell that will manage Hover/Focus updates */ _this._onMouseLeave = function (ev) { var parentSelector = _this.props.mouseLeaveParentSelector; if (!_this.props.focusOnHover || !parentSelector || !_this.isNavigationIdle || _this.props.disabled) { return; } // Get the elements that math the given selector var elements = document.querySelectorAll(parentSelector); // iterate over the elements return to make sure it is a parent of the target and focus it for (var index = 0; index < elements.length; index += 1) { if (elements[index].contains(ev.currentTarget)) { /** * IE11 focus() method forces parents to scroll to top of element. * Edge and IE expose a setActive() function for focusable divs that * sets the page focus but does not scroll the parent element. */ if (elements[index].setActive) { try { elements[index].setActive(); } catch (e) { /* no-op */ } } else { elements[index].focus(); } break; } } }; /** * Callback to make sure we don't update the hovered element during mouse wheel */ _this._onWheel = function () { _this._setNavigationTimeout(); }; /** * Callback that */ _this._onKeyDown = function (ev) { if (ev.which === Utilities_1.KeyCodes.up || ev.which === Utilities_1.KeyCodes.down || ev.which === Utilities_1.KeyCodes.left || ev.which === Utilities_1.KeyCodes.right) { _this._setNavigationTimeout(); } }; /** * Sets a timeout so we won't process any mouse "hover" events * while navigating (via mouseWheel or arrowKeys) */ _this._setNavigationTimeout = function () { if (!_this.isNavigationIdle && _this.navigationIdleTimeoutId !== undefined) { _this.async.clearTimeout(_this.navigationIdleTimeoutId); _this.navigationIdleTimeoutId = undefined; } else { _this.isNavigationIdle = false; } _this.navigationIdleTimeoutId = _this.async.setTimeout(function () { _this.isNavigationIdle = true; }, _this.navigationIdleDelay); }; /** * Callback passed to the GridCell class that will trigger the onCellHovered callback of the SwatchColorPicker * NOTE: This will not be triggered if shouldFocusOnHover === true */ _this._onGridCellHovered = function (item) { var onCellHovered = _this.props.onCellHovered; if (onCellHovered) { return item ? onCellHovered(item.id, item.color) : onCellHovered(); } }; /** * Callback passed to the GridCell class that will trigger the onCellFocus callback of the SwatchColorPicker */ _this._onGridCellFocused = function (item) { var onCellFocused = _this.props.onCellFocused; if (onCellFocused) { if (item) { _this._cellFocused = true; return onCellFocused(item.id, item.color); } else { _this._cellFocused = false; return onCellFocused(); } } }; /** * Handle the click on a cell * @param item - The cell that the click was fired against */ _this._onCellClick = function (item) { if (_this.props.disabled) { return; } var index = item.index; // If we have a valid index and it is not already // selected, select it if (index >= 0 && index !== _this.state.selectedIndex) { if (_this.props.onCellFocused && _this._cellFocused) { _this._cellFocused = false; _this.props.onCellFocused(); } if (_this.props.onColorChanged) { _this.props.onColorChanged(item.id, item.color); } // Update internal state only if the component is uncontrolled if (_this.props.isControlled !== true) { _this.setState({ selectedIndex: index, }); } } }; _this._id = props.id || Utilities_1.getId('swatchColorPicker'); _this.isNavigationIdle = true; _this.async = new Utilities_1.Async(_this); var selectedIndex; if (props.selectedId) { selectedIndex = _getSelectedIndex(props.colorCells, props.selectedId); } _this.state = { selectedIndex: selectedIndex, }; return _this; } SwatchColorPickerBase.getDerivedStateFromProps = function (newProps, state) { var newSelectedIndex = newProps.selectedId ? _getSelectedIndex(newProps.colorCells, newProps.selectedId) : undefined; // If not controlled, we do not want to allow updates to selectedIndex to be undefined if (!newProps.isControlled && newSelectedIndex === undefined) { return null; } if (newSelectedIndex !== state.selectedIndex) { return { selectedIndex: newSelectedIndex, }; } return null; }; SwatchColorPickerBase.prototype.componentWillUnmount = function () { if (this.props.onCellFocused && this._cellFocused) { this._cellFocused = false; this.props.onCellFocused(); } this.async.dispose(); }; SwatchColorPickerBase.prototype.render = function () { var _a = this.props, colorCells = _a.colorCells, columnCount = _a.columnCount, /* eslint-disable deprecation/deprecation */ _b = _a.ariaPosInSet, /* eslint-disable deprecation/deprecation */ ariaPosInSet = _b === void 0 ? this.props.positionInSet : _b, _c = _a.ariaSetSize, ariaSetSize = _c === void 0 ? this.props.setSize : _c, /* eslint-enable deprecation/deprecation */ shouldFocusCircularNavigate = _a.shouldFocusCircularNavigate, className = _a.className, doNotContainWithinFocusZone = _a.doNotContainWithinFocusZone, styles = _a.styles, cellMargin = _a.cellMargin; var classNames = getClassNames(styles, { theme: this.props.theme, className: className, cellMargin: cellMargin, }); if (colorCells.length < 1 || columnCount < 1) { return null; } return (React.createElement(ButtonGrid_1.ButtonGrid, tslib_1.__assign({}, this.props, { id: this._id, items: this._getItemsWithIndex(colorCells), columnCount: columnCount, onRenderItem: this._onRenderItem, ariaPosInSet: ariaPosInSet, ariaSetSize: ariaSetSize, shouldFocusCircularNavigate: shouldFocusCircularNavigate, doNotContainWithinFocusZone: doNotContainWithinFocusZone, onBlur: this._onSwatchColorPickerBlur, theme: this.props.theme, styles: { root: classNames.root, tableCell: classNames.tableCell, focusedContainer: classNames.focusedContainer, } }))); }; SwatchColorPickerBase.defaultProps = { cellShape: 'circle', disabled: false, shouldFocusCircularNavigate: true, cellMargin: 10, }; return SwatchColorPickerBase; }(React.Component)); exports.SwatchColorPickerBase = SwatchColorPickerBase; /** * Get the selected item's index * @param items - The items to search * @param selectedId - The selected item's id to find * @returns - The index of the selected item's id, -1 if there was no match */ function _getSelectedIndex(items, selectedId) { var selectedIndex = Utilities_1.findIndex(items, function (item) { return item.id === selectedId; }); return selectedIndex >= 0 ? selectedIndex : undefined; } }); //# sourceMappingURL=SwatchColorPicker.base.js.map