UNPKG

office-ui-fabric-react

Version:

Reusable React components for building experiences for Office 365.

217 lines • 12.5 kB
define(["require", "exports", "tslib", "react", "../../Utilities", "../../TextField", "./ColorRectangle/ColorRectangle", "./ColorSlider/ColorSlider", "../../utilities/color/consts", "../../utilities/color/getColorFromString", "../../utilities/color/getColorFromRGBA", "../../utilities/color/updateA", "../../utilities/color/updateH", "../../utilities/color/correctRGB", "../../utilities/color/correctHex"], function (require, exports, tslib_1, React, Utilities_1, TextField_1, ColorRectangle_1, ColorSlider_1, consts_1, getColorFromString_1, getColorFromRGBA_1, updateA_1, updateH_1, correctRGB_1, correctHex_1) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var getClassNames = Utilities_1.classNamesFunction(); var colorComponents = ['hex', 'r', 'g', 'b', 'a']; /** * {@docCategory ColorPicker} */ var ColorPickerBase = /** @class */ (function (_super) { tslib_1.__extends(ColorPickerBase, _super); function ColorPickerBase(props) { var _this = _super.call(this, props) || this; _this._onSVChanged = function (ev, color) { _this._updateColor(ev, color); }; _this._onHChanged = function (ev, h) { _this._updateColor(ev, updateH_1.updateH(_this.state.color, h)); }; _this._onAChanged = function (ev, a) { _this._updateColor(ev, updateA_1.updateA(_this.state.color, Math.round(a))); }; _this._onBlur = function (event) { var _a; var _b = _this.state, color = _b.color, editingColor = _b.editingColor; if (!editingColor) { return; } // If there was an intermediate incorrect value (such as too large or empty), correct it. var value = editingColor.value, component = editingColor.component; var isHex = component === 'hex'; var minLength = isHex ? consts_1.MIN_HEX_LENGTH : consts_1.MIN_RGBA_LENGTH; if (value.length >= minLength && (isHex || !isNaN(Number(value)))) { // Real value. Clamp to appropriate length (hex) or range (rgba). var newColor = void 0; if (isHex) { newColor = getColorFromString_1.getColorFromString('#' + correctHex_1.correctHex(value)); } else { newColor = getColorFromRGBA_1.getColorFromRGBA(correctRGB_1.correctRGB(tslib_1.__assign({}, color, (_a = {}, _a[component] = Number(value), _a)))); } // Update state and call onChange _this._updateColor(event, newColor); } else { // Intermediate value was an empty string, too short (hex only), or just . (alpha only). // Just clear the intermediate state and revert to the previous value. _this.setState({ editingColor: undefined }); } }; Utilities_1.initializeComponentRef(_this); _this.state = { color: _getColorFromProps(props) || getColorFromString_1.getColorFromString('#ffffff') }; _this._textChangeHandlers = {}; for (var _i = 0, colorComponents_1 = colorComponents; _i < colorComponents_1.length; _i++) { var component = colorComponents_1[_i]; _this._textChangeHandlers[component] = _this._onTextChange.bind(_this, component); } _this._textLabels = { r: props.redLabel, g: props.greenLabel, b: props.blueLabel, a: props.alphaLabel, hex: props.hexLabel }; return _this; } Object.defineProperty(ColorPickerBase.prototype, "color", { get: function () { return this.state.color; }, enumerable: true, configurable: true }); // tslint:disable-next-line function-name ColorPickerBase.prototype.UNSAFE_componentWillReceiveProps = function (newProps) { var color = _getColorFromProps(newProps); if (color) { this._updateColor(undefined, color); } }; ColorPickerBase.prototype.render = function () { var _this = this; var props = this.props; var theme = props.theme, className = props.className, styles = props.styles; var color = this.state.color; var classNames = getClassNames(styles, { theme: theme, className: className }); return (React.createElement("div", { className: classNames.root }, React.createElement("div", { className: classNames.panel }, React.createElement(ColorRectangle_1.ColorRectangle, { color: color, onChange: this._onSVChanged, className: classNames.colorRectangle }), React.createElement("div", { className: classNames.flexContainer }, React.createElement("div", { className: classNames.flexSlider }, React.createElement(ColorSlider_1.ColorSlider, { className: "is-hue", minValue: 0, maxValue: consts_1.MAX_COLOR_HUE, value: color.h, onChange: this._onHChanged }), !props.alphaSliderHidden && (React.createElement(ColorSlider_1.ColorSlider, { className: "is-alpha", isAlpha: true, overlayStyle: { background: "linear-gradient(to right, transparent 0, #" + color.hex + " 100%)" }, minValue: 0, maxValue: consts_1.MAX_COLOR_ALPHA, value: color.a, onChange: this._onAChanged }))), props.showPreview && (React.createElement("div", { className: classNames.flexPreviewBox }, React.createElement("div", { className: classNames.colorSquare + ' is-preview', style: { backgroundColor: color.str } })))), React.createElement("table", { className: classNames.table, cellPadding: "0", cellSpacing: "0" }, React.createElement("thead", null, React.createElement("tr", { className: classNames.tableHeader }, React.createElement("td", { className: classNames.tableHexCell }, props.hexLabel), React.createElement("td", null, props.redLabel), React.createElement("td", null, props.greenLabel), React.createElement("td", null, props.blueLabel), !props.alphaSliderHidden && React.createElement("td", null, props.alphaLabel))), React.createElement("tbody", null, React.createElement("tr", null, colorComponents.map(function (comp) { if (comp === 'a' && props.alphaSliderHidden) { return null; } return (React.createElement("td", { key: comp, style: comp === 'hex' ? undefined : { width: '18%' } }, React.createElement(TextField_1.TextField, { className: classNames.input, onChange: _this._textChangeHandlers[comp], onBlur: _this._onBlur, value: _this._getDisplayValue(comp), spellCheck: false, ariaLabel: _this._textLabels[comp] }))); }))))))); }; ColorPickerBase.prototype._getDisplayValue = function (component) { var _a = this.state, color = _a.color, editingColor = _a.editingColor; if (editingColor && editingColor.component === component) { return editingColor.value; } if (component === 'hex') { return color[component] || ''; } else if (typeof color[component] === 'number' && !isNaN(color[component])) { return String(color[component]); } return ''; }; ColorPickerBase.prototype._onTextChange = function (component, event, newValue) { var _a; var color = this.state.color; var isHex = component === 'hex'; var isAlpha = component === 'a'; newValue = (newValue || '').substr(0, isHex ? consts_1.MAX_HEX_LENGTH : consts_1.MAX_RGBA_LENGTH); // Ignore what the user typed if it contains invalid characters var validCharsRegex = isHex ? consts_1.HEX_REGEX : consts_1.RGBA_REGEX; if (!validCharsRegex.test(newValue)) { return; } // Determine if the entry is valid (different methods for hex, alpha, and RGB) var isValid; if (newValue === '') { // Empty string is obviously not valid isValid = false; } else if (isHex) { // Technically hex values of length 3 are also valid, but committing the value here would // cause it to be automatically converted to a value of length 6, which may not be what the // user wanted if they're not finished typing. (Values of length 3 will be committed on blur.) isValid = newValue.length === consts_1.MAX_HEX_LENGTH; } else if (isAlpha) { isValid = Number(newValue) <= consts_1.MAX_COLOR_ALPHA; } else { isValid = Number(newValue) <= consts_1.MAX_COLOR_RGB; } if (!isValid) { // If the new value is an empty string or other invalid value, save that to display. // (if the user still hasn't entered anything on blur, the last value is restored) this.setState({ editingColor: { component: component, value: newValue } }); } else if (String(color[component]) === newValue) { // If the new value is the same as the current value, mostly ignore it. // Exception is that if the user was previously editing the value (but hadn't yet entered // a new valid value), we should clear the intermediate value. if (this.state.editingColor) { this.setState({ editingColor: undefined }); } } else { // Should be a valid color. Update the value. var newColor = isHex ? getColorFromString_1.getColorFromString('#' + newValue) : getColorFromRGBA_1.getColorFromRGBA(tslib_1.__assign({}, color, (_a = {}, _a[component] = Number(newValue), _a))); this._updateColor(event, newColor); } }; /** * Update the displayed color and call change handlers if appropriate. * @param ev - Event if call was triggered by an event (undefined if triggered by props change) * @param newColor - Updated color */ ColorPickerBase.prototype._updateColor = function (ev, newColor) { var _this = this; if (!newColor) { return; } var _a = this.state, color = _a.color, editingColor = _a.editingColor; var isDifferentColor = newColor.h !== color.h || newColor.str !== color.str; if (isDifferentColor || editingColor) { this.setState({ color: newColor, editingColor: undefined }, function () { if (ev && _this.props.onChange) { _this.props.onChange(ev, newColor); } }); } }; ColorPickerBase.defaultProps = { hexLabel: 'Hex', redLabel: 'Red', greenLabel: 'Green', blueLabel: 'Blue', alphaLabel: 'Alpha' }; return ColorPickerBase; }(React.Component)); exports.ColorPickerBase = ColorPickerBase; function _getColorFromProps(props) { var color = props.color; return typeof color === 'string' ? getColorFromString_1.getColorFromString(color) : color; } }); //# sourceMappingURL=ColorPicker.base.js.map