Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EuiColorPicker opacity support #2850

Merged
merged 37 commits into from
Mar 12, 2020
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
78e8187
alpha range
thompsongl Feb 12, 2020
00f84a6
alpha tests
thompsongl Feb 12, 2020
59addfa
docs
thompsongl Feb 12, 2020
6af0bed
wip: rgba support
thompsongl Feb 14, 2020
3a95340
maintain alpha value
thompsongl Feb 19, 2020
9900dd9
prevent track visibility; clean up
thompsongl Feb 19, 2020
1465d18
Merge branch 'master' into colorpicker-opacity
thompsongl Feb 19, 2020
52c6aee
display toggles
thompsongl Feb 19, 2020
34a654a
docs validation
thompsongl Feb 20, 2020
3320fac
use rgba for swatches
thompsongl Feb 20, 2020
0338379
Merge branch 'master' into colorpicker-opacity
thompsongl Feb 20, 2020
db5b934
use rgba for css
thompsongl Feb 20, 2020
4a87871
better hue and format throughput
thompsongl Feb 21, 2020
cd89265
Merge branch 'master' into colorpicker-opacity
thompsongl Feb 24, 2020
2976b67
color stops validation
thompsongl Feb 24, 2020
ddc394a
more docs
thompsongl Feb 24, 2020
f0471f2
better format output
thompsongl Feb 24, 2020
8f21a0c
Merge branch 'master' into colorpicker-opacity
thompsongl Feb 25, 2020
cfc4c5e
disallow opacity when showAlpha=false
thompsongl Feb 25, 2020
7676221
Merge branch 'master' into colorpicker-opacity
thompsongl Mar 2, 2020
73bb0db
clean up
thompsongl Mar 2, 2020
f7f9948
Merge branch 'master' into colorpicker-opacity
thompsongl Mar 3, 2020
9e3471c
updated opacity and validity logic
thompsongl Mar 3, 2020
41733d6
fix button example
thompsongl Mar 3, 2020
9b0bea8
better format detection for null
thompsongl Mar 4, 2020
1345587
alpha channel for color stops
thompsongl Mar 4, 2020
522d598
allow empty range value
thompsongl Mar 4, 2020
887cd3d
sanitize rgb strings
thompsongl Mar 4, 2020
1de8de3
more resiliant sanitization
thompsongl Mar 4, 2020
99285c4
feedback
thompsongl Mar 4, 2020
48c42c3
clean up
thompsongl Mar 5, 2020
bac43b4
Merge branch 'master' into colorpicker-opacity
thompsongl Mar 11, 2020
5fd717f
usesEffect; clean up
thompsongl Mar 11, 2020
64dc808
utils tests
thompsongl Mar 11, 2020
b71ae10
comment
thompsongl Mar 12, 2020
751685d
Merge branch 'master' into colorpicker-opacity
thompsongl Mar 12, 2020
010f310
CL
thompsongl Mar 12, 2020
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"test-staged"
],
"dependencies": {
"@types/chroma-js": "^1.4.3",
"@types/chroma-js": "^2.0.0",
"@types/enzyme": "^3.1.13",
"@types/lodash": "^4.14.116",
"@types/numeral": "^0.0.25",
Expand Down
60 changes: 60 additions & 0 deletions src-docs/src/views/color_picker/alpha.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from 'react';

import { EuiColorPicker, EuiFormRow } from '../../../../src/components';
import { useColorPicker } from './utils';

export const Alpha = () => {
const [color, setColor, errors] = useColorPicker('#D36086');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like useColorPicker is probably a service we'll want to document and export if it's this helpful in a consuming application?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going to open an issue for this. I hadn't thought about it, but it does seem really useful and could be something of a pattern for other relatively simple form-like components.

const [color2, setColor2, errors2] = useColorPicker('211, 96, 134');

const customSwatches = [
'#54B399',
'#6092C0',
'#D36086',
'#9170B8',
'#CA8EAE',
'#54B39940',
'#6092C040',
'#D3608640',
'#9170B840',
'#CA8EAE40',
];

const customSwatches2 = [
'211, 96, 134, 0.25',
'211, 96, 134, 0.5',
'211, 96, 134, 0.75',
'211, 96, 134',
];

return (
<>
<EuiFormRow
label="Pick a color with optional opacity"
isInvalid={!!errors}
error={errors}>
<EuiColorPicker
onChange={setColor}
color={color}
showAlpha={true}
isInvalid={!!errors}
swatches={customSwatches}
/>
</EuiFormRow>

<EuiFormRow
label="Using RGBa format"
isInvalid={!!errors2}
error={errors2}>
<EuiColorPicker
thompsongl marked this conversation as resolved.
Show resolved Hide resolved
onChange={setColor2}
color={color2}
showAlpha={true}
format="rgba"
isInvalid={!!errors2}
swatches={customSwatches2}
/>
</EuiFormRow>
</>
);
};
45 changes: 11 additions & 34 deletions src-docs/src/views/color_picker/color_picker.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,13 @@
import React, { Component } from 'react';
import React from 'react';

import { EuiColorPicker, EuiFormRow } from '../../../../src/components';
import { isValidHex } from '../../../../src/services';

export class ColorPicker extends Component {
constructor(props) {
super(props);
this.state = {
color: '#D36086',
};
}

handleChange = value => {
this.setState({ color: value });
};

render() {
const hasErrors = !isValidHex(this.state.color) && this.state.color !== '';

let errors;
if (hasErrors) {
errors = ['Provide a valid hex value'];
}

return (
<EuiFormRow label="Pick a color" isInvalid={hasErrors} error={errors}>
<EuiColorPicker
onChange={this.handleChange}
color={this.state.color}
isInvalid={hasErrors}
/>
</EuiFormRow>
);
}
}
import { useColorPicker } from './utils';

export const ColorPicker = () => {
const [color, setColor, errors] = useColorPicker('#D36086');
return (
<EuiFormRow label="Pick a color" isInvalid={!!errors} error={errors}>
<EuiColorPicker onChange={setColor} color={color} isInvalid={!!errors} />
</EuiFormRow>
);
};
82 changes: 78 additions & 4 deletions src-docs/src/views/color_picker/color_picker_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,28 @@ const colorPickerRangeSnippet = `<EuiColorStops
/>
`;

import { Alpha } from './alpha';
const alphaSource = require('!!raw-loader!./alpha');
const alphaHtml = renderToHtml(Alpha);
const alphaSnippet = `<EuiColorPicker
id={colorPickerId}
onChange={handleChange}
color={chosenColor}
showAlpha={true}
isInvalid={hasErrors}
/>`;

import { Formats } from './formats';
const formatsSource = require('!!raw-loader!./formats');
const formatsHtml = renderToHtml(Formats);
const formatsSnippet = `<EuiColorPicker
format="hex"
id={colorPickerId}
onChange={handleChange}
color={chosenColor}
isInvalid={hasErrors}
/>`;

import { CustomSwatches } from './custom_swatches';
const customSwatchesSource = require('!!raw-loader!./custom_swatches');
const customSwatchesHtml = renderToHtml(CustomSwatches);
Expand Down Expand Up @@ -243,13 +265,13 @@ export const ColorPickerExample = {
selection.
</p>
<p>
Direct text entry will only match hexadecimal (hex) colors, and
output values only return hex values. Spatial selection involves
HSV manipulaton, which is converted to hex.
Direct text entry will match hexadecimal (hex) and RGB(a) colors,
and output will return both hex and RGBa values. Spatial selection
involves HSV manipulaton, which is converted to hex.
</p>
<p>
Swatches allow consumers to predefine preferred or suggested
choices. The swatches must also be entered in hex format.
choices. The swatches must also be entered in hex or RGBa format.
</p>
</EuiText>
</React.Fragment>
Expand Down Expand Up @@ -329,6 +351,58 @@ export const ColorPickerExample = {
snippet: colorPickerRangeSnippet,
demo: <ColorStopsRange />,
},
{
title: 'Format selection',
source: [
{
type: GuideSectionTypes.JS,
code: formatsSource,
},
{
type: GuideSectionTypes.HTML,
code: formatsHtml,
},
],
text: (
<>
<p>
Format selection does <em>not</em> limit the format of text input
the picker will allow, but instead attempts to keep consistency
during HSV selection. By default, the color picker will
automatically use the last input value format. Notice in following
the examples how hue and saturation selection behave differently.
</p>
<p>
Swatches will always show the &quot;as-authored&quot; color value,
as will the value provided via the <EuiCode>color</EuiCode> prop.
</p>
</>
),
snippet: formatsSnippet,
demo: <Formats />,
},
{
title: 'Alpha channel (opacity) selection',
source: [
{
type: GuideSectionTypes.JS,
code: alphaSource,
},
{
type: GuideSectionTypes.HTML,
code: alphaHtml,
},
],
text: (
<p>
To allow color opacity via alpha channel, set the{' '}
<EuiCode>showAlpha</EuiCode> prop to `true`. This will also display a
range slider allowing manual opacity updates.
</p>
),
snippet: alphaSnippet,
demo: <Alpha />,
},
{
title: 'Custom color swatches',
source: [
Expand Down
82 changes: 34 additions & 48 deletions src-docs/src/views/color_picker/custom_button.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Component, Fragment } from 'react';
import React, { Fragment, useState } from 'react';

import {
EuiColorPicker,
Expand All @@ -8,56 +8,42 @@ import {
EuiSpacer,
} from '../../../../src/components';

import { isValidHex } from '../../../../src/services';
import { useColorPicker } from './utils';

export class CustomButton extends Component {
constructor(props) {
super(props);
this.state = {
color: null,
};
}

handleChange = value => {
this.setState({ color: value });
export const CustomButton = () => {
const [color, setColor, errors] = useColorPicker('');
const [selectedColor, setSelectedColor] = useState(color);
const handleColorChange = (text, { hex, isValid }) => {
setColor(text, { hex, isValid });
setSelectedColor(hex);
};

render() {
const hasErrors = !isValidHex(this.state.color) && this.state.color !== '';

let errors;
if (hasErrors) {
errors = ['Provide a valid hex value'];
}

return (
<Fragment>
<EuiFormRow label="Pick a color" error={errors}>
<EuiColorPicker
onChange={this.handleChange}
color={this.state.color}
button={
<EuiColorPickerSwatch
color={this.state.color}
aria-label="Select a new color"
/>
}
/>
</EuiFormRow>
<EuiSpacer />
return (
<Fragment>
<EuiFormRow label="Pick a color" error={errors}>
<EuiColorPicker
onChange={this.handleChange}
color={this.state.color}
isInvalid={hasErrors}
onChange={handleColorChange}
color={color}
button={
<EuiBadge
color={this.state.color ? this.state.color : 'hollow'}
onClickAriaLabel="Select a new color">
Color this badge
</EuiBadge>
<EuiColorPickerSwatch
color={selectedColor}
aria-label="Select a new color"
/>
}
/>
</Fragment>
);
}
}
</EuiFormRow>
<EuiSpacer />
<EuiColorPicker
onChange={handleColorChange}
color={color}
isInvalid={!!errors}
button={
<EuiBadge
color={selectedColor ? selectedColor : 'hollow'}
onClickAriaLabel="Select a new color">
Color this badge
</EuiBadge>
}
/>
</Fragment>
);
};
38 changes: 38 additions & 0 deletions src-docs/src/views/color_picker/formats.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';

import { EuiColorPicker, EuiFormRow } from '../../../../src/components';
import { useColorPicker } from './utils';

export const Formats = () => {
const [color, setColor, errors] = useColorPicker('#D36086');
const [color2, setColor2, errors2] = useColorPicker('#D36086');
const [color3, setColor3, errors3] = useColorPicker('211, 96, 134');
return (
<>
<EuiFormRow label="Auto format" isInvalid={!!errors} error={errors}>
<EuiColorPicker
onChange={setColor}
color={color}
isInvalid={!!errors}
/>
</EuiFormRow>
<EuiFormRow label="Hex format" isInvalid={!!errors2} error={errors2}>
<EuiColorPicker
format="hex"
onChange={setColor2}
color={color2}
isInvalid={!!errors2}
/>
</EuiFormRow>
<EuiFormRow label="RGB(a) format" isInvalid={!!errors3} error={errors3}>
<EuiColorPicker
format="rgba"
onChange={setColor3}
color={color3}
isInvalid={!!errors3}
showAlpha={true}
/>
</EuiFormRow>
</>
);
};
Loading