Refactor RenameDashboard component & styles

pull/10616/head
Alex P 2018-07-17 00:59:04 -07:00
parent 5cb7fbc8dd
commit 78d3b2b4be
3 changed files with 148 additions and 121 deletions

View File

@ -0,0 +1,73 @@
/*
Rename Dashboard Component Styles
------------------------------------------------------------------------------
*/
@import 'src/style/modules/influx-colors';
@import 'src/style/modules/variables';
@import 'src/style/modules/mixins';
@import 'src/style/layout/page-header';
$rename-dash-title-padding: 7px;
.rename-dashboard {
height: $chronograf-page-header-height;
display: flex;
align-items: center;
flex: 1 0 0;
}
.rename-dashboard--title {
width: 100%;
position: relative;
padding: 0 $rename-dash-title-padding;
border: $ix-border solid $g0-obsidian;
height: $form-sm-height;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
border-radius: $radius;
@include no-user-select();
color: $g17-whisper;
transition:
color 0.25s ease,
background-color 0.25s ease,
border-color 0.25s ease;
h1 {
text-transform: none;
letter-spacing: 0;
line-height: $form-sm-height - $ix-border;
margin: 0;
font-size: $page-header-size;
font-weight: $page-header-weight;
}
.icon {
position: absolute;
font-size: 15px;
top: 50%;
right: $rename-dash-title-padding;
transform: translateY(-50%);
opacity: 0;
transition: opacity 0.25s ease;
color: $g11-sidewalk;
}
&:hover {
cursor: text;
color: $g20-white;
background-color: $g3-castle;
border-color: $g3-castle;
}
&:hover .icon {
opacity: 1;
}
}
input.form-control.input-sm.rename-dashboard--input {
padding: 0 $rename-dash-title-padding;
font-size: $page-header-size;
font-weight: $page-header-weight;
}

View File

@ -1,84 +1,102 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import React, {Component, KeyboardEvent} from 'react'
import {ErrorHandling} from 'src/shared/decorators/errors'
import './RenameDashboard.scss'
import {
DASHBOARD_NAME_MAX_LENGTH,
NEW_DASHBOARD,
DEFAULT_DASHBOARD_NAME,
} from 'src/dashboards/constants/index'
import {ErrorHandling} from 'src/shared/decorators/errors'
interface Props {
onRename: (name: string) => void
name: string
}
interface State {
isEditing: boolean
reset: boolean
}
@ErrorHandling
class DashboardEditHeader extends Component {
constructor(props) {
class DashboardEditHeader extends Component<Props, State> {
private inputRef: HTMLInputElement
constructor(props: Props) {
super(props)
this.state = {
isEditing: false,
reset: false,
}
}
handleInputBlur = e => {
const {onSave, onCancel} = this.props
public render() {
const {isEditing} = this.state
const {name} = this.props
if (isEditing) {
return <div className="rename-dashboard">{this.input}</div>
}
return (
<div className="rename-dashboard">
<div className="rename-dashboard--title">
<h1 onClick={this.handleStartEditing}>{name}</h1>
<span className="icon pencil" />
</div>
</div>
)
}
private get input(): JSX.Element {
const {name} = this.props
return (
<input
maxLength={DASHBOARD_NAME_MAX_LENGTH}
type="text"
className="rename-dashboard--input form-control input-sm"
defaultValue={name}
autoComplete="off"
autoFocus={true}
spellCheck={false}
onBlur={this.handleInputBlur}
onKeyDown={this.handleKeyDown}
onFocus={this.handleFocus}
placeholder="Name this Dashboard"
ref={r => (this.inputRef = r)}
/>
)
}
private handleStartEditing = (): void => {
this.setState({isEditing: true})
}
private handleInputBlur = e => {
const {onRename} = this.props
const {reset} = this.state
if (reset) {
onCancel()
this.setState({isEditing: false})
} else {
const newName = e.target.value || NEW_DASHBOARD.name
onSave(newName)
const newName = e.target.value || DEFAULT_DASHBOARD_NAME
onRename(newName)
}
this.setState({reset: false})
this.setState({isEditing: false, reset: false})
}
handleKeyDown = e => {
private handleKeyDown = (e: KeyboardEvent<HTMLInputElement>): void => {
if (e.key === 'Enter') {
this.inputRef.blur()
}
if (e.key === 'Escape') {
this.inputRef.value = this.props.activeDashboard
this.inputRef.value = this.props.name
this.setState({reset: true}, () => this.inputRef.blur())
}
}
handleFocus = e => {
private handleFocus = (e): void => {
e.target.select()
}
render() {
const {onEditDashboard, isEditMode, activeDashboard} = this.props
return (
<div className="dashboard-title">
{isEditMode ? (
<input
maxLength={DASHBOARD_NAME_MAX_LENGTH}
type="text"
className="dashboard-title--input form-control input-sm"
defaultValue={activeDashboard}
autoComplete="off"
autoFocus={true}
spellCheck={false}
onBlur={this.handleInputBlur}
onKeyDown={this.handleKeyDown}
onFocus={this.handleFocus}
placeholder="Name this Dashboard"
ref={r => (this.inputRef = r)}
/>
) : (
<h1 onClick={onEditDashboard}>{activeDashboard}</h1>
)}
</div>
)
}
}
const {bool, func, string} = PropTypes
DashboardEditHeader.propTypes = {
activeDashboard: string.isRequired,
onSave: func.isRequired,
onCancel: func.isRequired,
isEditMode: bool,
onEditDashboard: func.isRequired,
}
export default DashboardEditHeader

View File

@ -398,75 +398,6 @@ $tick-script-overlay-margin: 30px;
white-space: nowrap;
}
/*
Dashboard Name Editing
-----------------------------------------------------------------------------
*/
$dash-editable-header-padding: 7px;
.page-header--left.page-header__dash-editable,
.dashboard-title,
.dashboard-title input[type='text'].form-control.dashboard-title--input,
.dashboard-title h1 {
flex: 1 0 0;
}
.dashboard-title {
display: flex;
input[type='text'].form-control.dashboard-title--input,
input[type='text'].form-control.dashboard-title--input:focus,
h1 {
font-size: $page-header-size;
font-weight: $page-header-weight;
padding: 0 $dash-editable-header-padding;
}
input[type='text'].form-control.dashboard-title--input,
input[type='text'].form-control.dashboard-title--input:focus {
font-size: $page-header-size;
font-weight: $page-header-weight;
}
h1 {
@include no-user-select();
position: relative;
border: 2px solid $g0-obsidian;
color: $g17-whisper;
height: 30px;
line-height: 28px;
border-radius: 4px;
margin: 0;
letter-spacing: 0;
text-transform: none;
transition: color 0.25s ease, background-color 0.25s ease,
border-color 0.25s ease;
&:after {
content: '\f058';
font-family: 'icomoon';
position: absolute;
font-size: 15px;
top: 50%;
right: $dash-editable-header-padding;
transform: translateY(-50%);
opacity: 0;
transition: opacity 0.25s ease;
color: $g11-sidewalk;
}
&:hover {
cursor: text;
color: $g20-white;
background-color: $g3-castle;
border-color: $g3-castle;
&:after {
opacity: 1;
}
}
}
}
/* Add borders between items in .nav-tablist
-----------------------------------------------------------------------------
TODO: Add these styles into the theme
@ -510,3 +441,8 @@ div.dropdown.dropdown-stretch > button.dropdown-toggle {
.custom-time-format {
margin-top: 4px;
}
.annotation-selector {
margin-left: 4px;
}