import * as React from "react"; import * as cx from "classnames"; import { cssPropertyChangeCompleted, cssPropertyChanged, cssPropertiesChanged, cssPropertiesChangeCompleted } from "../../../../../../../actions"; import { arraySplice } from "tandem-common"; import { Dispatch } from "redux"; import { PCVariable, isTextLikePCNode, ComputedStyleInfo } from "paperclip"; import { BaseBackgroundsProps } from "./backgrounds.pc"; import { computeCSSBackgrounds, CSSBackground, getCSSBackgroundsStyle } from "./inputs/background/state"; import { BackgroundItem } from "./backgrounds.pc"; const DEFAULT_COLOR = "rgba(200, 200, 200, 1)"; export type Props = { cwd: string; documentColors: string[]; dispatch: Dispatch; computedStyleInfo: ComputedStyleInfo; globalVariables: PCVariable[]; }; export default (Base: React.ComponentClass) => class BackgroundsController extends React.PureComponent { onChange = (item, index) => { const style = this._getChangedStyle(item, index); this.props.dispatch(cssPropertiesChanged(style)); }; onChangeComplete = (item, index) => { const style = this._getChangedStyle(item, index); this.props.dispatch(cssPropertiesChangeCompleted(style)); }; private _getChangedStyle(item: CSSBackground, index: number) { const backgrounds = arraySplice( computeCSSBackgrounds(this.props.computedStyleInfo), index, 1, item ); const backgroundStyle = getCSSBackgroundsStyle(backgrounds); return backgroundStyle; } onPlusButtonClick = () => { const value = this.props.computedStyleInfo.style["background-image"]; this.props.dispatch( cssPropertyChangeCompleted( "background-image", value ? value + "," + `linear-gradient(${DEFAULT_COLOR}, ${DEFAULT_COLOR})` : `linear-gradient(${DEFAULT_COLOR}, ${DEFAULT_COLOR})` ) ); }; onRemove = (index: number) => { const backgrounds = arraySplice( computeCSSBackgrounds(this.props.computedStyleInfo), index, 1 ); const backgroundStyle = getCSSBackgroundsStyle(backgrounds); this.props.dispatch(cssPropertiesChangeCompleted(backgroundStyle)); return backgroundStyle; }; render() { const { cwd, computedStyleInfo, documentColors, globalVariables } = this.props; const { onChange, onChangeComplete, onPlusButtonClick, onRemove } = this; const { sourceNode } = computedStyleInfo; // Typography pane is only available to text nodes to prevent cascading styles if (isTextLikePCNode(sourceNode)) { return null; } let backgrounds: CSSBackground[] = []; try { backgrounds = computeCSSBackgrounds(computedStyleInfo); } catch (e) { console.warn(e); } const children = backgrounds.map((background, i) => { return ( onRemove(i)} globalVariables={globalVariables} onChange={value => onChange(value, i)} onChangeComplete={value => onChangeComplete(value, i)} documentColors={documentColors} /> ); }); return ( ); } }; const splitBackgrounds = value => (value || "").match(/(\w+\(.*?\)|[\w-]+|#[^,]+)/g) || []; // TODO - validation here const replaceBackground = (oldValue, replacement, index) => arraySplice(splitBackgrounds(oldValue), index, 1, replacement) .filter(v => Boolean(v && v.trim())) .join(",") || undefined;