Skip to content

Commit

Permalink
Release v1.17.0
Browse files Browse the repository at this point in the history
  • Loading branch information
sawyerh committed Mar 7, 2018
1 parent 4326116 commit 5539e73
Show file tree
Hide file tree
Showing 11 changed files with 229 additions and 17 deletions.
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@
"packages/*",
"packages/themes/*"
],
"version": "1.16.0"
"version": "1.17.0"
}
1 change: 1 addition & 0 deletions packages/core/dist/components/TextField/CurrencyField.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

203 changes: 203 additions & 0 deletions packages/core/dist/components/TextField/Mask.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Mask = undefined;

var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
* A Mask component renders a controlled input field. When the
* field is blurred, it applies formatting to improve the readability
* of the value.
*/
var Mask = exports.Mask = function (_React$PureComponent) {
_inherits(Mask, _React$PureComponent);

function Mask(props) {
_classCallCheck(this, Mask);

var _this = _possibleConstructorReturn(this, (Mask.__proto__ || Object.getPrototypeOf(Mask)).call(this, props));

_this.field = _react2.default.Children.only(_this.props.children);
_this.state = {
value: _this.maskedValue(_this.initialValue())
};
return _this;
}

_createClass(Mask, [{
key: 'componentDidUpdate',
value: function componentDidUpdate() {
if (this.debouncedOnBlurEvent) {
this.field.props.onBlur(this.debouncedOnBlurEvent);
this.debouncedOnBlurEvent = null;
}
}

/**
* @param {String} value
* @returns {Number}
*/

}, {
key: 'toNumber',
value: function toNumber(value) {
if (typeof value !== 'string') return value;

// 0 = number, 1 = decimals
var parts = value.split('.');
var digitsRegex = /\d/g;
var a = parts[0].match(digitsRegex).join('');
var b = parts.length >= 2 && parts[1].match(digitsRegex).join('');

return b ? parseFloat(a + '.' + b) : parseInt(a);
}

/**
* Format a string using fixed-point notation, similar to Number.prototype.toFixed
* though a decimal is only fixed if the string included a decimal already
* @param {String} value - A stringified number (i.e. "1234")
* @param {Number} digits - The number of digits to appear after the decimal point
* @returns {String}
*/

}, {
key: 'stringWithFixedDigits',
value: function stringWithFixedDigits(value) {
var digits = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;

var decimalRegex = /\.[\d]+$/;

// Check for existing decimal
var decimal = value.match(decimalRegex);

if (decimal) {
var fixedDecimal = parseFloat(decimal).toFixed(digits).match(decimalRegex)[0];

return value.replace(decimal, fixedDecimal);
}

return value;
}

/**
* Returns the value with additional masking characters
* @param {String} value
* @returns {String}
*/

}, {
key: 'maskedValue',
value: function maskedValue() {
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';

if (value && typeof value === 'string') {
value = value.trim();

if (this.props.mask === 'currency') {
// Format number with commas. If the number includes a decimal,
// ensure it includes two decimal points
value = this.toNumber(value);
value = this.stringWithFixedDigits(value.toLocaleString('en-US'));
}
}

return value;
}

/**
* To avoid a jarring experience for screen readers, we only
* add/remove characters after the field has been blurred,
* rather than when the user is typing in the field
* @param {Object} evt
*/

}, {
key: 'handleBlur',
value: function handleBlur(evt) {
var value = this.maskedValue(evt.target.value);

// We only debounce the onBlur when we know for sure that
// this component will re-render (AKA when the value changes)
// and when an onBlur callback is present
var debounce = value !== this.state.value && typeof this.field.props.onBlur === 'function';

if (debounce) {
// We need to retain a reference to the event after the callback
// has been called. We pass this onto the consuming app's onBlur
// only after the value has been manipulated – this way, the
// value returned by event.target.value is the value after masking
evt.persist();
this.debouncedOnBlurEvent = evt;
}

this.setState({
value: value
});

if (!debounce && typeof this.field.props.onBlur === 'function') {
// If we didn't debounce the onBlur event, then we need to
// call the onBlur callback from here
this.field.props.onBlur(evt);
}
}
}, {
key: 'handleChange',
value: function handleChange(evt) {
this.setState({ value: evt.target.value });

if (typeof this.field.props.onChange === 'function') {
this.field.props.onChange(evt);
}
}
}, {
key: 'initialValue',
value: function initialValue() {
return this.field.props.value || this.field.props.defaultValue;
}
}, {
key: 'render',
value: function render() {
var _this2 = this;

return _react2.default.cloneElement(this.field, {
defaultValue: undefined,
onBlur: function onBlur(evt) {
return _this2.handleBlur(evt);
},
onChange: function onChange(evt) {
return _this2.handleChange(evt);
},
value: this.state.value
});
}
}]);

return Mask;
}(_react2.default.PureComponent);

