2 * Copyright 2003-present Greg Hurrell. All rights reserved.
3 * Licensed under the terms of the MIT license.
8 import DIGITS from './DIGITS';
9 import React from 'react';
10 import convert from './convert';
11 import cx from 'classnames';
17 export const ValuePropType = React.PropTypes.shape({
18 base: React.PropTypes.number,
19 value: React.PropTypes.string,
23 * Convert from `value` to `base`.
25 function fromValue(value: ?Value, base: number): string {
28 } else if (value.base === base) {
31 return convert(value.value, value.base, base);
34 export default class Field extends React.Component {
36 base: React.PropTypes.number,
37 onValueChange: React.PropTypes.func.required,
40 static defaultProps = {
46 if (props.base < 2 || props.base > DIGITS.length) {
48 `base prop must be between 2..${DIGITS.length}`
51 this.state = {copySucceeded: false};
54 _isValid(value: string): boolean {
55 const validator = new RegExp(
56 `^[${DIGITS.slice(0, this.props.base)}]*$`
58 return validator.test(value.trim().toLowerCase());
61 _onChange = event => {
62 const value = event.currentTarget.value;
63 if (this._isValid(value)) {
64 this.props.onValueChange({
65 base: this.props.base,
72 React.findDOMNode(this._input).select();
74 // May throw a SecurityError.
77 copySucceeded: document.execCommand('copy'),
79 setTimeout(() => this.setState({copySucceeded: false}), 750);
81 this.setState({copySucceeded: false});
86 // Would check `document.queryCommandSupported('copy')` here, but that
88 // - https://code.google.com/p/chromium/issues/detail?id=476508
89 // - https://github.com/w3c/clipboard-apis/issues/4
92 className="hextrapolate-copy"
93 onClick={this._onCopy}
94 title="Copy to Clipboard">
101 const classNames = cx({
102 'hextrapolate-copy-status': true,
103 'hextrapolate-copy-success': this.state.copySucceeded,
105 return <span className={classNames}>✓</span>;
109 React.findDOMNode(this._input).focus();
114 <span className="hextrapolate-field">
116 onChange={this._onChange}
117 ref={ref => this._input = ref}
119 value={fromValue(this.props.value, this.props.base)}