Add prompt for variable creation
This commit is contained in:
1 parent
00b4f87ebe
commit
992eb209c3
3 files changed
+180
-8
No files matched your search
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user