Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/components/common/Alpha.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
import React, { Component, PureComponent } from 'react'
import reactCSS from 'reactcss'
import throttle from 'lodash/throttle'
import * as alpha from '../../helpers/alpha'

import Checkboard from './Checkboard'

export class Alpha extends (PureComponent || Component) {
constructor(props) {
super(props)

this.throttle = throttle((fn, data, e) => {
fn(data, e)
}, 50)
}

componentWillUnmount() {
this.throttle.cancel()
this.unbindEventListeners()
}

handleChange = (e) => {
const change = alpha.calculateChange(e, this.props.hsl, this.props.direction, this.props.a, this.container)
change && typeof this.props.onChange === 'function' && this.props.onChange(change, e)
change && typeof this.props.onChange === 'function' && this.throttle(this.props.onChange, change, e)
}

handleMouseDown = (e) => {
Expand Down
58 changes: 57 additions & 1 deletion src/components/common/ColorWrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@ import debounce from 'lodash/debounce'
import * as color from '../../helpers/color'

export const ColorWrap = (Picker) => {
class ColorPicker extends (PureComponent || Component) {
// Always use PureComponent for better rendering performance
const BaseComponent = PureComponent || Component;
class ColorPicker extends BaseComponent {
constructor(props) {
super()

this.state = {
...color.toState(props.color, 0),
}

// History management for undo/redo
this.colorHistory = [this.state]
this.historyIndex = 0

this.debounce = debounce((fn, data, event) => {
fn(data, event)
}, 100)
Expand All @@ -29,6 +35,9 @@ export const ColorWrap = (Picker) => {
this.setState(colors)
this.props.onChangeComplete && this.debounce(this.props.onChangeComplete, colors, event)
this.props.onChange && this.props.onChange(colors, event)

// Update color history
this.updateHistory(colors)
}
}

Expand All @@ -40,6 +49,51 @@ export const ColorWrap = (Picker) => {
}
}

// Update color history
updateHistory = (newColor) => {
// If we're not at the latest history entry, trim the history
if (this.historyIndex < this.colorHistory.length - 1) {
this.colorHistory = this.colorHistory.slice(0, this.historyIndex + 1)
}

// Add new color to history
this.colorHistory.push(newColor)

// Limit history size (optional, but prevents memory issues)
const MAX_HISTORY = 50
if (this.colorHistory.length > MAX_HISTORY) {
this.colorHistory.shift()
} else {
this.historyIndex = this.colorHistory.length - 1
}
}

// Undo functionality
undo = () => {
if (this.historyIndex > 0) {
this.historyIndex--
const previousColor = this.colorHistory[this.historyIndex]
this.setState(previousColor)
this.props.onChange && this.props.onChange(previousColor)
this.props.onChangeComplete && this.props.onChangeComplete(previousColor)
return true
}
return false
}

// Redo functionality
redo = () => {
if (this.historyIndex < this.colorHistory.length - 1) {
this.historyIndex++
const nextColor = this.colorHistory[this.historyIndex]
this.setState(nextColor)
this.props.onChange && this.props.onChange(nextColor)
this.props.onChangeComplete && this.props.onChangeComplete(nextColor)
return true
}
return false
}

render() {
const optionalEvents = {}
if (this.props.onSwatchHover) {
Expand All @@ -51,6 +105,8 @@ export const ColorWrap = (Picker) => {
{ ...this.props }
{ ...this.state }
onChange={ this.handleChange }
undo={ this.undo }
redo={ this.redo }
{ ...optionalEvents }
/>
)
Expand Down
18 changes: 10 additions & 8 deletions src/components/common/EditableInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,13 @@ export class EditableInput extends (PureComponent || Component) {
}

componentDidUpdate(prevProps, prevState) {
if (
this.props.value !== this.state.value &&
(prevProps.value !== this.props.value || prevState.value !== this.state.value)
) {
// Always update value from props to ensure consistency
if (this.props.value !== prevProps.value) {
const newValue = String(this.props.value).toUpperCase()
if (this.input === document.activeElement) {
this.setState({ blurValue: String(this.props.value).toUpperCase() })
this.setState({ blurValue: newValue })
} else {
this.setState({ value: String(this.props.value).toUpperCase(), blurValue: !this.state.blurValue && String(this.props.value).toUpperCase() })
this.setState({ value: newValue, blurValue: null })
}
}
}
Expand Down Expand Up @@ -77,10 +76,13 @@ export class EditableInput extends (PureComponent || Component) {
}

setUpdatedValue(value, e) {
const onChangeValue = this.props.label ? this.getValueObjectWithLabel(value) : value
// Convert to number if it's a numeric input
const numericValue = !isNaN(value) ? Number(value) : value
const onChangeValue = this.props.label ? this.getValueObjectWithLabel(numericValue) : numericValue
this.props.onChange && this.props.onChange(onChangeValue, e)

this.setState({ value })
// Keep the display value as string to maintain formatting
this.setState({ value: String(value) })
}

handleDrag = (e) => {
Expand Down
12 changes: 11 additions & 1 deletion src/components/common/Hue.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
import React, { Component, PureComponent } from 'react'
import reactCSS from 'reactcss'
import throttle from 'lodash/throttle'
import * as hue from '../../helpers/hue'

export class Hue extends (PureComponent || Component) {
constructor(props) {
super(props)

this.throttle = throttle((fn, data, e) => {
fn(data, e)
}, 50)
}

componentWillUnmount() {
this.throttle.cancel()
this.unbindEventListeners()
}

handleChange = (e) => {
const change = hue.calculateChange(e, this.props.direction, this.props.hsl, this.container)
change && typeof this.props.onChange === 'function' && this.props.onChange(change, e)
change && typeof this.props.onChange === 'function' && this.throttle(this.props.onChange, change, e)
}

handleMouseDown = (e) => {
Expand Down