carbon-react 101.4.5 → 102.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
- var _react = _interopRequireDefault(require("react"));
8
+ var _react = _interopRequireWildcard(require("react"));
9
9
 
10
10
  var _propTypes = _interopRequireDefault(require("prop-types"));
11
11
 
@@ -21,268 +21,211 @@ var _i18nContext = _interopRequireDefault(require("../../__internal__/i18n-conte
21
21
 
22
22
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
23
 
24
- function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
25
-
26
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
27
-
28
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
29
-
30
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
31
-
32
- function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
33
-
34
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
35
-
36
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
37
-
38
- function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
39
-
40
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
41
-
42
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
24
+ function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
43
25
 
44
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
26
+ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
45
27
 
46
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
28
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
47
29
 
48
30
  const marginPropTypes = (0, _utils.filterStyledSystemMarginProps)(_propTypes2.default.space);
49
31
 
50
- let Decimal = /*#__PURE__*/function (_React$Component) {
51
- _inherits(Decimal, _React$Component);
52
-
53
- var _super = _createSuper(Decimal);
54
-
55
- function Decimal(props, context) {
56
- var _this;
57
-
58
- _classCallCheck(this, Decimal);
59
-
60
- _this = _super.call(this, props, context);
61
-
62
- _defineProperty(_assertThisInitialized(_this), "emptyValue", _this.props.allowEmptyValue ? "" : "0.00");
63
-
64
- _defineProperty(_assertThisInitialized(_this), "callOnChange", () => {
65
- if (_this.props.onChange) {
66
- _this.props.onChange(_this.createEvent());
67
- }
68
- });
69
-
70
- _defineProperty(_assertThisInitialized(_this), "onChange", ev => {
71
- const {
72
- target: {
73
- value
74
- }
75
- } = ev;
76
-
77
- _this.setState({
78
- value: _this.toStandardDecimal(value),
79
- visibleValue: value
80
- }, () => {
81
- _this.callOnChange();
82
- });
83
- });
84
-
85
- _defineProperty(_assertThisInitialized(_this), "onBlur", () => {
86
- let shouldCallOnChange = false;
87
-
88
- _this.setState(({
89
- value,
90
- visibleValue
91
- }) => {
92
- if (!visibleValue) {
93
- shouldCallOnChange = value !== _this.emptyValue;
94
- return {
95
- value: _this.emptyValue,
96
- visibleValue: _this.formatValue(_this.emptyValue)
97
- };
98
- }
99
-
100
- return {
101
- visibleValue: _this.formatValue(value)
102
- };
103
- }, () => {
104
- if (shouldCallOnChange) {
105
- _this.callOnChange();
106
- }
32
+ const Decimal = ({
33
+ align = "right",
34
+ defaultValue,
35
+ precision = 2,
36
+ inputWidth,
37
+ readOnly,
38
+ onChange,
39
+ onBlur,
40
+ onKeyPress,
41
+ id,
42
+ name,
43
+ allowEmptyValue = false,
44
+ required,
45
+ locale,
46
+ value,
47
+ ...rest
48
+ }) => {
49
+ const l = (0, _react.useContext)(_i18nContext.default);
50
+ const emptyValue = allowEmptyValue ? "" : "0.00";
51
+
52
+ const getSafeValueProp = initialValue => {
53
+ // We're intentionally preventing the use of number values to help prevent any unintentional rounding issues
54
+ (0, _invariant.default)(typeof initialValue === "string", "Decimal `value` prop must be a string");
55
+
56
+ if (initialValue && !allowEmptyValue) {
57
+ (0, _invariant.default)(initialValue !== "", "Decimal `value` must not be an empty string. Please use `allowEmptyValue` or `0.00`");
58
+ }
107
59
 
108
- if (_this.props.onBlur) {
109
- _this.props.onBlur(_this.createEvent());
110
- }
111
- });
112
- });
60
+ return initialValue;
61
+ };
113
62
 
114
- _defineProperty(_assertThisInitialized(_this), "createEvent", () => {
115
- const standardVisible = _this.toStandardDecimal(_this.state.visibleValue);
116
-
117
- const formattedValue = _this.isNaN(standardVisible) ? _this.state.visibleValue : _this.formatValue(standardVisible);
118
- return {
119
- target: {
120
- name: _this.props.name,
121
- id: _this.props.id,
122
- value: {
123
- rawValue: _this.state.value,
124
- formattedValue
125
- }
126
- }
127
- };
128
- });
63
+ const getSeparator = (0, _react.useCallback)(separatorType => {
64
+ const numberWithGroupAndDecimalSeparator = 10000.1;
65
+ return Intl.NumberFormat(locale || l.locale()).formatToParts(numberWithGroupAndDecimalSeparator).find(part => part.type === separatorType).value;
66
+ }, [l, locale]);
67
+ const isNaN = (0, _react.useCallback)(valueToTest => {
68
+ return Number.isNaN(Number(valueToTest));
69
+ }, []);
70
+ /**
71
+ * Format a user defined value
72
+ */
129
73
 
130
- _defineProperty(_assertThisInitialized(_this), "isNaN", value => {
131
- return Number.isNaN(Number(value));
132
- });
74
+ const formatValue = (0, _react.useCallback)(valueToFormat => {
75
+ if (isNaN(valueToFormat)) {
76
+ return valueToFormat;
77
+ }
78
+ /* Guards against any white-space only strings like " " being
79
+ mishandled and returned as `NaN` for the value displayed in the textbox */
133
80
 
134
- _defineProperty(_assertThisInitialized(_this), "getSafeValueProp", isInitialValue => {
135
- const {
136
- value,
137
- allowEmptyValue
138
- } = _this.props; // We're intentionally preventing the use of number values to help prevent any unintentional rounding issues
139
81
 
140
- (0, _invariant.default)(typeof value === "string", "Decimal `value` prop must be a string");
82
+ if (valueToFormat === "" || valueToFormat.match(/\s+/g)) {
83
+ return valueToFormat;
84
+ }
141
85
 
142
- if (isInitialValue && !allowEmptyValue) {
143
- (0, _invariant.default)(value !== "", "Decimal `value` must not be an empty string. Please use `allowEmptyValue` or `0.00`");
144
- }
86
+ const separator = getSeparator("decimal");
87
+ const [integer, remainder] = valueToFormat.split(".");
88
+ const formattedInteger = Intl.NumberFormat(locale || l.locale(), {
89
+ maximumFractionDigits: 0
90
+ }).format(integer);
91
+ let formattedNumber = formattedInteger;
92
+
93
+ if ((remainder === null || remainder === void 0 ? void 0 : remainder.length) > precision) {
94
+ formattedNumber += `${separator + remainder}`;
95
+ } else if ((remainder === null || remainder === void 0 ? void 0 : remainder.length) <= precision) {
96
+ formattedNumber += `${separator + remainder + "0".repeat(precision - remainder.length)}`;
97
+ } else {
98
+ formattedNumber += `${precision ? separator + "0".repeat(precision) : ""}`;
99
+ }
145
100
 
146
- return value;
147
- });
101
+ return formattedNumber;
102
+ }, [getSeparator, isNaN, l, locale, precision]); // Return previous value before state is changed. Used to compare prevState and newState.
148
103
 
149
- _defineProperty(_assertThisInitialized(_this), "removeDelimiters", value => {
150
- const delimiterMatcher = new RegExp(`[\\${_this.getSeparator("group")} ]*`, "g");
151
- return value.replace(delimiterMatcher, "");
104
+ function usePrevious(arg) {
105
+ const ref = (0, _react.useRef)();
106
+ (0, _react.useEffect)(() => {
107
+ ref.current = arg;
152
108
  });
109
+ return ref.current;
110
+ }
111
+ /**
112
+ * Determine if the precision value has changed from the previous ref value for precision
113
+ */
153
114
 
154
- _defineProperty(_assertThisInitialized(_this), "formatValue", value => {
155
- if (_this.isNaN(value)) {
156
- return value;
157
- }
158
- /* Guards against any white-space only strings like " " being
159
- mishandled and returned as `NaN` for visibleValue */
160
-
161
-
162
- if (value === "" || value.match(/\s+/g)) {
163
- return value;
164
- }
165
-
166
- const separator = _this.getSeparator("decimal");
167
-
168
- const [integer, remainder] = value.split(".");
169
- const formattedInteger = Intl.NumberFormat(_this.props.locale || _this.context.locale(), {
170
- maximumFractionDigits: 0
171
- }).format(integer);
172
- let formattedNumber = formattedInteger;
173
-
174
- if (remainder && remainder.length > _this.props.precision) {
175
- formattedNumber += `${separator + remainder}`;
176
- } else if (remainder && remainder.length <= _this.props.precision) {
177
- formattedNumber += `${separator + remainder + "0".repeat(_this.props.precision - remainder.length)}`;
178
- } else {
179
- formattedNumber += `${_this.props.precision ? separator + "0".repeat(_this.props.precision) : ""}`;
180
- }
181
115
 
182
- return formattedNumber;
183
- });
116
+ const prevPrecisionValue = usePrevious(precision);
117
+ (0, _react.useEffect)(() => {
118
+ if (prevPrecisionValue && prevPrecisionValue !== precision) {
119
+ // eslint-disable-next-line no-console
120
+ console.error("Decimal `precision` prop has changed value. Changing the Decimal `precision` prop has no effect.");
121
+ }
122
+ }, [precision]);
123
+ const removeDelimiters = (0, _react.useCallback)(valueToFormat => {
124
+ const delimiterMatcher = new RegExp(`[\\${getSeparator("group")} ]*`, "g");
125
+ return valueToFormat.replace(delimiterMatcher, "");
126
+ }, [getSeparator]);
127
+ /**
128
+ * Convert raw input to a standard decimal format
129
+ */
184
130
 
185
- _defineProperty(_assertThisInitialized(_this), "toStandardDecimal", i18nValue => {
186
- const valueWithoutNBS = _this.getSeparator("group").match(/\s+/) && !i18nValue.match(/\s{2,}/) ? i18nValue.replace(/\s+/g, "") : i18nValue;
187
- /* If a value is passed in that is a number but has too many delimiters in succession, we want to handle this
188
- value without formatting it or removing delimiters. We also want to consider that,
189
- if a value consists of only delimiters, we want to treat that
190
- value in the same way as if the value was NaN. We want to pass this value to the
191
- formatValue function, before the delimiters can be removed. */
131
+ const toStandardDecimal = (0, _react.useCallback)(i18nValue => {
132
+ const valueWithoutNBS = getSeparator("group").match(/\s+/) && !i18nValue.match(/\s{2,}/) ? i18nValue.replace(/\s+/g, "") : i18nValue;
133
+ /* If a value is passed in that is a number but has too many delimiters in succession, we want to handle this
134
+ value without formatting it or removing delimiters. We also want to consider that,
135
+ if a value consists of only delimiters, we want to treat that
136
+ value in the same way as if the value was NaN. We want to pass this value to the
137
+ formatValue function, before the delimiters can be removed. */
192
138
 
193
- const errorsWithDelimiter = new RegExp(`([^A-Za-z0-9]{2,})|(^[^A-Za-z0-9-]+)|([^0-9a-z-,.])|([^0-9-,.]+)|([W,.])$`, "g");
139
+ const errorsWithDelimiter = new RegExp(`([^A-Za-z0-9]{2,})|(^[^A-Za-z0-9-]+)|([^0-9a-z-,.])|([^0-9-,.]+)|([W,.])$`, "g");
140
+ const separator = getSeparator("decimal");
141
+ const separatorRegex = new RegExp(separator === "." ? `\\${separator}` : separator, "g");
194
142
 
195
- const separator = _this.getSeparator("decimal");
143
+ if (valueWithoutNBS.match(errorsWithDelimiter) || (valueWithoutNBS.match(separatorRegex) || []).length > 1) {
144
+ return valueWithoutNBS;
145
+ }
196
146
 
197
- const separatorRegex = new RegExp(separator === "." ? `\\${separator}` : separator, "g");
147
+ const withoutDelimiters = removeDelimiters(valueWithoutNBS);
148
+ return withoutDelimiters.replace(new RegExp(`\\${separator}`, "g"), ".");
149
+ }, [getSeparator, removeDelimiters]);
150
+ const decimalValue = getSafeValueProp(defaultValue || value || emptyValue);
151
+ const [stateValue, setStateValue] = (0, _react.useState)(isNaN(toStandardDecimal(decimalValue)) ? decimalValue : formatValue(decimalValue));
198
152
 
199
- if (valueWithoutNBS.match(errorsWithDelimiter) || (valueWithoutNBS.match(separatorRegex) || []).length > 1) {
200
- return valueWithoutNBS;
153
+ const createEvent = (formatted, raw) => {
154
+ return {
155
+ target: {
156
+ name,
157
+ id,
158
+ value: {
159
+ formattedValue: formatValue(toStandardDecimal(formatted)),
160
+ rawValue: raw || toStandardDecimal(formatted)
161
+ }
201
162
  }
202
-
203
- const withoutDelimiters = _this.removeDelimiters(valueWithoutNBS);
204
-
205
- return withoutDelimiters.replace(new RegExp(`\\${separator}`, "g"), ".");
206
- });
207
-
208
- const isControlled = _this.isControlled();
209
-
210
- const _value = isControlled ? _this.getSafeValueProp(true) : _this.props.defaultValue || _this.emptyValue;
211
-
212
- _this.state = {
213
- value: _value,
214
- visibleValue: _this.formatValue(_value),
215
- isControlled
216
163
  };
217
- return _this;
218
- }
164
+ };
165
+
166
+ const handleOnChange = ev => {
167
+ const {
168
+ value: val
169
+ } = ev.target;
170
+ setStateValue(val);
171
+ if (onChange) onChange(createEvent(val));
172
+ };
173
+
174
+ const handleOnBlur = ev => {
175
+ const {
176
+ value: updatedValue
177
+ } = ev.target;
178
+ let event;
179
+
180
+ if (updatedValue) {
181
+ const standardVisible = toStandardDecimal(updatedValue);
182
+ const formattedValue = isNaN(standardVisible) ? updatedValue : formatValue(standardVisible);
183
+ event = createEvent(formattedValue, standardVisible);
184
+ setStateValue(formattedValue);
185
+ } else {
186
+ event = createEvent(emptyValue);
187
+ setStateValue(emptyValue);
188
+ }
219
189
 
220
- _createClass(Decimal, [{
221
- key: "componentDidUpdate",
222
- value: function componentDidUpdate(prevProps, prevState) {
223
- const message = "Input elements should not switch from uncontrolled to controlled (or vice versa). " + "Decide between using a controlled or uncontrolled input element for the lifetime of the component";
224
- const isControlled = this.isControlled();
225
- (0, _invariant.default)(this.state.isControlled === isControlled, message);
190
+ if (onBlur) onBlur(event);
191
+ };
226
192
 
227
- if (prevProps.precision !== this.props.precision) {
228
- // eslint-disable-next-line no-console
229
- console.error("Decimal `precision` prop has changed value. Changing the Decimal `precision` prop has no effect.");
230
- }
193
+ const isComponentControlled = value !== undefined;
194
+ const prevControlledState = usePrevious(isComponentControlled);
195
+ (0, _react.useEffect)(() => {
196
+ const message = "Input elements should not switch from uncontrolled to controlled (or vice versa). " + "Decide between using a controlled or uncontrolled input element for the lifetime of the component";
197
+ (0, _invariant.default)(prevControlledState !== isComponentControlled, message);
198
+ }, [isComponentControlled]);
199
+ (0, _react.useEffect)(() => {
200
+ const unformattedValue = toStandardDecimal(stateValue);
231
201
 
232
- if (isControlled) {
233
- const valueProp = this.getSafeValueProp();
202
+ if (isComponentControlled) {
203
+ const valueProp = getSafeValueProp(value);
234
204
 
235
- if (valueProp !== prevState.value) {
236
- this.setState({
237
- value: valueProp,
238
- visibleValue: this.formatValue(valueProp)
239
- });
240
- }
205
+ if (unformattedValue !== valueProp) {
206
+ setStateValue(formatValue(value));
241
207
  }
242
- }
243
- }, {
244
- key: "isControlled",
245
- value:
246
- /**
247
- * Determine if the component is controlled at the time of call
248
- */
249
- function isControlled() {
250
- return this.props.value !== undefined;
251
- }
252
- }, {
253
- key: "getSeparator",
254
- value: function getSeparator(separatorType) {
255
- const numberWithGroupAndDecimalSeparator = 10000.1;
256
- return Intl.NumberFormat(this.props.locale || this.context.locale()).formatToParts(numberWithGroupAndDecimalSeparator).find(part => part.type === separatorType).value;
257
- }
258
- }, {
259
- key: "render",
260
- value: function render() {
261
- const {
262
- name,
263
- defaultValue,
264
- locale,
265
- ...rest
266
- } = this.props;
267
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_textbox.default, _extends({}, rest, {
268
- onChange: this.onChange,
269
- onBlur: this.onBlur,
270
- value: this.state.visibleValue
271
- })), /*#__PURE__*/_react.default.createElement("input", {
272
- name: name,
273
- value: this.toStandardDecimal(this.state.visibleValue),
274
- type: "hidden",
275
- "data-component": "hidden-input"
276
- }));
277
- }
278
- }]);
279
-
280
- return Decimal;
281
- }(_react.default.Component);
282
-
283
- _defineProperty(Decimal, "maxPrecision", 15);
208
+ } // eslint-disable-next-line react-hooks/exhaustive-deps
209
+
210
+ }, [value]);
211
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_textbox.default, _extends({
212
+ onKeyPress: onKeyPress,
213
+ align: align,
214
+ readOnly: readOnly,
215
+ required: required,
216
+ inputWidth: inputWidth,
217
+ onChange: handleOnChange,
218
+ onBlur: handleOnBlur,
219
+ value: stateValue,
220
+ "data-component": "decimal"
221
+ }, rest)), /*#__PURE__*/_react.default.createElement("input", {
222
+ name: name,
223
+ value: toStandardDecimal(stateValue),
224
+ type: "hidden",
225
+ "data-component": "hidden-input"
226
+ }));
227
+ };
284
228
 
285
- Decimal.contextType = _i18nContext.default;
286
229
  Decimal.propTypes = {
287
230
  /** Styled-system margin props */
288
231
  ...marginPropTypes,
@@ -300,7 +243,7 @@ Decimal.propTypes = {
300
243
  */
301
244
  // eslint-disable-next-line consistent-return
302
245
  precision: props => {
303
- if (!Number.isInteger(props.precision) || props.precision < 0 || props.precision > Decimal.maxPrecision) {
246
+ if (!Number.isInteger(props.precision) || props.precision < 0 || props.precision > 15) {
304
247
  return new Error("Precision prop must be a number greater than 0 or equal to or less than 15.");
305
248
  }
306
249
  },
@@ -366,11 +309,5 @@ Decimal.propTypes = {
366
309
  /** Aria label for rendered help component */
367
310
  helpAriaLabel: _propTypes.default.string
368
311
  };
369
- Decimal.defaultProps = {
370
- align: "right",
371
- precision: 2,
372
- allowEmptyValue: false,
373
- "data-component": "decimal"
374
- };
375
312
  var _default = Decimal;
376
313
  exports.default = _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "carbon-react",
3
- "version": "101.4.5",
3
+ "version": "102.0.0",
4
4
  "description": "A library of reusable React components for easily building user interfaces.",
5
5
  "engineStrict": true,
6
6
  "engines": {