Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

591 строка
19 KiB

  1. 'use strict';
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. var _extends2 = require('babel-runtime/helpers/extends');
  6. var _extends3 = _interopRequireDefault(_extends2);
  7. var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');
  8. var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);
  9. var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
  10. var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
  11. var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
  12. var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
  13. var _createClass2 = require('babel-runtime/helpers/createClass');
  14. var _createClass3 = _interopRequireDefault(_createClass2);
  15. var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
  16. var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
  17. var _inherits2 = require('babel-runtime/helpers/inherits');
  18. var _inherits3 = _interopRequireDefault(_inherits2);
  19. var _simpleAssign = require('simple-assign');
  20. var _simpleAssign2 = _interopRequireDefault(_simpleAssign);
  21. var _react = require('react');
  22. var _react2 = _interopRequireDefault(_react);
  23. var _propTypes = require('prop-types');
  24. var _propTypes2 = _interopRequireDefault(_propTypes);
  25. var _reactDom = require('react-dom');
  26. var _reactDom2 = _interopRequireDefault(_reactDom);
  27. var _shallowEqual = require('recompose/shallowEqual');
  28. var _shallowEqual2 = _interopRequireDefault(_shallowEqual);
  29. var _transitions = require('../styles/transitions');
  30. var _transitions2 = _interopRequireDefault(_transitions);
  31. var _EnhancedTextarea = require('./EnhancedTextarea');
  32. var _EnhancedTextarea2 = _interopRequireDefault(_EnhancedTextarea);
  33. var _TextFieldHint = require('./TextFieldHint');
  34. var _TextFieldHint2 = _interopRequireDefault(_TextFieldHint);
  35. var _TextFieldLabel = require('./TextFieldLabel');
  36. var _TextFieldLabel2 = _interopRequireDefault(_TextFieldLabel);
  37. var _TextFieldUnderline = require('./TextFieldUnderline');
  38. var _TextFieldUnderline2 = _interopRequireDefault(_TextFieldUnderline);
  39. var _warning = require('warning');
  40. var _warning2 = _interopRequireDefault(_warning);
  41. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  42. var getStyles = function getStyles(props, context, state) {
  43. var _context$muiTheme = context.muiTheme,
  44. baseTheme = _context$muiTheme.baseTheme,
  45. _context$muiTheme$tex = _context$muiTheme.textField,
  46. floatingLabelColor = _context$muiTheme$tex.floatingLabelColor,
  47. focusColor = _context$muiTheme$tex.focusColor,
  48. textColor = _context$muiTheme$tex.textColor,
  49. disabledTextColor = _context$muiTheme$tex.disabledTextColor,
  50. backgroundColor = _context$muiTheme$tex.backgroundColor,
  51. errorColor = _context$muiTheme$tex.errorColor;
  52. var styles = {
  53. root: {
  54. fontSize: 16,
  55. lineHeight: '24px',
  56. width: props.fullWidth ? '100%' : 256,
  57. height: (props.rows - 1) * 24 + (props.floatingLabelText ? 72 : 48),
  58. display: 'inline-block',
  59. position: 'relative',
  60. backgroundColor: backgroundColor,
  61. fontFamily: baseTheme.fontFamily,
  62. transition: _transitions2.default.easeOut('200ms', 'height'),
  63. cursor: props.disabled ? 'not-allowed' : 'auto'
  64. },
  65. error: {
  66. position: 'relative',
  67. bottom: 2,
  68. fontSize: 12,
  69. lineHeight: '12px',
  70. color: errorColor,
  71. transition: _transitions2.default.easeOut()
  72. },
  73. floatingLabel: {
  74. color: props.disabled ? disabledTextColor : floatingLabelColor,
  75. pointerEvents: 'none'
  76. },
  77. input: {
  78. padding: 0,
  79. position: 'relative',
  80. width: '100%',
  81. border: 'none',
  82. outline: 'none',
  83. backgroundColor: 'rgba(0,0,0,0)',
  84. color: props.disabled ? disabledTextColor : textColor,
  85. cursor: 'inherit',
  86. font: 'inherit',
  87. WebkitOpacity: 1,
  88. WebkitTapHighlightColor: 'rgba(0,0,0,0)' // Remove mobile color flashing (deprecated style).
  89. },
  90. inputNative: {
  91. appearance: 'textfield' // Improve type search style.
  92. }
  93. };
  94. styles.textarea = (0, _simpleAssign2.default)({}, styles.input, {
  95. marginTop: props.floatingLabelText ? 36 : 12,
  96. marginBottom: props.floatingLabelText ? -36 : -12,
  97. boxSizing: 'border-box',
  98. font: 'inherit'
  99. });
  100. // Do not assign a height to the textarea as he handles it on his own.
  101. styles.input.height = '100%';
  102. if (state.isFocused) {
  103. styles.floatingLabel.color = focusColor;
  104. }
  105. if (props.floatingLabelText) {
  106. styles.input.boxSizing = 'border-box';
  107. if (!props.multiLine) {
  108. styles.input.marginTop = 14;
  109. }
  110. if (state.errorText) {
  111. styles.error.bottom = !props.multiLine ? styles.error.fontSize + 3 : 3;
  112. }
  113. }
  114. if (state.errorText) {
  115. if (state.isFocused) {
  116. styles.floatingLabel.color = styles.error.color;
  117. }
  118. }
  119. return styles;
  120. };
  121. /**
  122. * Check if a value is valid to be displayed inside an input.
  123. *
  124. * @param The value to check.
  125. * @returns True if the string provided is valid, false otherwise.
  126. */
  127. function isValid(value) {
  128. return value !== '' && value !== undefined && value !== null && !(Array.isArray(value) && value.length === 0);
  129. }
  130. var TextField = function (_Component) {
  131. (0, _inherits3.default)(TextField, _Component);
  132. function TextField() {
  133. var _ref;
  134. var _temp, _this, _ret;
  135. (0, _classCallCheck3.default)(this, TextField);
  136. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  137. args[_key] = arguments[_key];
  138. }
  139. return _ret = (_temp = (_this = (0, _possibleConstructorReturn3.default)(this, (_ref = TextField.__proto__ || (0, _getPrototypeOf2.default)(TextField)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
  140. isFocused: false,
  141. errorText: undefined,
  142. hasValue: false
  143. }, _this.handleInputBlur = function (event) {
  144. _this.setState({ isFocused: false });
  145. if (_this.props.onBlur) {
  146. _this.props.onBlur(event);
  147. }
  148. }, _this.handleInputChange = function (event) {
  149. if (!_this.props.hasOwnProperty('value')) {
  150. _this.setState({ hasValue: isValid(event.target.value) });
  151. }
  152. if (_this.props.onChange) {
  153. _this.props.onChange(event, event.target.value);
  154. }
  155. }, _this.handleInputFocus = function (event) {
  156. if (_this.props.disabled) {
  157. return;
  158. }
  159. _this.setState({ isFocused: true });
  160. if (_this.props.onFocus) {
  161. _this.props.onFocus(event);
  162. }
  163. }, _this.handleHeightChange = function (event, height) {
  164. var newHeight = height + 24;
  165. if (_this.props.floatingLabelText) {
  166. newHeight += 24;
  167. }
  168. _reactDom2.default.findDOMNode(_this).style.height = newHeight + 'px';
  169. }, _temp), (0, _possibleConstructorReturn3.default)(_this, _ret);
  170. }
  171. (0, _createClass3.default)(TextField, [{
  172. key: 'componentWillMount',
  173. value: function componentWillMount() {
  174. var _props = this.props,
  175. children = _props.children,
  176. name = _props.name,
  177. hintText = _props.hintText,
  178. floatingLabelText = _props.floatingLabelText,
  179. id = _props.id;
  180. var propsLeaf = children ? children.props : this.props;
  181. this.setState({
  182. errorText: this.props.errorText,
  183. hasValue: isValid(propsLeaf.value) || isValid(propsLeaf.defaultValue)
  184. });
  185. process.env.NODE_ENV !== "production" ? (0, _warning2.default)(name || hintText || floatingLabelText || id, 'Material-UI: We don\'t have enough information\n to build a robust unique id for the TextField component. Please provide an id or a name.') : void 0;
  186. var uniqueId = name + '-' + hintText + '-' + floatingLabelText + '-' + Math.floor(Math.random() * 0xFFFF);
  187. this.uniqueId = uniqueId.replace(/[^A-Za-z0-9-]/gi, '');
  188. }
  189. }, {
  190. key: 'componentWillReceiveProps',
  191. value: function componentWillReceiveProps(nextProps) {
  192. if (nextProps.disabled && !this.props.disabled) {
  193. this.setState({
  194. isFocused: false
  195. });
  196. }
  197. if (nextProps.errorText !== this.props.errorText) {
  198. this.setState({
  199. errorText: nextProps.errorText
  200. });
  201. }
  202. if (nextProps.children && nextProps.children.props) {
  203. nextProps = nextProps.children.props;
  204. }
  205. if (nextProps.hasOwnProperty('value')) {
  206. var hasValue = isValid(nextProps.value);
  207. this.setState({
  208. hasValue: hasValue
  209. });
  210. }
  211. }
  212. }, {
  213. key: 'shouldComponentUpdate',
  214. value: function shouldComponentUpdate(nextProps, nextState, nextContext) {
  215. return !(0, _shallowEqual2.default)(this.props, nextProps) || !(0, _shallowEqual2.default)(this.state, nextState) || !(0, _shallowEqual2.default)(this.context, nextContext);
  216. }
  217. }, {
  218. key: 'blur',
  219. value: function blur() {
  220. if (this.input) {
  221. this.getInputNode().blur();
  222. }
  223. }
  224. }, {
  225. key: 'focus',
  226. value: function focus() {
  227. if (this.input) {
  228. this.getInputNode().focus();
  229. }
  230. }
  231. }, {
  232. key: 'select',
  233. value: function select() {
  234. if (this.input) {
  235. this.getInputNode().select();
  236. }
  237. }
  238. }, {
  239. key: 'getValue',
  240. value: function getValue() {
  241. return this.input ? this.getInputNode().value : undefined;
  242. }
  243. }, {
  244. key: 'getInputNode',
  245. value: function getInputNode() {
  246. return this.props.children || this.props.multiLine ? this.input.getInputNode() : _reactDom2.default.findDOMNode(this.input);
  247. }
  248. }, {
  249. key: '_isControlled',
  250. value: function _isControlled() {
  251. return this.props.hasOwnProperty('value');
  252. }
  253. }, {
  254. key: 'render',
  255. value: function render() {
  256. var _this2 = this;
  257. var _props2 = this.props,
  258. children = _props2.children,
  259. className = _props2.className,
  260. disabled = _props2.disabled,
  261. errorStyle = _props2.errorStyle,
  262. errorText = _props2.errorText,
  263. floatingLabelFixed = _props2.floatingLabelFixed,
  264. floatingLabelFocusStyle = _props2.floatingLabelFocusStyle,
  265. floatingLabelShrinkStyle = _props2.floatingLabelShrinkStyle,
  266. floatingLabelStyle = _props2.floatingLabelStyle,
  267. floatingLabelText = _props2.floatingLabelText,
  268. fullWidth = _props2.fullWidth,
  269. hintText = _props2.hintText,
  270. hintStyle = _props2.hintStyle,
  271. id = _props2.id,
  272. inputStyle = _props2.inputStyle,
  273. multiLine = _props2.multiLine,
  274. onBlur = _props2.onBlur,
  275. onChange = _props2.onChange,
  276. onFocus = _props2.onFocus,
  277. style = _props2.style,
  278. type = _props2.type,
  279. underlineDisabledStyle = _props2.underlineDisabledStyle,
  280. underlineFocusStyle = _props2.underlineFocusStyle,
  281. underlineShow = _props2.underlineShow,
  282. underlineStyle = _props2.underlineStyle,
  283. rows = _props2.rows,
  284. rowsMax = _props2.rowsMax,
  285. textareaStyle = _props2.textareaStyle,
  286. other = (0, _objectWithoutProperties3.default)(_props2, ['children', 'className', 'disabled', 'errorStyle', 'errorText', 'floatingLabelFixed', 'floatingLabelFocusStyle', 'floatingLabelShrinkStyle', 'floatingLabelStyle', 'floatingLabelText', 'fullWidth', 'hintText', 'hintStyle', 'id', 'inputStyle', 'multiLine', 'onBlur', 'onChange', 'onFocus', 'style', 'type', 'underlineDisabledStyle', 'underlineFocusStyle', 'underlineShow', 'underlineStyle', 'rows', 'rowsMax', 'textareaStyle']);
  287. var prepareStyles = this.context.muiTheme.prepareStyles;
  288. var styles = getStyles(this.props, this.context, this.state);
  289. var inputId = id || this.uniqueId;
  290. var errorTextElement = this.state.errorText && _react2.default.createElement(
  291. 'div',
  292. { style: prepareStyles((0, _simpleAssign2.default)(styles.error, errorStyle)) },
  293. this.state.errorText
  294. );
  295. var floatingLabelTextElement = floatingLabelText && _react2.default.createElement(
  296. _TextFieldLabel2.default,
  297. {
  298. muiTheme: this.context.muiTheme,
  299. style: (0, _simpleAssign2.default)(styles.floatingLabel, floatingLabelStyle, this.state.isFocused ? floatingLabelFocusStyle : null),
  300. shrinkStyle: floatingLabelShrinkStyle,
  301. htmlFor: inputId,
  302. shrink: this.state.hasValue || this.state.isFocused || floatingLabelFixed,
  303. disabled: disabled
  304. },
  305. floatingLabelText
  306. );
  307. var inputProps = {
  308. id: inputId,
  309. ref: function ref(elem) {
  310. return _this2.input = elem;
  311. },
  312. disabled: this.props.disabled,
  313. onBlur: this.handleInputBlur,
  314. onChange: this.handleInputChange,
  315. onFocus: this.handleInputFocus
  316. };
  317. var childStyleMerged = (0, _simpleAssign2.default)(styles.input, inputStyle);
  318. var inputElement = void 0;
  319. if (children) {
  320. inputElement = _react2.default.cloneElement(children, (0, _extends3.default)({}, inputProps, children.props, {
  321. style: (0, _simpleAssign2.default)(childStyleMerged, children.props.style)
  322. }));
  323. } else {
  324. inputElement = multiLine ? _react2.default.createElement(_EnhancedTextarea2.default, (0, _extends3.default)({
  325. style: childStyleMerged,
  326. textareaStyle: (0, _simpleAssign2.default)(styles.textarea, styles.inputNative, textareaStyle),
  327. rows: rows,
  328. rowsMax: rowsMax,
  329. hintText: hintText
  330. }, other, inputProps, {
  331. onHeightChange: this.handleHeightChange
  332. })) : _react2.default.createElement('input', (0, _extends3.default)({
  333. type: type,
  334. style: prepareStyles((0, _simpleAssign2.default)(styles.inputNative, childStyleMerged))
  335. }, other, inputProps));
  336. }
  337. var rootProps = {};
  338. if (children) {
  339. rootProps = other;
  340. }
  341. return _react2.default.createElement(
  342. 'div',
  343. (0, _extends3.default)({}, rootProps, {
  344. className: className,
  345. style: prepareStyles((0, _simpleAssign2.default)(styles.root, style))
  346. }),
  347. floatingLabelTextElement,
  348. hintText ? _react2.default.createElement(_TextFieldHint2.default, {
  349. muiTheme: this.context.muiTheme,
  350. show: !(this.state.hasValue || floatingLabelText && !this.state.isFocused) || !this.state.hasValue && floatingLabelText && floatingLabelFixed && !this.state.isFocused,
  351. style: hintStyle,
  352. text: hintText
  353. }) : null,
  354. inputElement,
  355. underlineShow ? _react2.default.createElement(_TextFieldUnderline2.default, {
  356. disabled: disabled,
  357. disabledStyle: underlineDisabledStyle,
  358. error: !!this.state.errorText,
  359. errorStyle: errorStyle,
  360. focus: this.state.isFocused,
  361. focusStyle: underlineFocusStyle,
  362. muiTheme: this.context.muiTheme,
  363. style: underlineStyle
  364. }) : null,
  365. errorTextElement
  366. );
  367. }
  368. }]);
  369. return TextField;
  370. }(_react.Component);
  371. TextField.defaultProps = {
  372. disabled: false,
  373. floatingLabelFixed: false,
  374. multiLine: false,
  375. fullWidth: false,
  376. type: 'text',
  377. underlineShow: true,
  378. rows: 1
  379. };
  380. TextField.contextTypes = {
  381. muiTheme: _propTypes2.default.object.isRequired
  382. };
  383. TextField.propTypes = process.env.NODE_ENV !== "production" ? {
  384. children: _propTypes2.default.node,
  385. /**
  386. * The css class name of the root element.
  387. */
  388. className: _propTypes2.default.string,
  389. /**
  390. * The text string to use for the default value.
  391. */
  392. defaultValue: _propTypes2.default.any,
  393. /**
  394. * Disables the text field if set to true.
  395. */
  396. disabled: _propTypes2.default.bool,
  397. /**
  398. * The style object to use to override error styles.
  399. */
  400. errorStyle: _propTypes2.default.object,
  401. /**
  402. * The error content to display.
  403. */
  404. errorText: _propTypes2.default.node,
  405. /**
  406. * If true, the floating label will float even when there is no value.
  407. */
  408. floatingLabelFixed: _propTypes2.default.bool,
  409. /**
  410. * The style object to use to override floating label styles when focused.
  411. */
  412. floatingLabelFocusStyle: _propTypes2.default.object,
  413. /**
  414. * The style object to use to override floating label styles when shrunk.
  415. */
  416. floatingLabelShrinkStyle: _propTypes2.default.object,
  417. /**
  418. * The style object to use to override floating label styles.
  419. */
  420. floatingLabelStyle: _propTypes2.default.object,
  421. /**
  422. * The content to use for the floating label element.
  423. */
  424. floatingLabelText: _propTypes2.default.node,
  425. /**
  426. * If true, the field receives the property width 100%.
  427. */
  428. fullWidth: _propTypes2.default.bool,
  429. /**
  430. * Override the inline-styles of the TextField's hint text element.
  431. */
  432. hintStyle: _propTypes2.default.object,
  433. /**
  434. * The hint content to display.
  435. */
  436. hintText: _propTypes2.default.node,
  437. /**
  438. * The id prop for the text field.
  439. */
  440. id: _propTypes2.default.string,
  441. /**
  442. * Override the inline-styles of the TextField's input element.
  443. * When multiLine is false: define the style of the input element.
  444. * When multiLine is true: define the style of the container of the textarea.
  445. */
  446. inputStyle: _propTypes2.default.object,
  447. /**
  448. * If true, a textarea element will be rendered.
  449. * The textarea also grows and shrinks according to the number of lines.
  450. */
  451. multiLine: _propTypes2.default.bool,
  452. /**
  453. * Name applied to the input.
  454. */
  455. name: _propTypes2.default.string,
  456. /** @ignore */
  457. onBlur: _propTypes2.default.func,
  458. /**
  459. * Callback function that is fired when the textfield's value changes.
  460. *
  461. * @param {object} event Change event targeting the text field.
  462. * @param {string} newValue The new value of the text field.
  463. */
  464. onChange: _propTypes2.default.func,
  465. /** @ignore */
  466. onFocus: _propTypes2.default.func,
  467. /**
  468. * Number of rows to display when multiLine option is set to true.
  469. */
  470. rows: _propTypes2.default.number,
  471. /**
  472. * Maximum number of rows to display when
  473. * multiLine option is set to true.
  474. */
  475. rowsMax: _propTypes2.default.number,
  476. /**
  477. * Override the inline-styles of the root element.
  478. */
  479. style: _propTypes2.default.object,
  480. /**
  481. * Override the inline-styles of the TextField's textarea element.
  482. * The TextField use either a textarea or an input,
  483. * this property has effects only when multiLine is true.
  484. */
  485. textareaStyle: _propTypes2.default.object,
  486. /**
  487. * Specifies the type of input to display
  488. * such as "password" or "text".
  489. */
  490. type: _propTypes2.default.string,
  491. /**
  492. * Override the inline-styles of the
  493. * TextField's underline element when disabled.
  494. */
  495. underlineDisabledStyle: _propTypes2.default.object,
  496. /**
  497. * Override the inline-styles of the TextField's
  498. * underline element when focussed.
  499. */
  500. underlineFocusStyle: _propTypes2.default.object,
  501. /**
  502. * If true, shows the underline for the text field.
  503. */
  504. underlineShow: _propTypes2.default.bool,
  505. /**
  506. * Override the inline-styles of the TextField's underline element.
  507. */
  508. underlineStyle: _propTypes2.default.object,
  509. /**
  510. * The value of the text field.
  511. */
  512. value: _propTypes2.default.any
  513. } : {};
  514. exports.default = TextField;