@elastic/eui
Version:
Elastic UI Component Library
106 lines (99 loc) • 3.64 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useEuiValidatableControl = exports.EuiValidatableControl = void 0;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _react = require("react");
var _propTypes = _interopRequireDefault(require("prop-types"));
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
function isMutableRef(ref) {
return ref != null && ref.hasOwnProperty('current');
}
/**
* The `EuiValidatableControl` component should be used in scenarios where
* we can render the validated `<input>` as its direct child.
*/
var EuiValidatableControl = exports.EuiValidatableControl = function EuiValidatableControl(_ref) {
var isInvalid = _ref.isInvalid,
children = _ref.children;
// Note that this must be state and not a ref to cause a rerender/set invalid state on initial mount
var _useState = (0, _react.useState)(null),
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
control = _useState2[0],
setControl = _useState2[1];
var child = _react.Children.only(children);
var childRef = child.ref;
var replacedRef = (0, _react.useCallback)(function (element) {
setControl(element);
// Call the original ref, if any
if (typeof childRef === 'function') {
childRef(element);
} else if (isMutableRef(childRef)) {
childRef.current = element;
}
}, [childRef]);
useSetControlValidity({
controlEl: control,
isInvalid: isInvalid
});
return /*#__PURE__*/(0, _react.cloneElement)(child, {
ref: replacedRef,
'aria-invalid': isInvalid || child.props['aria-invalid']
});
};
/**
* The `UseEuiValidatableControl` hook should be used in scenarios where
* we *cannot* control where the validated `<input>` is rendered (e.g., ReactDatePicker)
* and instead need to access the input via a ref and pass the element in directly
*/
EuiValidatableControl.propTypes = {
className: _propTypes.default.string,
"aria-label": _propTypes.default.string,
"data-test-subj": _propTypes.default.string,
css: _propTypes.default.any,
isInvalid: _propTypes.default.bool,
children: _propTypes.default.shape({
ref: _propTypes.default.any
}).isRequired
};
var useEuiValidatableControl = exports.useEuiValidatableControl = function useEuiValidatableControl(_ref2) {
var isInvalid = _ref2.isInvalid,
controlEl = _ref2.controlEl;
useSetControlValidity({
controlEl: controlEl,
isInvalid: isInvalid
});
(0, _react.useEffect)(function () {
if (!controlEl) return;
if (typeof isInvalid === 'boolean') {
controlEl.setAttribute('aria-invalid', String(isInvalid));
} else {
controlEl.removeAttribute('aria-invalid');
}
}, [isInvalid, controlEl]);
};
/**
* Internal `setCustomValidity` helper
*/
var useSetControlValidity = function useSetControlValidity(_ref3) {
var controlEl = _ref3.controlEl,
isInvalid = _ref3.isInvalid;
(0, _react.useEffect)(function () {
if (controlEl == null || typeof controlEl.setCustomValidity !== 'function') {
return;
}
if (isInvalid) {
controlEl.setCustomValidity('Invalid');
} else {
controlEl.setCustomValidity('');
}
}, [isInvalid, controlEl]);
};