import * as React from "react"; import * as cx from "classnames"; import { BaseColorSwatchesProps, ColorSwatchItem } from "./picker.pc"; import { EMPTY_ARRAY, memoize } from "tandem-common"; import { DropdownMenuOption } from "../dropdown/controller"; export const maybeConvertSwatchValueToColor = ( value: string, swatchOptionGroups: ColorSwatchGroup[] = [] ) => { for (const group of swatchOptionGroups) { const option = group.options.find(option => option.value === value); if (option) { return option.color; } } return value; }; export type ColorSwatchGroup = { label: string; options: ColorSwatchOption[]; }; export type ColorSwatchOption = { value: string; color: string; }; export const mapValueToColorSwatch = (value: string): ColorSwatchOption => ({ value, color: value }); export const getColorSwatchOptionsFromValues = memoize((value: string[]) => value.map(mapValueToColorSwatch) ); export type Props = { onChange: (value: string) => any; value: string; optionGroups: ColorSwatchGroup[]; }; export type State = { selectedGroupIndex: number; value: string; }; const getColorSwatchGroupFromValue = ( value: string, groups: ColorSwatchGroup[] ) => { if (!groups.length) { return 0; } for (const group of groups) { const option = group.options.find(option => option.value === value); if (option) { return group; } } return groups[0]; }; export default (Base: React.ComponentClass) => class ColorSwatchesController extends React.PureComponent { state = { selectedGroupIndex: 0, value: null }; static getDerivedStateFromProps(nextProps: Props, prevState: State): State { if ( nextProps.value !== prevState.value && nextProps.optionGroups.length ) { const selectedGroup = getColorSwatchGroupFromValue( nextProps.value, nextProps.optionGroups ); return { selectedGroupIndex: selectedGroup ? nextProps.optionGroups.indexOf(selectedGroup) : 0, value: nextProps.value }; } return null; } onGroupChange = (group: ColorSwatchGroup) => { this.setState({ ...this.state, selectedGroupIndex: this.props.optionGroups.indexOf(group) }); }; render() { const { value: selectedValue, optionGroups = EMPTY_ARRAY, onChange, ...rest } = this.props; const { onGroupChange } = this; const { selectedGroupIndex } = this.state; if (!optionGroups.length) { return null; } const selectedGroup = optionGroups[Math.min(selectedGroupIndex, optionGroups.length - 1)]; const content = selectedGroup.options.map( ({ color, value, label }, i) => { return ( onChange(value)} pillProps={{ style: { background: color } }} /> ); } ); return ( 1 })} swatchSourceInputProps={{ value: selectedGroup, options: mapColorSwatchGroupsToDropdownOptions(optionGroups), onChangeComplete: onGroupChange }} content={content} /> ); } }; const mapColorSwatchGroupsToDropdownOptions = memoize( (groups: ColorSwatchGroup[]): DropdownMenuOption[] => { return groups.map(group => ({ label: group.label, value: group })); } );