Add prompt for variable creation

This commit is contained in:
Paul Kaplan committed 2017-04-26 10:14:02 -04:00
1 parent 00b4f87ebe
commit 992eb209c3
3 files changed
+180 -8

No files matched your search

+71
View File
@@ -0,0 +1,71 @@
@import "../../css/colors.css";
@import "../../css/units.css";
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
background-color: rgba(94, 102, 125, .95);
}
.modal-content {
width: 360px;
margin: 100px auto;
outline: none;
border: 3px solid rgb(126, 133, 151);
padding: 0;
border-radius: $space;
user-select: none;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #5d647a;
overflow: hidden;
}
.body {
background: $ui-pane-gray;
padding: 1.5rem 2.25rem;
}
.label {
font-weight: 500;
margin: 0 0 0.75rem;
}
.input {
margin-bottom: 1.5rem;
width: 100%;
border: 1px solid rgba(0,0,0,.1);
border-radius: 5px;
padding: 0 1rem;
height: 3rem;
color: #6b6b6b;
font-size: .875rem;
}
.button-row {
font-weight: bolder;
text-align: right;
}
.button-row button {
padding: 0.75rem 1rem;
border-radius: 0.25rem;
background: white;
border: 1px solid $ui-pane-border;
font-weight: 600;
font-size: 0.85rem;
}
.button-row button.ok-button {
background: $blue;
border: $blue;
color: white;
}
.button-row button + button {
margin-left: 0.5rem;
}
+74
View File
@@ -0,0 +1,74 @@
const React = require('react');
const ReactModal = require('react-modal');
const bindAll = require('lodash.bindall');
const Box = require('../box/box.jsx');
const styles = require('./prompt.css');
class PromptComponent extends React.Component {
constructor (props) {
super(props);
bindAll(this, [
'handleOk',
'handleKeyPress'
]);
}
handleKeyPress (event) {
if (event.key === 'Enter') this.handleOk();
}
handleOk () {
this.props.onOk(this.input.value);
}
render () {
return (
<ReactModal
isOpen
className={styles.modalContent}
overlayClassName={styles.modalOverlay}
onRequestClose={this.props.onCancel}
>
<Box className={styles.body}>
<Box className={styles.label}>
{this.props.label}
</Box>
<Box>
<input
autoFocus
className={styles.input}
placeholder={this.props.placeholder}
ref={el => (this.input = el)}
onKeyPress={this.handleKeyPress}
/>
</Box>
<Box className={styles.buttonRow}>
<button
className={styles.cancelButton}
onClick={this.props.onCancel}
>
Cancel
</button>
<button
className={styles.okButton}
onClick={this.handleOk}
>
OK
</button>
</Box>
</Box>
</ReactModal>
);
}
}
PromptComponent.propTypes = {
label: React.PropTypes.string.isRequired,
onCancel: React.PropTypes.func.isRequired,
onOk: React.PropTypes.func.isRequired,
placeholder: React.PropTypes.string
};
PromptComponent.defaultProps = {
placeholder: '...'
};
module.exports = PromptComponent;
+35 -8
View File
@@ -4,7 +4,7 @@ const PropTypes = require('prop-types');
const React = require('react');
const VMScratchBlocks = require('../lib/blocks');
const VM = require('scratch-vm');
const Prompt = require('../components/prompt/prompt.jsx');
const BlocksComponent = require('../components/blocks/blocks.jsx');
const addFunctionListener = (object, property, callback) => {
@@ -23,6 +23,8 @@ class Blocks extends React.Component {
bindAll(this, [
'attachVM',
'detachVM',
'handlePromptCallback',
'handlePromptClose',
'onScriptGlowOn',
'onScriptGlowOff',
'onBlockGlowOn',
@@ -32,20 +34,27 @@ class Blocks extends React.Component {
'onWorkspaceMetricsChange',
'setBlocks'
]);
this.state = {workspaceMetrics: {}};
this.state = {
workspaceMetrics: {},
prompt: null
};
}
componentDidMount () {
const workspaceConfig = defaultsDeep({}, Blocks.defaultOptions, this.props.options);
this.workspace = this.ScratchBlocks.inject(this.blocks, workspaceConfig);
this.ScratchBlocks.prompt = (message, defaultValue, callback) => {
this.setState({prompt: {callback, message, defaultValue}});
};
// @todo change this when blockly supports UI events
addFunctionListener(this.workspace, 'translate', this.onWorkspaceMetricsChange);
addFunctionListener(this.workspace, 'zoom', this.onWorkspaceMetricsChange);
this.attachVM();
}
shouldComponentUpdate () {
return false;
shouldComponentUpdate (nextProps, nextState) {
return this.state.prompt !== nextState.prompt;
}
componentWillUnmount () {
this.detachVM();
@@ -72,6 +81,7 @@ class Blocks extends React.Component {
this.props.vm.removeListener('VISUAL_REPORT', this.onVisualReport);
this.props.vm.removeListener('workspaceUpdate', this.onWorkspaceUpdate);
}
onWorkspaceMetricsChange () {
const target = this.props.vm.editingTarget;
if (target && target.id) {
@@ -124,6 +134,13 @@ class Blocks extends React.Component {
setBlocks (blocks) {
this.blocks = blocks;
}
handlePromptCallback (data) {
this.state.prompt.callback(data);
this.handlePromptClose();
}
handlePromptClose () {
this.setState({prompt: null});
}
render () {
const {
options, // eslint-disable-line no-unused-vars
@@ -131,10 +148,20 @@ class Blocks extends React.Component {
...props
} = this.props;
return (
<BlocksComponent
componentRef={this.setBlocks}
{...props}
/>
<div>
<BlocksComponent
componentRef={this.setBlocks}
{...props}
/>
{this.state.prompt ? (
<Prompt
label={this.state.prompt.message}
placeholder={this.state.prompt.defaultValue}
onCancel={this.handlePromptClose}
onOk={this.handlePromptCallback}
/>
) : null}
</div>
);
}
}