You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
5.4 KiB
JavaScript

import React from 'react'
import dynamic from 'next/dynamic'
import Dropdown from '../Dropdown'
import { managePopout } from '../Popout'
import ThemeIcon from '../svg/Theme'
import RemoveIcon from '../svg/Remove'
import { COLORS } from '../../lib/constants'
const ThemeCreate = dynamic(() => import('./ThemeCreate'), {
loading: () => null
})
const ThemeItem = ({ children, item, isSelected, remove }) => (
<div className="theme-item">
{children}
{item.custom && !isSelected && (
<div
role="button"
tabIndex={0}
className="icon"
onClick={e => {
e.stopPropagation()
remove(item.id)
}}
>
<RemoveIcon color={COLORS.SECONDARY} />
</div>
)}
<style jsx>
{`
.theme-item {
display: flex;
flex: 1;
justify-content: ${item.id === 'create' ? 'center' : 'space-between'};
align-items: center;
}
.icon {
display: flex;
margin-right: 6px;
}
`}
</style>
</div>
)
const themeIcon = <ThemeIcon />
class Themes extends React.PureComponent {
state = {
highlights: {}
}
dropdown = React.createRef()
static getDerivedStateFromProps(props) {
if (!props.isVisible) {
return {
highlights: {}
}
}
return null
}
handleThemeSelected = theme => {
const { toggleVisibility, update } = this.props
if (theme.id === 'create') {
toggleVisibility()
this.dropdown.current.closeMenu()
} else {
update(theme)
}
}
updateHighlights = updates =>
this.setState(({ highlights }) => ({
highlights: {
...highlights,
...updates
}
}))
create = theme => {
this.props.toggleVisibility()
this.props.create(theme)
}
itemWrapper = props => <ThemeItem {...props} remove={this.props.remove} />
render() {
const { themes, theme, isVisible, toggleVisibility } = this.props
const highlights = { ...theme.highlights, ...this.state.highlights }
const dropdownValue = isVisible ? { name: '' } : { id: theme.id, name: theme.name }
const dropdownList = [
{
id: 'create',
name: 'Create +'
},
...themes
]
let isColorLight = color => {
var r, g, b, hsp
color = +("0x" + color.slice(1).replace(color.length < 5 && /./g, '$&$&'))
r = color >> 16
g = color >> 8 & 255
b = color & 255;
hsp = Math.sqrt(
0.299 * (r * r) +
0.587 * (g * g) +
0.114 * (b * b)
)
return hsp > 127.5
}
return (
<div className="themes">
<Dropdown
innerRef={this.dropdown}
icon={themeIcon}
disableInput={isVisible}
inputValue={dropdownValue}
selected={dropdownValue}
list={dropdownList}
itemWrapper={this.itemWrapper}
onChange={this.handleThemeSelected}
onOpen={isVisible && toggleVisibility}
/>
{isVisible && (
<ThemeCreate
theme={theme}
themes={themes}
highlights={highlights}
create={this.create}
updateHighlights={this.updateHighlights}
/>
)}
<style jsx>
{`
.themes {
position: relative;
}
:global(.CodeMirror__container .CodeMirror) {
color: ${highlights.text} !important;
background-color: ${highlights.background} !important;
}
:global(.cm-string),
:global(.cm-string-2) {
color: ${highlights.string} !important;
}
:global(.cm-comment) {
color: ${highlights.comment} !important;
}
:global(.cm-variable),
:global(.cm-variable-2),
:global(.cm-variable-3) {
color: ${highlights.variable} !important;
}
:global(.cm-number) {
color: ${highlights.number} !important;
}
:global(.cm-keyword) {
color: ${highlights.keyword} !important;
}
:global(.cm-property) {
color: ${highlights.property} !important;
}
:global(.cm-def) {
color: ${highlights.definition} !important;
}
:global(.cm-meta) {
color: ${highlights.meta} !important;
}
:global(.cm-operator) {
color: ${highlights.operator} !important;
}
:global(.cm-attribute) {
color: ${highlights.attribute} !important;
}
:global(.cm-s-dracula .CodeMirror-cursor) {
border-left: solid 2px #159588 !important;
}
:global(.cm-s-solarized) {
box-shadow: none !important;
}
:global(.cm-s-solarized.cm-s-light) {
text-shadow: #eee8d5 0 1px !important;
}
:global(.cm-s-solarized.cm-s-light .CodeMirror-linenumber),
:global(.cm-s-solarized.cm-s-light .CodeMirror-linenumbers) {
background-color: #fdf6e3 !important;
}
:global(.cm-s-solarized.cm-s-dark .CodeMirror-linenumber),
:global(.cm-s-solarized.cm-s-dark .CodeMirror-linenumbers) {
background-color: #002b36 !important;
}
`}
</style>
</div>
)
}
}
export default managePopout(Themes)