Skip to content
Snippets Groups Projects
Commit 6d626d1b authored by Karishma Chadha's avatar Karishma Chadha
Browse files

Import input now shows error state w/orange border around input and tooltip...

Import input now shows error state w/orange border around input and tooltip with static error message.
parent 954e74be
No related branches found
No related tags found
No related merge requests found
/*
* NOTE: the copious use of `important` is needed to overwrite
* the default tooltip styling, and is required by the 3rd party
* library being used, `react-tooltip`
*/
@import "../../css/colors.css";
.import-error {
background-color: $data-primary !important;
border: 1px solid hsla(0, 0%, 0%, .1) !important;
border-radius: .25rem !important;
box-shadow: 0 0 .5rem hsla(0, 0%, 0%, .25) !important;
padding: .75rem 1rem !important;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif !important;
font-size: 1rem !important;
line-height: 1.25rem !important;
z-index: 100 !important;
}
.import-error:after {
content: "";
border-top: 1px solid hsla(0, 0%, 0%, .1) !important;
border-left: 0 !important;
border-bottom: 0 !important;
border-right: 1px solid hsla(0, 0%, 0%, .1) !important;
border-radius: .25rem;
background-color: $data-primary !important;
height: 1rem !important;
width: 1rem !important;
}
.show,
.show:before,
.show:after {
opacity: 1 !important;
}
.left:after {
margin-top: -.5rem !important;
right: -.5rem !important;
transform: rotate(45deg) !important;
}
.right:after {
margin-top: -.5rem !important;
left: -.5rem !important;
transform: rotate(-135deg) !important;
}
.top:after {
margin-right: -.5rem !important;
bottom: -.5rem !important;
transform: rotate(135deg) !important;
}
.bottom:after {
margin-left: -.5rem !important;
top: -.5rem !important;
transform: rotate(-45deg) !important;
}
import bindAll from 'lodash.bindall';
import classNames from 'classnames';
import {defineMessages, injectIntl, intlShape, FormattedMessage} from 'react-intl';
import PropTypes from 'prop-types';
import React from 'react';
import ReactTooltip from 'react-tooltip';
import styles from './import-error.css';
class ImportErrorContent extends React.Component {
constructor (props) {
super(props);
bindAll(this, [
'setHide',
'setShow',
'getContent'
]);
this.state = {
isShowing: true
};
}
setShow () {
// needed to set the opacity to 1, since the default is .9 on show
this.setState({isShowing: true});
}
setHide () {
this.setState({isShowing: false});
}
getContent () {
return (
<p>{this.props.errorMessage}</p>
);
}
render () {
return (
<ReactTooltip
afterHide={this.setHide}
afterShow={this.setShow}
className={classNames(
styles.importError,
this.props.className,
{
[styles.show]: (this.state.isShowing),
[styles.left]: (this.props.place === 'left'),
[styles.right]: (this.props.place === 'right'),
[styles.top]: (this.props.place === 'top'),
[styles.bottom]: (this.props.place === 'bottom')
}
)}
getContent={this.getContent}
id={this.props.tooltipId}
/>
);
}
}
ImportErrorContent.propTypes = {
className: PropTypes.string,
intl: intlShape,
place: PropTypes.oneOf(['top', 'right', 'bottom', 'left']),
tooltipId: PropTypes.string.isRequired,
errorMessage: PropTypes.string.isRequired
};
ImportErrorContent.defaultProps = {
place: 'bottom'
};
const ImportError = injectIntl(ImportErrorContent);
const ImportErrorTooltip = props => (
<div className={props.className}>
<div
data-delay-hide={props.delayHide}
data-delay-show={props.delayShow}
data-effect="solid"
data-for={props.tooltipId}
data-place={props.place}
data-tip="tooltip"
>
{props.children}
</div>
<ImportError
className={props.tooltipClassName}
place={props.place}
tooltipId={props.tooltipId}
errorMessage={props.errorMessage}
/>
</div>
);
ImportErrorTooltip.propTypes = {
children: PropTypes.node.isRequired,
className: PropTypes.string,
delayHide: PropTypes.number,
delayShow: PropTypes.number,
place: PropTypes.oneOf(['top', 'right', 'bottom', 'left']),
tooltipClassName: PropTypes.string,
tooltipId: PropTypes.string.isRequired,
errorMessage: PropTypes.string.isRequired
};
ImportErrorTooltip.defaultProps = {
delayHide: 0,
delayShow: 0
};
export {
ImportError as ImportErrorComponent,
ImportErrorTooltip
};
import PropTypes from 'prop-types';
import React from 'react';
import classNames from 'classnames';
import {ImportErrorTooltip} from '../import-error/import-error.jsx';
class ImportInput extends React.Component {
render () {
let input = null;
if (!this.props.hasValidationError) {
input = (
<input
autoFocus
className={this.props.okClassName}
placeholder={this.props.placeholder}
onChange={this.props.onChange}
onKeyPress={this.props.onKeyPress}
value={this.props.inputValue}
/>
);
} else {
input = (
<ImportErrorTooltip
place="bottom"
tooltipId="import-input-error"
errorMessage={this.props.errorMessage}
className={this.props.errorDivClassName}
>
<input
autoFocus
className={this.props.badClassName}
placeholder={this.props.placeholder}
onChange={this.props.onChange}
onKeyPress={this.props.onKeyPress}
value={this.props.inputValue}
/>
</ImportErrorTooltip>
);
}
return input;
}
}
ImportInput.propTypes = {
onChange: PropTypes.func.isRequired,
onKeyPress: PropTypes.func.isRequired,
placeholder: PropTypes.string,
errorMessage: PropTypes.string.isRequired,
hasValidationError: PropTypes.bool.isRequired,
inputValue: PropTypes.string.isRequired,
okClassName: PropTypes.string,
badClassName: PropTypes.string,
errorDivClassName: PropTypes.string
};
export default ImportInput;
......@@ -113,8 +113,12 @@ $sides: 20rem;
text-align: right;
display: flex;
justify-content: center;
/*border: 1px solid $import-primary;
border-radius: 0.25rem;*/
}
.input-row div.error-div {
margin: 0;
width: 100%;
padding: 0;
}
.input-row input {
......@@ -130,12 +134,18 @@ $sides: 20rem;
color: rgba(87,94,117,0.5);
}
.input-row input:focus {
.input-row input.ok-input:focus {
outline: none;
border: 1px solid $motion-primary;
border-radius: 0.25rem
}
.input-row input.bad-input:focus {
outline: none;
border: 1px solid $data-primary;
border-radius: 0.25rem
}
.input-row button {
padding: 0.5rem 2rem;
font-weight: bold;
......
......@@ -6,6 +6,7 @@ import {defineMessages, injectIntl, intlShape, FormattedMessage} from 'react-int
import classNames from 'classnames';
import CloseButton from '../close-button/close-button.jsx';
import ImportInput from '../import-input/import-input.jsx';
import styles from './import-modal.css';
......@@ -64,12 +65,16 @@ const ImportModal = ({intl, ...props}) => (
</p>
<Box className={styles.inputRow}>
<input
autoFocus
className={styles.input}
<ImportInput
placeholder={props.placeholder}
onChange={props.onChange}
onKeyPress={props.onKeyPress}
errorMessage={props.errorMessage}
hasValidationError={props.hasValidationError}
inputValue={props.inputValue}
okClassName={styles.okInput}
badClassName={styles.badInput}
errorDivClassName={styles.errorDiv}
/>
<button
className={styles.okButton}
......@@ -127,6 +132,8 @@ ImportModal.propTypes = {
onKeyPress: PropTypes.func.isRequired,
onViewProject: PropTypes.func.isRequired,
placeholder: PropTypes.string,
hasValidationError: PropTypes.bool.isRequired,
errorMessage: PropTypes.string.isRequired
};
export default injectIntl(ImportModal);
......@@ -23,7 +23,9 @@ class ImportModal extends React.Component {
]);
this.state = {
inputValue: ''
inputValue: '',
hasValidationError: false,
errorMessage: ''
};
}
handleKeyPress (event) {
......@@ -41,12 +43,10 @@ class ImportModal extends React.Component {
document.body.removeChild(projectLink);
this.handleCancel();
} else {
console.log("Error")
this.setState({
hasValidationError: true,
errorMessage: `Uh oh, that link doesn't look quite right.`});
}
// window.
// this.setState({previewing: true});
// this.props.onViewProject();
}
handleChange (e) {
this.setState({inputValue: e.target.value});
......@@ -82,6 +82,9 @@ class ImportModal extends React.Component {
placeholder='scratch.mit.edu/projects/123456789'
onKeyPress={this.handleKeyPress}
onChange={this.handleChange}
errorMessage={this.state.errorMessage}
hasValidationError={this.state.hasValidationError}
inputValue={this.state.inputValue}
/> :
<BrowserModalComponent
onBack={this.handleGoBack}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment