Pick colors in mscreen from pallet
Summary:
{F226170897}
Color picker based on Lite's color table
We can't use standard color picker because of FB Lite's limitation: color set is predefined and sent from the server
'extra' field and 'color-lite' type are added to field description
Reviewed By: jknoxville
Differential Revision: D19330480
fbshipit-source-id: 695d288b4b8409e8b63a9e461a41914379d75a8c
This commit is contained in:
committed by
Facebook Github Bot
parent
850bc3fe76
commit
11e134e87c
@@ -11,7 +11,7 @@ import Link from '../Link';
|
|||||||
import {DataInspectorSetValue} from './DataInspector';
|
import {DataInspectorSetValue} from './DataInspector';
|
||||||
import {PureComponent} from 'react';
|
import {PureComponent} from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import {SketchPicker} from 'react-color';
|
import {SketchPicker, CompactPicker} from 'react-color';
|
||||||
import {Component, Fragment} from 'react';
|
import {Component, Fragment} from 'react';
|
||||||
import Popover from '../Popover';
|
import Popover from '../Popover';
|
||||||
import {colors} from '../colors';
|
import {colors} from '../colors';
|
||||||
@@ -80,6 +80,7 @@ type DataDescriptionProps = {
|
|||||||
path?: Array<string>;
|
path?: Array<string>;
|
||||||
type: string;
|
type: string;
|
||||||
value: any;
|
value: any;
|
||||||
|
extra?: any;
|
||||||
setValue: DataInspectorSetValue | null | undefined;
|
setValue: DataInspectorSetValue | null | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -207,7 +208,7 @@ export default class DataDescription extends PureComponent<
|
|||||||
};
|
};
|
||||||
|
|
||||||
_renderEditing() {
|
_renderEditing() {
|
||||||
const {type} = this.props;
|
const {type, extra} = this.props;
|
||||||
const {origValue, value} = this.state;
|
const {origValue, value} = this.state;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -230,6 +231,16 @@ export default class DataDescription extends PureComponent<
|
|||||||
return <ColorEditor value={value} commit={this.commit} />;
|
return <ColorEditor value={value} commit={this.commit} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type === 'color_lite') {
|
||||||
|
return (
|
||||||
|
<ColorEditor
|
||||||
|
value={value}
|
||||||
|
colorSet={extra.colorSet}
|
||||||
|
commit={this.commit}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +251,8 @@ export default class DataDescription extends PureComponent<
|
|||||||
type === 'text' ||
|
type === 'text' ||
|
||||||
type === 'number' ||
|
type === 'number' ||
|
||||||
type === 'enum' ||
|
type === 'enum' ||
|
||||||
type === 'color'
|
type === 'color' ||
|
||||||
|
type === 'color_lite'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,6 +272,7 @@ export default class DataDescription extends PureComponent<
|
|||||||
<DataDescriptionPreview
|
<DataDescriptionPreview
|
||||||
type={this.props.type}
|
type={this.props.type}
|
||||||
value={this.props.value}
|
value={this.props.value}
|
||||||
|
extra={this.props.extra}
|
||||||
editable={Boolean(this.props.setValue)}
|
editable={Boolean(this.props.setValue)}
|
||||||
commit={this.commit}
|
commit={this.commit}
|
||||||
onEdit={this.onEditStart}
|
onEdit={this.onEditStart}
|
||||||
@@ -271,6 +284,7 @@ export default class DataDescription extends PureComponent<
|
|||||||
|
|
||||||
class ColorEditor extends Component<{
|
class ColorEditor extends Component<{
|
||||||
value: any;
|
value: any;
|
||||||
|
colorSet?: Array<string | number>;
|
||||||
commit: (opts: DescriptionCommitOptions) => void;
|
commit: (opts: DescriptionCommitOptions) => void;
|
||||||
}> {
|
}> {
|
||||||
onBlur = () => {
|
onBlur = () => {
|
||||||
@@ -320,6 +334,25 @@ class ColorEditor extends Component<{
|
|||||||
this.props.commit({clear: false, keep: true, value: val, set: true});
|
this.props.commit({clear: false, keep: true, value: val, set: true});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onChangeLite = ({
|
||||||
|
rgb: {a, b, g, r},
|
||||||
|
}: {
|
||||||
|
rgb: {a: number; b: number; g: number; r: number};
|
||||||
|
}) => {
|
||||||
|
const prev = this.props.value;
|
||||||
|
|
||||||
|
if (typeof prev !== 'number') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// compute RRGGBBAA value
|
||||||
|
let val = (Math.round(a * 255) & 0xff) << 24;
|
||||||
|
val |= (r & 0xff) << 16;
|
||||||
|
val |= (g & 0xff) << 8;
|
||||||
|
val |= b & 0xff;
|
||||||
|
|
||||||
|
this.props.commit({clear: false, keep: true, value: val, set: true});
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const colorInfo = parseColor(this.props.value);
|
const colorInfo = parseColor(this.props.value);
|
||||||
if (!colorInfo) {
|
if (!colorInfo) {
|
||||||
@@ -331,10 +364,37 @@ class ColorEditor extends Component<{
|
|||||||
<DataDescriptionPreview
|
<DataDescriptionPreview
|
||||||
type="color"
|
type="color"
|
||||||
value={this.props.value}
|
value={this.props.value}
|
||||||
|
extra={this.props.colorSet}
|
||||||
editable={false}
|
editable={false}
|
||||||
commit={this.props.commit}
|
commit={this.props.commit}
|
||||||
/>
|
/>
|
||||||
<Popover onDismiss={this.onBlur}>
|
<Popover onDismiss={this.onBlur}>
|
||||||
|
{this.props.colorSet ? (
|
||||||
|
<CompactPicker
|
||||||
|
color={colorInfo}
|
||||||
|
colors={this.props.colorSet
|
||||||
|
.filter(x => x != 0)
|
||||||
|
.map(parseColor)
|
||||||
|
.map(rgba => {
|
||||||
|
if (!rgba) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})`;
|
||||||
|
})}
|
||||||
|
onChange={(color: {
|
||||||
|
hex: string;
|
||||||
|
hsl: {
|
||||||
|
a?: number;
|
||||||
|
h: number;
|
||||||
|
l: number;
|
||||||
|
s: number;
|
||||||
|
};
|
||||||
|
rgb: {a?: number; b: number; g: number; r: number};
|
||||||
|
}) => {
|
||||||
|
this.onChangeLite({rgb: {...color.rgb, a: color.rgb.a || 0}});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
<SketchPicker
|
<SketchPicker
|
||||||
color={colorInfo}
|
color={colorInfo}
|
||||||
presetColors={[
|
presetColors={[
|
||||||
@@ -370,6 +430,7 @@ class ColorEditor extends Component<{
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</Popover>
|
</Popover>
|
||||||
</ColorPickerDescription>
|
</ColorPickerDescription>
|
||||||
);
|
);
|
||||||
@@ -379,6 +440,7 @@ class ColorEditor extends Component<{
|
|||||||
class DataDescriptionPreview extends Component<{
|
class DataDescriptionPreview extends Component<{
|
||||||
type: string;
|
type: string;
|
||||||
value: any;
|
value: any;
|
||||||
|
extra?: any;
|
||||||
editable: boolean;
|
editable: boolean;
|
||||||
commit: (opts: DescriptionCommitOptions) => void;
|
commit: (opts: DescriptionCommitOptions) => void;
|
||||||
onEdit?: () => void;
|
onEdit?: () => void;
|
||||||
@@ -513,6 +575,23 @@ class DataDescriptionContainer extends Component<{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'color_lite': {
|
||||||
|
const colorInfo = parseColor(val);
|
||||||
|
if (typeof val === 'number' && val === 0) {
|
||||||
|
return <UndefinedValue>(not set)</UndefinedValue>;
|
||||||
|
} else if (colorInfo) {
|
||||||
|
const {a, b, g, r} = colorInfo;
|
||||||
|
return [
|
||||||
|
<ColorBox key="color-box" color={`rgba(${r}, ${g}, ${b}, ${a})`} />,
|
||||||
|
<ColorValue key="value">
|
||||||
|
rgba({r}, {g}, {b}, {a === 1 ? '1' : a.toFixed(2)})
|
||||||
|
</ColorValue>,
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
return <span>Malformed color</span>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case 'text':
|
case 'text':
|
||||||
case 'string':
|
case 'string':
|
||||||
if (val.startsWith('http://') || val.startsWith('https://')) {
|
if (val.startsWith('http://') || val.startsWith('https://')) {
|
||||||
|
|||||||
@@ -439,12 +439,13 @@ export default class DataInspector extends Component<DataInspectorProps> {
|
|||||||
|
|
||||||
let type;
|
let type;
|
||||||
let value;
|
let value;
|
||||||
|
let extra;
|
||||||
if (res) {
|
if (res) {
|
||||||
if (!res.mutable) {
|
if (!res.mutable) {
|
||||||
setValue = null;
|
setValue = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
({type, value} = res);
|
({type, value, extra} = res);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -566,6 +567,7 @@ export default class DataInspector extends Component<DataInspectorProps> {
|
|||||||
setValue={setValue}
|
setValue={setValue}
|
||||||
type={type}
|
type={type}
|
||||||
value={value}
|
value={value}
|
||||||
|
extra={extra}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ export type DataValueExtractor = (
|
|||||||
mutable: boolean;
|
mutable: boolean;
|
||||||
type: string;
|
type: string;
|
||||||
value: any;
|
value: any;
|
||||||
|
extra?: any;
|
||||||
}
|
}
|
||||||
| undefined
|
| undefined
|
||||||
| null;
|
| null;
|
||||||
|
|||||||
Reference in New Issue
Block a user