Mask.propTypes = {
/** Pass the input as the child */
children: _propTypes2.default.node.isRequired,
mask: _propTypes2.default.string.isRequired
};

exports.default = Mask;
2 changes: 1 addition & 1 deletion packages/core/dist/components/TextField/TextField.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 12 additions & 4 deletions packages/core/dist/components/TextField/TextField.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ var _FormLabel = require('../FormLabel/FormLabel');

var _FormLabel2 = _interopRequireDefault(_FormLabel);

var _Mask = require('./Mask');

var _Mask2 = _interopRequireDefault(_Mask);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);
Expand Down Expand Up @@ -79,8 +83,12 @@ var TextField = exports.TextField = function (_React$PureComponent) {
return maskName ? _react2.default.createElement(
'div',
{ className: 'ds-c-field-mask ds-c-field-mask--' + maskName },
this.renderMask(),
field
this.renderMaskOverlay(),
_react2.default.createElement(
_Mask2.default,
{ mask: maskName },
field
)
) : field;
}

Expand All @@ -89,8 +97,8 @@ var TextField = exports.TextField = function (_React$PureComponent) {
*/

}, {
key: 'renderMask',
value: function renderMask() {
key: 'renderMaskOverlay',
value: function renderMaskOverlay() {
if (this.props.mask) {
var content = {
currency: '$'
Expand Down
2 changes: 1 addition & 1 deletion packages/core/dist/index.css

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cmsgov/design-system-core",
"version": "1.16.0",
"version": "1.17.0",
"publishConfig": {
"access": "public"
},
Expand All @@ -9,7 +9,7 @@
"license": "SEE LICENSE IN LICENSE.md",
"main": "dist/index.js",
"dependencies": {
"@cmsgov/design-system-support": "^1.16.0",
"@cmsgov/design-system-support": "^1.17.0",
"classnames": "^2.2.5",
"core-js": "^2.5.3",
"downshift": "^1.28.2",
Expand Down
8 changes: 4 additions & 4 deletions packages/docs/package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "@cmsgov/design-system-docs",
"version": "1.16.0",
"version": "1.17.0",
"private": true,
"description": "Design system's documentation website",
"repository": "CMSgov/design-system",
"dependencies": {
"@cmsgov/design-system-core": "^1.16.0",
"@cmsgov/design-system-layout": "^1.16.0",
"@cmsgov/design-system-support": "^1.16.0",
"@cmsgov/design-system-core": "^1.17.0",
"@cmsgov/design-system-layout": "^1.17.0",
"@cmsgov/design-system-support": "^1.17.0",
"classnames": "^2.2.5",
"core-js": "^2.5.3",
"lodash": "^4.17.5",
Expand Down
2 changes: 1 addition & 1 deletion packages/layout/dist/index.css

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions packages/layout/package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "@cmsgov/design-system-layout",
"version": "1.16.0",
"version": "1.17.0",
"publishConfig": {
"access": "public"
},
"description": "Responsive flexbox grid framework",
"repository": "CMSgov/design-system",
"license": "SEE LICENSE IN LICENSE.md",
"dependencies": {
"@cmsgov/design-system-support": "^1.16.0"
"@cmsgov/design-system-support": "^1.17.0"
}
}
2 changes: 1 addition & 1 deletion packages/support/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cmsgov/design-system-support",
"version": "1.16.0",
"version": "1.17.0",
"publishConfig": {
"access": "public"
},
Expand Down

0 comments on commit 5539e73

Please sign in to comment.