summaryrefslogtreecommitdiffstats
path: root/devtools/client/inspector/fonts/components/LetterSpacing.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--devtools/client/inspector/fonts/components/LetterSpacing.js105
1 files changed, 105 insertions, 0 deletions
diff --git a/devtools/client/inspector/fonts/components/LetterSpacing.js b/devtools/client/inspector/fonts/components/LetterSpacing.js
new file mode 100644
index 0000000000..42d6ddfa61
--- /dev/null
+++ b/devtools/client/inspector/fonts/components/LetterSpacing.js
@@ -0,0 +1,105 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const {
+ createFactory,
+ PureComponent,
+} = require("resource://devtools/client/shared/vendor/react.js");
+const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.js");
+
+const FontPropertyValue = createFactory(
+ require("resource://devtools/client/inspector/fonts/components/FontPropertyValue.js")
+);
+
+const {
+ getStr,
+} = require("resource://devtools/client/inspector/fonts/utils/l10n.js");
+const {
+ getUnitFromValue,
+ getStepForUnit,
+} = require("resource://devtools/client/inspector/fonts/utils/font-utils.js");
+
+class LetterSpacing extends PureComponent {
+ static get propTypes() {
+ return {
+ disabled: PropTypes.bool.isRequired,
+ onChange: PropTypes.func.isRequired,
+ value: PropTypes.string.isRequired,
+ };
+ }
+
+ constructor(props) {
+ super(props);
+ // Local state for min/max bounds indexed by unit to allow user input that
+ // goes out-of-bounds while still providing a meaningful default range. The indexing
+ // by unit is needed to account for unit conversion (ex: em to px) where the operation
+ // may result in out-of-bounds values. Avoiding React's state and setState() because
+ // `value` is a prop coming from the Redux store while min/max are local. Reconciling
+ // value/unit changes is needlessly complicated and adds unnecessary re-renders.
+ this.historicMin = {};
+ this.historicMax = {};
+ }
+
+ getDefaultMinMax(unit) {
+ let min;
+ let max;
+ switch (unit) {
+ case "px":
+ min = -10;
+ max = 10;
+ break;
+ default:
+ min = -0.2;
+ max = 0.6;
+ break;
+ }
+
+ return { min, max };
+ }
+
+ render() {
+ // For a unitless or a NaN value, default unit to "em".
+ const unit = getUnitFromValue(this.props.value) || "em";
+ // When the initial value of "letter-spacing" is "normal", the parsed value
+ // is not a number (NaN). Guard by setting the default value to 0.
+ const isKeywordValue = this.props.value === "normal";
+ const value = isKeywordValue ? 0 : parseFloat(this.props.value);
+
+ let { min, max } = this.getDefaultMinMax(unit);
+ min = Math.min(min, value);
+ max = Math.max(max, value);
+ // Allow lower and upper bounds to move to accomodate the incoming value.
+ this.historicMin[unit] = this.historicMin[unit]
+ ? Math.min(this.historicMin[unit], min)
+ : min;
+ this.historicMax[unit] = this.historicMax[unit]
+ ? Math.max(this.historicMax[unit], max)
+ : max;
+
+ return FontPropertyValue({
+ allowOverflow: true,
+ allowUnderflow: true,
+ disabled: this.props.disabled,
+ label: getStr("fontinspector.letterSpacingLabel"),
+ min: this.historicMin[unit],
+ max: this.historicMax[unit],
+ name: "letter-spacing",
+ onChange: this.props.onChange,
+ // Increase the increment granularity because letter spacing is very sensitive.
+ step: getStepForUnit(unit) / 100,
+ // Show the value input and unit only when the value is not a keyword.
+ showInput: !isKeywordValue,
+ showUnit: !isKeywordValue,
+ unit,
+ unitOptions: ["em", "rem", "px"],
+ value,
+ // Show the value as a read-only label if it's a keyword.
+ valueLabel: isKeywordValue ? this.props.value : null,
+ });
+ }
+}
+
+module.exports = LetterSpacing;