Move variable names into own component

pull/10616/head
Alex P 2018-05-07 16:43:50 -07:00 committed by Andrew Watkins
parent 30561d64e8
commit b8959ae769
3 changed files with 174 additions and 42 deletions

View File

@ -2,6 +2,7 @@ import React, {PureComponent} from 'react'
import _ from 'lodash' import _ from 'lodash'
import ExpressionNode from 'src/ifql/components/ExpressionNode' import ExpressionNode from 'src/ifql/components/ExpressionNode'
import VariableName from 'src/ifql/components/VariableName'
import {FlatBody, Suggestion} from 'src/types/ifql' import {FlatBody, Suggestion} from 'src/types/ifql'
@ -22,9 +23,7 @@ class BodyBuilder extends PureComponent<Props> {
if (d.funcs) { if (d.funcs) {
return ( return (
<div className="declaration" key={b.id}> <div className="declaration" key={b.id}>
<div className="variable-string"> <VariableName name={d.name} />
<span className="variable-name">{d.name}</span>
</div>
<ExpressionNode <ExpressionNode
key={b.id} key={b.id}
bodyID={b.id} bodyID={b.id}
@ -38,49 +37,27 @@ class BodyBuilder extends PureComponent<Props> {
return ( return (
<div className="declaration" key={b.id}> <div className="declaration" key={b.id}>
<div className="variable-string"> <VariableName name={b.source} />
{this.colorVariableSyntax(b.source)}
</div>
</div> </div>
) )
}) })
} }
return ( return (
<div className="declaration" key={b.id}>
<VariableName />
<ExpressionNode <ExpressionNode
key={b.id}
bodyID={b.id} bodyID={b.id}
funcs={b.funcs} funcs={b.funcs}
funcNames={this.funcNames} funcNames={this.funcNames}
/> />
</div>
) )
}) })
return <div className="body-builder">{_.flatten(bodybuilder)}</div> return <div className="body-builder">{_.flatten(bodybuilder)}</div>
} }
private colorVariableSyntax = (varString: string) => {
const split = varString.split('=')
const varName = split[0].substring(0, split[0].length - 1)
const varValue = split[1].substring(1)
const valueIsString = varValue.endsWith('"')
return (
<>
<span className="variable-name">{varName}</span>
{' = '}
<span
className={
valueIsString ? 'variable-value--string' : 'variable-value--number'
}
>
{varValue}
</span>
</>
)
}
private get funcNames() { private get funcNames() {
return this.props.suggestions.map(f => f.name) return this.props.suggestions.map(f => f.name)
} }

View File

@ -0,0 +1,126 @@
import React, {PureComponent, MouseEvent} from 'react'
interface Props {
name?: string
}
interface State {
isExpanded: boolean
}
export default class VariableName extends PureComponent<Props, State> {
public static defaultProps: Partial<Props> = {
name: '',
}
constructor(props) {
super(props)
this.state = {
isExpanded: false,
}
}
public render() {
const {isExpanded} = this.state
return (
<div
className="variable-string"
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
>
{this.nameElement}
{isExpanded && this.renderTooltip}
</div>
)
}
private get renderTooltip(): JSX.Element {
const {name} = this.props
if (name.includes('=')) {
const split = name.split('=')
const varName = split[0].substring(0, split[0].length - 1)
const varValue = split[1].substring(1)
return (
<div className="variable-name--tooltip">
<input
type="text"
className="form-control form-plutonium input-sm variable-name--input"
defaultValue={varName}
placeholder="Name"
/>
<span className="variable-name--operator">=</span>
<input
type="text"
className="form-control input-sm variable-name--input"
defaultValue={varValue}
placeholder="Value"
/>
</div>
)
}
return (
<div className="variable-name--tooltip">
<input
type="text"
className="form-control form-plutonium input-sm variable-name--input"
defaultValue={name}
placeholder="Name this query..."
/>
</div>
)
}
private handleMouseEnter = (e: MouseEvent<HTMLElement>): void => {
e.stopPropagation()
this.setState({isExpanded: true})
}
private handleMouseLeave = (e: MouseEvent<HTMLElement>): void => {
e.stopPropagation()
this.setState({isExpanded: false})
}
private get nameElement(): JSX.Element {
const {name} = this.props
if (!name) {
return <span className="variable-blank">Untitled</span>
}
if (name.includes('=')) {
return this.colorizeSyntax
}
return <span className="variable-name">{name}</span>
}
private get colorizeSyntax(): JSX.Element {
const {name} = this.props
const split = name.split('=')
const varName = split[0].substring(0, split[0].length - 1)
const varValue = split[1].substring(1)
const valueIsString = varValue.endsWith('"')
return (
<>
<span className="variable-name">{varName}</span>
{' = '}
<span
className={
valueIsString ? 'variable-value--string' : 'variable-value--number'
}
>
{varValue}
</span>
</>
)
}
}

View File

@ -15,10 +15,16 @@ $ifql-arg-min-width: 120px;
font-size: 13px; font-size: 13px;
font-weight: 600; font-weight: 600;
position: relative; position: relative;
background-color: $g4-onyx;
transition: background-color 0.25s ease;
&:hover {
background-color: $g6-smoke;
}
} }
.body-builder { .body-builder {
padding: 12px 30px; padding: 30px;
min-width: 440px; min-width: 440px;
overflow: hidden; overflow: hidden;
height: 100%; height: 100%;
@ -30,7 +36,7 @@ $ifql-arg-min-width: 120px;
width: 100%; width: 100%;
margin-bottom: 24px; margin-bottom: 24px;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: nowrap;
&:last-of-type { &:last-of-type {
margin-bottom: 0; margin-bottom: 0;
@ -42,9 +48,11 @@ $ifql-arg-min-width: 120px;
color: $g11-sidewalk; color: $g11-sidewalk;
line-height: $ifql-node-height; line-height: $ifql-node-height;
white-space: nowrap; white-space: nowrap;
background-color: $g3-castle;
@include no-user-select(); @include no-user-select();
} }
.variable-blank {
font-style: italic;
}
.variable-name { .variable-name {
color: $c-pool; color: $c-pool;
} }
@ -65,9 +73,7 @@ $ifql-arg-min-width: 120px;
@extend %ifql-node; @extend %ifql-node;
display: flex; display: flex;
align-items: center; align-items: center;
background-color: $g4-onyx;
margin-left: $ifql-node-gap; margin-left: $ifql-node-gap;
transition: background-color 0.25s ease;
// Connection Line // Connection Line
&:after { &:after {
@ -81,8 +87,9 @@ $ifql-arg-min-width: 120px;
transform: translate(-100%, -50%); transform: translate(-100%, -50%);
} }
&:hover { &:first-child:after {
background-color: $g6-smoke; content: none;
margin-left: 0;
} }
} }
.func-node--name, .func-node--name,
@ -112,7 +119,8 @@ $ifql-arg-min-width: 120px;
} }
.func-node--tooltip { .func-node--tooltip,
.variable-name--tooltip {
background-color: $g3-castle; background-color: $g3-castle;
border-radius: $radius; border-radius: $radius;
padding: 10px; padding: 10px;
@ -176,3 +184,24 @@ $ifql-arg-min-width: 120px;
.func-arg--value { .func-arg--value {
flex: 1 0 0; flex: 1 0 0;
} }
.variable-name--tooltip {
flex-direction: row;
align-items: center;
justify-content: space-between;
flex-wrap: nowrap;
}
.variable-name--input {
width: 140px;
}
.variable-name--operator {
width: 20px;
height: 30px;
text-align: center;
line-height: 30px;
font-weight: 600;
@include no-user-select();
}