2 * Copyright 2015-present Greg Hurrell. All rights reserved.
3 * Licensed under the terms of the MIT license.
10 import React from 'react';
11 import convert from './convert';
17 export const ValuePropType = React.PropTypes.shape({
18 base: React.PropTypes.number,
19 value: React.PropTypes.string,
22 const DIGITS = '0123456789abcdef';
25 * Convert from `value` to `base`.
27 function fromValue(value: ?Value, base: number): string {
30 } else if (value.base === base) {
33 return convert(value.value, value.base, base);
36 export default class Field extends React.Component {
38 base: React.PropTypes.number,
39 onValueChange: React.PropTypes.func.required,
42 static defaultProps = {
48 if (props.base < 2 || props.base > DIGITS.length) {
50 `base prop must be between 2..${DIGITS.length}`
55 _isValid(value: string): boolean {
56 const validator = new RegExp(
57 `^[${DIGITS.slice(0, this.props.base)}]*$`
59 return validator.test(value.trim().toLowerCase());
62 _onChange = event => {
63 const value = event.currentTarget.value;
64 if (this._isValid(value)) {
65 this.props.onValueChange({
66 base: this.props.base,
73 const input = React.findDOMNode(this._input);
77 // May throw a SecurityError.
78 document.execCommand('copy');
79 } catch(error) { // eslint-disable-line no-empty
85 // Would check `document.queryCommandSupported('copy')` here, but that
87 // - https://code.google.com/p/chromium/issues/detail?id=476508
88 // - https://github.com/w3c/clipboard-apis/issues/4
89 return <span className="hextrapolate-copy" onClick={this._onCopy}>copy</span>;
96 className="hextrapolate-input"
97 onChange={this._onChange}
98 ref={ref => this._input = ref}
100 value={fromValue(this.props.value, this.props.base)}